ETH Price: $2,469.64 (+1.05%)

Contract

0xea5EDEF19979aBD627D0734E59E67BEDACDd3beD
 
Transaction Hash
Method
Block
From
To
Purchase209474332024-10-12 5:26:5920 hrs ago1728710819IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004786811.63704248
Purchase209474312024-10-12 5:26:3520 hrs ago1728710795IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004884111.8681768
Get Reward209474302024-10-12 5:26:2320 hrs ago1728710783IN
0xea5EDEF1...DACDd3beD
0 ETH0.0017817312.04989766
Get Reward209269042024-10-09 8:41:233 days ago1728463283IN
0xea5EDEF1...DACDd3beD
0 ETH0.002414216.32728799
Purchase209063302024-10-06 11:51:476 days ago1728215507IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004877811.85187915
Purchase209063292024-10-06 11:51:356 days ago1728215495IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004627311.51370563
Get Reward209063282024-10-06 11:51:236 days ago1728215483IN
0xea5EDEF1...DACDd3beD
0 ETH0.001713411.58779377
Get Reward208845062024-10-03 10:51:239 days ago1727952683IN
0xea5EDEF1...DACDd3beD
0 ETH0.00146839.93016449
Get Reward208623552024-09-30 8:44:5912 days ago1727685899IN
0xea5EDEF1...DACDd3beD
0 ETH0.0017295511.6970215
Get Reward208450832024-09-27 22:54:5915 days ago1727477699IN
0xea5EDEF1...DACDd3beD
0 ETH0.0019077612.90221643
Purchase208287842024-09-25 16:22:3517 days ago1727281355IN
0xea5EDEF1...DACDd3beD
0 ETH0.0020589550
Purchase208287832024-09-25 16:22:2317 days ago1727281343IN
0xea5EDEF1...DACDd3beD
0 ETH0.0020574550
Get Reward208287822024-09-25 16:22:1117 days ago1727281331IN
0xea5EDEF1...DACDd3beD
0 ETH0.0073931550
Get Reward208287802024-09-25 16:21:4717 days ago1727281307IN
0xea5EDEF1...DACDd3beD
0 ETH0.0073931550
Purchase208098642024-09-23 1:00:3520 days ago1727053235IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004424310.74983972
Purchase208098632024-09-23 1:00:2320 days ago1727053223IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004444310.79583761
Get Reward208098612024-09-23 0:59:5920 days ago1727053199IN
0xea5EDEF1...DACDd3beD
0 ETH0.0015968410.79948688
Get Reward207933022024-09-20 17:29:5922 days ago1726853399IN
0xea5EDEF1...DACDd3beD
0 ETH0.0034799723.53513768
Purchase207760752024-09-18 7:45:3524 days ago1726645535IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004652211.29977804
Purchase207760742024-09-18 7:45:2324 days ago1726645523IN
0xea5EDEF1...DACDd3beD
0 ETH0.0004480611.14320725
Get Reward207760732024-09-18 7:45:1124 days ago1726645511IN
0xea5EDEF1...DACDd3beD
0 ETH0.0016111210.89606169
Get Reward207569212024-09-15 15:29:5927 days ago1726414199IN
0xea5EDEF1...DACDd3beD
0 ETH0.001012396.84685055
Get Reward207396892024-09-13 5:45:1129 days ago1726206311IN
0xea5EDEF1...DACDd3beD
0 ETH0.000894496.04950924
Get Reward207228542024-09-10 21:19:5932 days ago1726003199IN
0xea5EDEF1...DACDd3beD
0 ETH0.0016415111.10160097
Get Reward207066722024-09-08 15:04:5934 days ago1725807899IN
0xea5EDEF1...DACDd3beD
0 ETH0.001022246.91348934
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RcaShieldConvex

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 12 : RcaShieldConvex.sol
/// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.11;

import "../RcaShieldBase.sol";
import "../../external/Convex.sol";

contract RcaShieldConvex is RcaShieldBase {
    using SafeERC20 for IERC20Metadata;

    IConvexRewardPool public immutable rewardPool;

    constructor(
        string memory _name,
        string memory _symbol,
        address _uToken,
        address _governance,
        address _controller,
        IConvexRewardPool _rewardPool
    ) RcaShieldBase(_name, _symbol, _uToken, _governance, _controller) {
        rewardPool = _rewardPool;
        uToken.safeApprove(address(rewardPool), type(uint256).max);
    }

    function getReward() external {
        rewardPool.getReward(address(this), true);
    }

    function purchase(
        address _token,
        uint256 _amount, // token amount to buy
        uint256 _tokenPrice,
        bytes32[] calldata _tokenPriceProof,
        uint256 _underlyingPrice,
        bytes32[] calldata _underlyinPriceProof
    ) external {
        require(_token != address(uToken), "cannot buy underlying token");
        controller.verifyPrice(_token, _tokenPrice, _tokenPriceProof);
        controller.verifyPrice(address(uToken), _underlyingPrice, _underlyinPriceProof);
        uint256 underlyingAmount = (_amount * _tokenPrice) / _underlyingPrice;
        if (discount > 0) {
            underlyingAmount -= (underlyingAmount * discount) / DENOMINATOR;
        }
        IERC20Metadata(_token).safeTransfer(msg.sender, _amount);
        uToken.safeTransferFrom(msg.sender, address(this), underlyingAmount);
        rewardPool.stake(underlyingAmount);
    }

    function _uBalance() internal view override returns (uint256) {
        return uToken.balanceOf(address(this)) + rewardPool.balanceOf(address(this));
    }

    function _afterMint(uint256 _uAmount) internal override {
        rewardPool.stake(_uAmount);
    }

    function _afterRedeem(uint256 _uAmount) internal override {
        // CHEK : we are not going to claims rewards here since it will be claimed on _update
        rewardPool.withdraw(_uAmount, false);
    }
}

File 2 of 12 : RcaShieldBase.sol
/// SPDX-License-Identifier: UNLICENSED

/**
 * By using this contract and/or any other launched by the Ease protocol, you agree to Ease's
 * Terms and Conditions, Privacy Policy, and Terms of Coverage.
 * https://ease.org/about-ease-defi/terms-and-conditions-disclaimer/
 * https://ease.org/about-ease-defi/privacy-policy/
 * https://ease.org/learn-crypto-defi/get-defi-cover-at-ease/ease-defi-cover/terms-of-ease-coverage/
 */

/**

                               ................                            
                          ..',,;;::::::::ccccc:;,'..                       
                      ..',;;;;::::::::::::cccccllllc;..                    
                    .';;;;;;;,'..............',:clllolc,.                  
                  .,;;;;;,..                    .';cooool;.                
                .';;;;;'.           .....          .,coodoc.               
               .,;;;;'.       ..',;:::cccc:;,'.      .;odddl'              
              .,;;;;.       .,:cccclllllllllool:'      ,odddl'             
             .,:;:;.      .;ccccc:;,''''',;cooooo:.     ,odddc.            
             ';:::'     .,ccclc,..         .':odddc.    .cdddo,            
            .;:::,.     ,cccc;.              .:oddd:.    ,dddd:.           
            '::::'     .ccll:.                .ldddo'    'odddc.           
            ,::c:.     ,lllc'    .';;;::::::::codddd;    ,dxxxc.           
           .,ccc:.    .;lllc.    ,oooooddddddddddddd;    :dxxd:            
            ,cccc.     ;llll'    .;:ccccccccccccccc;.   'oxxxo'            
            'cccc,     'loooc.                         'lxxxd;             
            .:lll:.    .;ooooc.                      .;oxxxd:.             
             ,llll;.    .;ooddo:'.                ..:oxxxxo;.              
             .:llol,.     'coddddl:;''.........,;codxxxxd:.                
              .:lool;.     .':odddddddddoooodddxxxxxxdl;.                  
               .:ooooc'       .';codddddddxxxxxxdol:,.                     
                .;ldddoc'.        ...'',,;;;,,''..                         
                  .:oddddl:'.                          .,;:'.              
                    .:odddddoc;,...              ..',:ldxxxx;              
                      .,:odddddddoolcc::::::::cllodxxxxxxxd:.              
                         .';clddxxxxxxxxxxxxxxxxxxxxxxoc;'.                
                             ..',;:ccllooooooollc:;,'..                    
                                        ......                             
                                                                      
**/

pragma solidity 0.8.11;
import "../general/Governable.sol";
import "../interfaces/IRouter.sol";
import "../interfaces/IRcaController.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

/**
 * @title RCA Vault
 * @notice Main contract for reciprocally-covered assets. Mints, redeems, and sells.
 * Each underlying token (not protocol) has its own RCA vault. This contract
 * doubles as the vault and the RCA token.
 * @dev This contract assumes uToken decimals of 18.
 * @author Ease -- Robert M.C. Forster, Romke Jonker, Taek Lee, Chiranjibi Poudyal, Dominik Prediger
 **/
abstract contract RcaShieldBase is ERC20, Governable {
    using SafeERC20 for IERC20Metadata;

    uint256 constant YEAR_SECS = 31536000;
    uint256 constant DENOMINATOR = 10000;
    uint256 constant BUFFER = 1e18;

    /// @notice Controller of RCA contract that takes care of actions.
    IRcaController public controller;
    /// @notice Underlying token that is protected by the shield.
    IERC20Metadata public immutable uToken;

    /// @notice Percent to pay per year. 1000 == 10%.
    uint256 public apr;
    /// @notice Current sale discount to sell tokens cheaper.
    uint256 public discount;
    /// @notice Treasury for all funds that accepts payments.
    address payable public treasury;
    /// @notice Percent of the contract that is currently paused and cannot be withdrawn.
    /// Set > 0 when a hack has happened and DAO has not submitted for sales.
    /// Withdrawals during this time will lose this percent. 1000 == 10%.
    uint256 public percentReserved;

    /**
     * @notice Cumulative total amount that has been liquidated lol.
     * @dev Used to make sure we don't run into a situation where liq amount isn't updated,
     * a new hack occurs and current liq is added to, then current liq is updated while
     * DAO votes on the new total liq. In this case we can subtract that interim addition.
     */
    uint256 public cumLiqForClaims;
    /// @notice Amount of tokens currently up for sale.
    uint256 public amtForSale;

    /**
     * @notice Amount of RCA tokens pending withdrawal.
     * @dev When doing value calculations this is required because RCAs are burned immediately
     * upon request, but underlying tokens only leave the contract once the withdrawal is finalized.
     */
    uint256 public pendingWithdrawal;
    /// @notice withdrawal variable for withdrawal delays.
    uint256 public withdrawalDelay;
    /// @notice Requests by users for withdrawals.
    mapping(address => WithdrawRequest) public withdrawRequests;

    /**
     * @notice Last time the contract has been updated.
     * @dev Used to calculate APR if fees are implemented.
     */
    uint256 lastUpdate;

    struct WithdrawRequest {
        uint112 uAmount;
        uint112 rcaAmount;
        uint32 endTime;
    }

    /// @notice Notification of the mint of new tokens.
    event Mint(
        address indexed sender,
        address indexed to,
        address indexed referrer,
        uint256 uAmount,
        uint256 rcaAmount,
        uint256 timestamp
    );
    /// @notice Notification of an initial redeem request.
    event RedeemRequest(address indexed user, uint256 uAmount, uint256 rcaAmount, uint256 endTime, uint256 timestamp);
    /// @notice Notification of a redeem finalization after withdrawal delay.
    event RedeemFinalize(
        address indexed user,
        address indexed to,
        uint256 uAmount,
        uint256 rcaAmount,
        uint256 timestamp
    );
    /// @notice Notification of a purchase of the underlying token.
    event PurchaseU(address indexed to, uint256 uAmount, uint256 ethAmount, uint256 price, uint256 timestamp);
    /// @notice Notification of a purchase of an RCA token.
    event PurchaseRca(
        address indexed to,
        uint256 uAmount,
        uint256 rcaAmount,
        uint256 ethAmount,
        uint256 price,
        uint256 timestamp
    );

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////// modifiers //////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @notice Restrict set functions to only controller for many variables.
     */
    modifier onlyController() {
        require(msg.sender == address(controller), "Function must only be called by controller.");
        _;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////// constructor ////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @notice Construct shield and RCA ERC20 token.
     * @param _name Name of the RCA token.
     * @param _symbol Symbol of the RCA token.
     * @param _uToken Address of the underlying token.
     * @param _governor Address of the governor (owner) of the shield.
     * @param _controller Address of the controller that maintains the shield.
     */
    constructor(
        string memory _name,
        string memory _symbol,
        address _uToken,
        address _governor,
        address _controller
    ) ERC20(_name, _symbol) {
        initializeGovernable(_governor);
        uToken = IERC20Metadata(_uToken);
        controller = IRcaController(_controller);
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////// initialize /////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @notice Controller calls to initiate which sets current contract variables. All %s are 1000 == 10%.
     * @param _apr Fees for using the RCA ecosystem.
     * @param _discount Discount for purchases while tokens are being liquidated.
     * @param _treasury Address of the treasury to which Ether from fees and liquidation will be sent.
     * @param _withdrawalDelay Delay of withdrawals from the shield in seconds.
     */
    function initialize(
        uint256 _apr,
        uint256 _discount,
        address payable _treasury,
        uint256 _withdrawalDelay
    ) external onlyController {
        require(treasury == address(0), "Contract has already been initialized.");
        apr = _apr;
        discount = _discount;
        treasury = _treasury;
        withdrawalDelay = _withdrawalDelay;
        lastUpdate = block.timestamp;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////// external //////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @notice Mint tokens to an address. Not automatically to msg.sender so we can more easily zap assets.
     * @param _user The user to mint tokens to.
     * @param _referrer The address that referred this user.
     * @param _uAmount Amount of underlying tokens desired to use for mint.
     * @param _expiry Time (Unix timestamp) that this request expires.
     * @param _v The recovery byte of the signature.
     * @param _r Half of the ECDSA signature pair.
     * @param _s Half of the ECDSA signature pair.
     * @param _newCumLiqForClaims New total cumulative liquidated if there is one.
     * @param _liqForClaimsProof Merkle proof to verify cumulative liquidated.
     */
    function mintTo(
        address _user,
        address _referrer,
        uint256 _uAmount,
        uint256 _expiry,
        uint8 _v,
        bytes32 _r,
        bytes32 _s,
        uint256 _newCumLiqForClaims,
        bytes32[] calldata _liqForClaimsProof
    ) external virtual {
        // Call controller to check capacity limits, add to capacity limits, emit events, check for new "for sale".
        controller.mint(_user, _uAmount, _expiry, _v, _r, _s, _newCumLiqForClaims, _liqForClaimsProof);

        // Only update fees after potential contract update.
        _update();

        uint256 rcaAmount = _rcaValue(_uAmount, amtForSale);

        uToken.safeTransferFrom(msg.sender, address(this), _uAmount);

        _mint(_user, rcaAmount);

        _afterMint(_uAmount);

        emit Mint(msg.sender, _user, _referrer, _uAmount, rcaAmount, block.timestamp);
    }

    /**
     * @notice Request redemption of RCAs back to the underlying token.
     * Has a withdrawal delay so it's 2 parts (request and finalize).
     * @param _rcaAmount The amount of tokens (in RCAs) to be redeemed.
     * @param _newCumLiqForClaims New cumulative liquidated if this must be updated.
     * @param _liqForClaimsProof Merkle proof to verify the new cumulative liquidated.
     * @param _newPercentReserved New percent of funds in shield that are reserved.
     * @param _percentReservedProof Merkle proof for the new percent reserved.
     */
    function redeemRequest(
        uint256 _rcaAmount,
        uint256 _newCumLiqForClaims,
        bytes32[] calldata _liqForClaimsProof,
        uint256 _newPercentReserved,
        bytes32[] calldata _percentReservedProof
    ) external {
        controller.redeemRequest(
            msg.sender,
            _newCumLiqForClaims,
            _liqForClaimsProof,
            _newPercentReserved,
            _percentReservedProof
        );

        _update();

        uint256 uAmount = _uValue(_rcaAmount, amtForSale, percentReserved);
        _burn(msg.sender, _rcaAmount);

        _afterRedeem(uAmount);

        pendingWithdrawal += _rcaAmount;

        WithdrawRequest memory curRequest = withdrawRequests[msg.sender];
        uint112 newUAmount = uint112(uAmount) + curRequest.uAmount;
        uint112 newRcaAmount = uint112(_rcaAmount) + curRequest.rcaAmount;
        uint32 endTime = uint32(block.timestamp) + uint32(withdrawalDelay);
        withdrawRequests[msg.sender] = WithdrawRequest(newUAmount, newRcaAmount, endTime);

        emit RedeemRequest(msg.sender, uint256(uAmount), _rcaAmount, uint256(endTime), block.timestamp);
    }

    /**
     * @notice Used to exchange RCA tokens back to the underlying token. Will have a 1-2 day delay upon withdrawal.
     * This can mint to a router contract that can exchange the asset for Ether and send to the user.
     * @param _to The destination of the tokens.
     * @param _newCumLiqForClaims New cumulative liquidated if this must be updated.
     * @param _liqForClaimsProof Merkle proof to verify new cumulative liquidation.
     * @param _liqForClaimsProof Merkle proof to verify the new cumulative liquidated.
     * @param _newPercentReserved New percent of funds in shield that are reserved.
     * @param _percentReservedProof Merkle proof for the new percent reserved.
     */
    function redeemFinalize(
        address _to,
        bytes calldata _routerData,
        uint256 _newCumLiqForClaims,
        bytes32[] calldata _liqForClaimsProof,
        uint256 _newPercentReserved,
        bytes32[] calldata _percentReservedProof
    ) external virtual {
        address user = msg.sender;

        WithdrawRequest memory request = withdrawRequests[user];
        delete withdrawRequests[user];

        // endTime > 0 ensures request exists.
        require(request.endTime > 0 && uint32(block.timestamp) > request.endTime, "Withdrawal not yet allowed.");

        bool isRouterVerified = controller.redeemFinalize(
            user,
            _to,
            _newCumLiqForClaims,
            _liqForClaimsProof,
            _newPercentReserved,
            _percentReservedProof
        );

        _update();

        // We're going to calculate uAmount a second time here then send the lesser of the two.
        // If we only calculate once, users can either get their full uAmount after a hack if percentReserved
        // hasn't been sent in, or users can earn yield after requesting redeem (with the same consequence).
        uint256 uAmount = _uValue(request.rcaAmount, amtForSale, percentReserved);
        if (request.uAmount < uAmount) uAmount = uint256(request.uAmount);

        pendingWithdrawal -= uint256(request.rcaAmount);

        uToken.safeTransfer(_to, uAmount);

        // The cool part about doing it this way rather than having user send RCAs to router contract,
        // then it exchanging and returning Ether is that it's more gas efficient and no approvals are needed.
        // (and no nonsense with the withdrawal delay making routers wonky)
        if (isRouterVerified) IRouter(_to).routeTo(user, uAmount, _routerData);

        emit RedeemFinalize(user, _to, uAmount, uint256(request.rcaAmount), block.timestamp);
    }

    /**
     * @notice Purchase underlying tokens directly. This will be preferred by bots.
     * @param _user The user to purchase tokens for.
     * @param _uAmount Amount of underlying tokens to purchase.
     * @param _uEthPrice Price of the underlying token in Ether per token.
     * @param _priceProof Merkle proof for the price.
     * @param _newCumLiqForClaims New cumulative amount for liquidation.
     * @param _liqForClaimsProof Merkle proof for new liquidation amounts.
     */
    function purchaseU(
        address _user,
        uint256 _uAmount,
        uint256 _uEthPrice,
        bytes32[] calldata _priceProof,
        uint256 _newCumLiqForClaims,
        bytes32[] calldata _liqForClaimsProof
    ) external payable virtual {
        // If user submits incorrect price, tx will fail here.
        controller.purchase(_user, address(uToken), _uEthPrice, _priceProof, _newCumLiqForClaims, _liqForClaimsProof);

        _update();

        uint256 price = _uEthPrice - ((_uEthPrice * discount) / DENOMINATOR);
        // divide by 1 ether because price also has 18 decimals.
        uint256 ethAmount = (price * _uAmount) / 1 ether;
        require(msg.value == ethAmount, "Incorrect Ether sent.");

        // If amount is bigger than for sale, tx will fail here.
        amtForSale -= _uAmount;

        uToken.safeTransfer(_user, _uAmount);
        treasury.transfer(msg.value);

        emit PurchaseU(_user, _uAmount, ethAmount, _uEthPrice, block.timestamp);
    }

    /**
     * @notice purchaseRca allows a user to purchase the RCA directly with Ether through liquidation.
     * @param _user The user to make the purchase for.
     * @param _uAmount The amount of underlying tokens to purchase.
     * @param _uEthPrice The underlying token price in Ether per token.
     * @param _priceProof Merkle proof to verify this price.
     * @param _newCumLiqForClaims Old cumulative amount for sale.
     * @param _liqForClaimsProof Merkle proof of the for sale amounts.
     */
    function purchaseRca(
        address _user,
        uint256 _uAmount,
        uint256 _uEthPrice,
        bytes32[] calldata _priceProof,
        uint256 _newCumLiqForClaims,
        bytes32[] calldata _liqForClaimsProof
    ) external payable {
        // If user submits incorrect price, tx will fail here.
        controller.purchase(_user, address(uToken), _uEthPrice, _priceProof, _newCumLiqForClaims, _liqForClaimsProof);

        _update();

        uint256 price = _uEthPrice - ((_uEthPrice * discount) / DENOMINATOR);
        // divide by 1 ether because price also has 18 decimals.
        uint256 ethAmount = (price * _uAmount) / 1 ether;
        require(msg.value == ethAmount, "Incorrect Ether sent.");

        // If amount is too big than for sale, tx will fail here.
        uint256 rcaAmount = _rcaValue(_uAmount, amtForSale);
        amtForSale -= _uAmount;

        _mint(_user, rcaAmount);
        treasury.transfer(msg.value);

        emit PurchaseRca(_user, _uAmount, rcaAmount, _uEthPrice, ethAmount, block.timestamp);
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////// view ////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @dev External version of RCA value is needed so that frontend can properly
     * calculate values in cases where the contract has not been recently updated.
     * @param _rcaAmount Amount of RCA tokens (18 decimal) to find the underlying token value of.
     * @param _cumLiqForClaims New cumulative liquidated if this must be updated.
     * @param _percentReserved Percent of tokens that are reserved after a hack payout.
     */
    function uValue(
        uint256 _rcaAmount,
        uint256 _cumLiqForClaims,
        uint256 _percentReserved
    ) external view returns (uint256 uAmount) {
        uint256 extraForSale = getExtraForSale(_cumLiqForClaims);
        uAmount = _uValue(_rcaAmount, amtForSale + extraForSale, _percentReserved);
    }

    /**
     * @dev External version of RCA value is needed so that frontend can properly
     * calculate values in cases where the contract has not been recently updated.
     * @param _uAmount Amount of underlying tokens (18 decimal).
     * @param _cumLiqForClaims New cumulative liquidated if this must be updated.
     */
    function rcaValue(uint256 _uAmount, uint256 _cumLiqForClaims) external view returns (uint256 rcaAmount) {
        uint256 extraForSale = getExtraForSale(_cumLiqForClaims);
        rcaAmount = _rcaValue(_uAmount, amtForSale + extraForSale);
    }

    /**
     * @notice Convert RCA value to underlying tokens. This is internal because new
     * for sale amounts will already have been retrieved and updated.
     * @param _rcaAmount The amount of RCAs to find the underlying value of.
     * @param _totalForSale Used by external value calls cause updates aren't made on those.
     * @param _percentReserved Percent of funds reserved if a hack is being examined.
     */
    function _uValue(
        uint256 _rcaAmount,
        uint256 _totalForSale,
        uint256 _percentReserved
    ) internal view returns (uint256 uAmount) {
        uint256 balance = _uBalance();

        if (totalSupply() == 0) return _rcaAmount;
        else if (balance < _totalForSale) return 0;

        uAmount = ((balance - _totalForSale) * _rcaAmount) / (totalSupply() + pendingWithdrawal);

        if (_percentReserved > 0) uAmount -= ((uAmount * _percentReserved) / DENOMINATOR);
    }

    /**
     * @notice Find the RCA value of an amount of underlying tokens.
     * @param _uAmount Amount of underlying tokens to find RCA value of.
     * @param _totalForSale Used by external value calls cause updates aren't made on those.
     */
    function _rcaValue(uint256 _uAmount, uint256 _totalForSale) internal view virtual returns (uint256 rcaAmount) {
        uint256 balance = _uBalance();

        // Interesting edgecase in which 1 person is in vault, they request redeem,
        // underlying continue to gain value, then withdraw their original value.
        // Vault is then un-useable because below we're dividing 0 by > 0.
        if (balance == 0 || totalSupply() == 0 || balance < _totalForSale) return _uAmount;

        rcaAmount = ((totalSupply() + pendingWithdrawal) * _uAmount) / (balance - _totalForSale);
    }

    /**
     * @notice For frontend calls. Doesn't need to verify info because it's not changing state.
     */
    function getExtraForSale(uint256 _newCumLiqForClaims) public view returns (uint256 extraForSale) {
        // Check for liquidation, then percent paused, then APR
        uint256 extraLiqForClaims = _newCumLiqForClaims - cumLiqForClaims;
        uint256 extraFees = _getInterimFees(controller.apr(), uint256(controller.getAprUpdate()));
        extraForSale = extraFees + extraLiqForClaims;
        return extraForSale;
    }

    /**
     * @notice Get the amount that should be added to "amtForSale" based on actions within the time since last update.
     * @dev If values have changed within the interim period,
     * this function averages them to find new owed amounts for fees.
     * @param _newApr new APR.
     * @param _aprUpdate start time for new APR.
     */
    function _getInterimFees(uint256 _newApr, uint256 _aprUpdate) internal view returns (uint256 fees) {
        // Get all variables that are currently in this contract's state.
        uint256 balance = _uBalance();
        uint256 aprAvg = apr * BUFFER;
        uint256 totalTimeElapsed = block.timestamp - lastUpdate;

        // Find average APR throughout period if it has been updated.
        if (_aprUpdate > lastUpdate) {
            uint256 aprPrev = apr * (_aprUpdate - lastUpdate);
            uint256 aprCur = _newApr * (block.timestamp - _aprUpdate);
            aprAvg = ((aprPrev + aprCur) * BUFFER) / totalTimeElapsed;
        }

        // Will probably never occur, but just in case.
        if (balance < amtForSale) return 0;

        // Calculate fees based on average active amount.
        uint256 activeInclReserved = balance - amtForSale;
        fees = (activeInclReserved * aprAvg * totalTimeElapsed) / YEAR_SECS / DENOMINATOR / BUFFER;
    }

    /**
     * @notice Grabs full underlying balance to make frontend fetching much easier.
     */
    function uBalance() external view returns (uint256) {
        return _uBalance();
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////// internal ///////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @notice Update the amtForSale if there's an active fee.
     */
    function _update() internal {
        if (apr > 0) {
            uint256 balance = _uBalance();

            // If liquidation for claims is set incorrectly this could occur and break the contract.
            if (balance < amtForSale) return;

            uint256 secsElapsed = block.timestamp - lastUpdate;
            uint256 active = balance - amtForSale;
            uint256 activeExclReserved = active - ((active * percentReserved) / DENOMINATOR);

            amtForSale += (activeExclReserved * secsElapsed * apr) / YEAR_SECS / DENOMINATOR;
        }

        lastUpdate = block.timestamp;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////// virtual ///////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// @notice Check balance of underlying token.
    function _uBalance() internal view virtual returns (uint256);

    /// @notice Logic to run after a mint, such as if we need to stake the underlying token.
    function _afterMint(uint256 _uAmount) internal virtual;

    /// @notice Logic to run after a redeem, such as unstaking.
    function _afterRedeem(uint256 _uAmount) internal virtual;

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////// onlyController //////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @notice Update function to be called by controller. This is only called when a controller has made
     * an APR update since the last shield update was made, so it must do extra calculations to determine
     * what the exact costs throughout the period were according to when system updates were made.
     */
    function controllerUpdate(uint256 _newApr, uint256 _aprUpdate) external onlyController {
        uint256 extraFees = _getInterimFees(_newApr, _aprUpdate);

        amtForSale += extraFees;
        lastUpdate = block.timestamp;
    }

    /**
     * @notice Add a for sale amount to this shield vault.
     * @param _newCumLiqForClaims New cumulative total for sale.
     **/
    function setLiqForClaims(uint256 _newCumLiqForClaims) external onlyController {
        if (_newCumLiqForClaims > cumLiqForClaims) {
            amtForSale += _newCumLiqForClaims - cumLiqForClaims;
        } else {
            uint256 subtrahend = cumLiqForClaims - _newCumLiqForClaims;
            amtForSale = amtForSale > subtrahend ? amtForSale - subtrahend : 0;
        }

        require(_uBalance() >= amtForSale, "amtForSale is too high.");

        cumLiqForClaims = _newCumLiqForClaims;
    }

    /**
     * @notice Change the treasury address to which funds will be sent.
     * @param _newTreasury New treasury address.
     **/
    function setTreasury(address _newTreasury) external onlyController {
        treasury = payable(_newTreasury);
    }

    /**
     * @notice Change the percent reserved on this vault. 1000 == 10%.
     * @param _newPercentReserved New percent reserved.
     **/
    function setPercentReserved(uint256 _newPercentReserved) external onlyController {
        // Protection to not have too much reserved from any single vault.
        if (_newPercentReserved > 3300) {
            percentReserved = 3300;
        } else {
            percentReserved = _newPercentReserved;
        }
    }

    /**
     * @notice Change the withdrawal delay of withdrawing underlying tokens from vault. In seconds.
     * @param _newWithdrawalDelay New withdrawal delay.
     **/
    function setWithdrawalDelay(uint256 _newWithdrawalDelay) external onlyController {
        withdrawalDelay = _newWithdrawalDelay;
    }

    /**
     * @notice Change the discount that users get for purchasing from us. 1000 == 10%.
     * @param _newDiscount New discount.
     **/
    function setDiscount(uint256 _newDiscount) external onlyController {
        discount = _newDiscount;
    }

    /**
     * @notice Change the treasury address to which funds will be sent.
     * @param _newApr New APR. 1000 == 10%.
     **/
    function setApr(uint256 _newApr) external onlyController {
        apr = _newApr;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////// onlyGov //////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @notice Update Controller to a new address. Very rare case for this to be used.
     * @param _newController Address of the new Controller contract.
     */
    function setController(address _newController) external onlyGov {
        controller = IRcaController(_newController);
    }

    /**
     * @notice Needed for Nexus to prove this contract lost funds. We'll likely have reinsurance
     * at least at the beginning to ensure we don't have too much risk in certain protocols.
     * @param _coverAddress Address that we need to send 0 eth to to confirm we had a loss.
     */
    function proofOfLoss(address payable _coverAddress) external onlyGov {
        _coverAddress.transfer(0);
    }
}

File 3 of 12 : Convex.sol
/// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.11;

interface IConvexRewardPool {
    function rewardToken() external view returns (address);

    function balanceOf(address account) external view returns (uint256);

    function extraRewardsLength() external view returns (uint256);

    function extraRewards(uint256 idx) external view returns (address);

    function getReward(address _user, bool _extra) external returns (bool);

    function stake(uint256 _amount) external returns (bool);

    function withdraw(uint256 _amount, bool _claim) external returns (bool);
}

File 4 of 12 : Governable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;

/**
 * @title Governable
 * @dev Pretty default ownable but with variable names changed to better convey owner.
 */
contract Governable {
    address payable private _governor;
    address payable private _pendingGovernor;

    event OwnershipTransferred(address indexed previousGovernor, address indexed newGovernor);
    event PendingOwnershipTransfer(address indexed from, address indexed to);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    function initializeGovernable(address _newGovernor) internal {
        require(_governor == address(0), "already initialized");
        _governor = payable(_newGovernor);
        emit OwnershipTransferred(address(0), _newGovernor);
    }

    /**
     * @return the address of the owner.
     */
    function governor() public view returns (address payable) {
        return _governor;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyGov() {
        require(isGov(), "msg.sender is not owner");
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isGov() public view returns (bool) {
        return msg.sender == _governor;
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newGovernor The address to transfer ownership to.
     */
    function transferOwnership(address payable newGovernor) public onlyGov {
        _pendingGovernor = newGovernor;
        emit PendingOwnershipTransfer(_governor, newGovernor);
    }

    function receiveOwnership() public {
        require(msg.sender == _pendingGovernor, "Only pending governor can call this function");
        _transferOwnership(_pendingGovernor);
        _pendingGovernor = payable(address(0));
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newGovernor The address to transfer ownership to.
     */
    function _transferOwnership(address payable newGovernor) internal {
        require(newGovernor != address(0));
        emit OwnershipTransferred(_governor, newGovernor);
        _governor = newGovernor;
    }

    uint256[50] private __gap;
}

File 5 of 12 : IRouter.sol
/// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.11;

interface IRouter {
    function routeTo(
        address user,
        uint256 uAmount,
        bytes calldata data
    ) external;
}

File 6 of 12 : IRcaController.sol
/// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.11;

interface IRcaController {
    function mint(
        address user,
        uint256 uAmount,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s,
        uint256 _newCumLiq,
        bytes32[] calldata cumLiqProof
    ) external;

    function redeemRequest(
        address user,
        uint256 _newCumLiq,
        bytes32[] calldata cumLiqProof,
        uint256 _newPercentReserved,
        bytes32[] calldata _percentReservedProof
    ) external;

    function redeemFinalize(
        address user,
        address _to,
        uint256 _newCumLiq,
        bytes32[] calldata cumLiqProof,
        uint256 _newPercentReserved,
        bytes32[] calldata _percentReservedProof
    ) external returns (bool);

    function purchase(
        address user,
        address uToken,
        uint256 uEthPrice,
        bytes32[] calldata priceProof,
        uint256 _newCumLiq,
        bytes32[] calldata cumLiqProof
    ) external;

    function verifyLiq(
        address shield,
        uint256 _newCumLiq,
        bytes32[] memory cumLiqProof
    ) external view;

    function verifyPrice(
        address shield,
        uint256 _value,
        bytes32[] memory _proof
    ) external view;

    function apr() external view returns (uint256);

    function getAprUpdate() external view returns (uint32);

    function systemUpdates()
        external
        view
        returns (
            uint32,
            uint32,
            uint32,
            uint32,
            uint32,
            uint32
        );
}

File 7 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

File 8 of 12 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

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

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

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

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

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

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

File 9 of 12 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 10 of 12 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

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

File 11 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 12 of 12 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_uToken","type":"address"},{"internalType":"address","name":"_governance","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"contract IConvexRewardPool","name":"_rewardPool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousGovernor","type":"address"},{"indexed":true,"internalType":"address","name":"newGovernor","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PendingOwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PurchaseRca","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PurchaseU","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RedeemFinalize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"uAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rcaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RedeemRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amtForSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"apr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IRcaController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newApr","type":"uint256"},{"internalType":"uint256","name":"_aprUpdate","type":"uint256"}],"name":"controllerUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cumLiqForClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"discount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"}],"name":"getExtraForSale","outputs":[{"internalType":"uint256","name":"extraForSale","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_apr","type":"uint256"},{"internalType":"uint256","name":"_discount","type":"uint256"},{"internalType":"address payable","name":"_treasury","type":"address"},{"internalType":"uint256","name":"_withdrawalDelay","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isGov","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"_referrer","type":"address"},{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_expiry","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"}],"name":"mintTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingWithdrawal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_coverAddress","type":"address"}],"name":"proofOfLoss","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_tokenPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_tokenPriceProof","type":"bytes32[]"},{"internalType":"uint256","name":"_underlyingPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_underlyinPriceProof","type":"bytes32[]"}],"name":"purchase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_uEthPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_priceProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"}],"name":"purchaseRca","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_uEthPrice","type":"uint256"},{"internalType":"bytes32[]","name":"_priceProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"}],"name":"purchaseU","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uAmount","type":"uint256"},{"internalType":"uint256","name":"_cumLiqForClaims","type":"uint256"}],"name":"rcaValue","outputs":[{"internalType":"uint256","name":"rcaAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"receiveOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_routerData","type":"bytes"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newPercentReserved","type":"uint256"},{"internalType":"bytes32[]","name":"_percentReservedProof","type":"bytes32[]"}],"name":"redeemFinalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rcaAmount","type":"uint256"},{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"},{"internalType":"bytes32[]","name":"_liqForClaimsProof","type":"bytes32[]"},{"internalType":"uint256","name":"_newPercentReserved","type":"uint256"},{"internalType":"bytes32[]","name":"_percentReservedProof","type":"bytes32[]"}],"name":"redeemRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPool","outputs":[{"internalType":"contract IConvexRewardPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newApr","type":"uint256"}],"name":"setApr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newController","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newDiscount","type":"uint256"}],"name":"setDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCumLiqForClaims","type":"uint256"}],"name":"setLiqForClaims","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPercentReserved","type":"uint256"}],"name":"setPercentReserved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTreasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newWithdrawalDelay","type":"uint256"}],"name":"setWithdrawalDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newGovernor","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rcaAmount","type":"uint256"},{"internalType":"uint256","name":"_cumLiqForClaims","type":"uint256"},{"internalType":"uint256","name":"_percentReserved","type":"uint256"}],"name":"uValue","outputs":[{"internalType":"uint256","name":"uAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawRequests","outputs":[{"internalType":"uint112","name":"uAmount","type":"uint112"},{"internalType":"uint112","name":"rcaAmount","type":"uint112"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60c06040523480156200001157600080fd5b5060405162003fa938038062003fa98339810160408190526200003491620006df565b8585858585848481600390805190602001906200005392919062000546565b5080516200006990600490602084019062000546565b5050506200007d82620000d960201b60201c565b6001600160a01b039283166080819052603980546001600160a01b0319169285169290921790915591851660a0819052620000cd9450919250600019905062000184602090811b62001f0217901c565b5050505050506200086d565b6005546001600160a01b031615620001385760405162461bcd60e51b815260206004820152601360248201527f616c726561647920696e697469616c697a65640000000000000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350565b801580620002025750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015620001da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020091906200079f565b155b620002765760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084016200012f565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620002ce918591620002d316565b505050565b60006200032f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620003b160201b6200204f179092919060201c565b805190915015620002ce5780806020019051810190620003509190620007b9565b620002ce5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016200012f565b6060620003c28484600085620003cc565b90505b9392505050565b6060824710156200042f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200012f565b6001600160a01b0385163b620004885760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200012f565b600080866001600160a01b03168587604051620004a69190620007dd565b60006040518083038185875af1925050503d8060008114620004e5576040519150601f19603f3d011682016040523d82523d6000602084013e620004ea565b606091505b509092509050620004fd82828662000508565b979650505050505050565b6060831562000519575081620003c5565b8251156200052a5782518084602001fd5b8160405162461bcd60e51b81526004016200012f9190620007fb565b828054620005549062000830565b90600052602060002090601f016020900481019282620005785760008555620005c3565b82601f106200059357805160ff1916838001178555620005c3565b82800160010185558215620005c3579182015b82811115620005c3578251825591602001919060010190620005a6565b50620005d1929150620005d5565b5090565b5b80821115620005d15760008155600101620005d6565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200061f57818101518382015260200162000605565b838111156200062f576000848401525b50505050565b600082601f8301126200064757600080fd5b81516001600160401b0380821115620006645762000664620005ec565b604051601f8301601f19908116603f011681019082821181831017156200068f576200068f620005ec565b81604052838152866020858801011115620006a957600080fd5b620006bc84602083016020890162000602565b9695505050505050565b6001600160a01b0381168114620006dc57600080fd5b50565b60008060008060008060c08789031215620006f957600080fd5b86516001600160401b03808211156200071157600080fd5b6200071f8a838b0162000635565b975060208901519150808211156200073657600080fd5b506200074589828a0162000635565b95505060408701516200075881620006c6565b60608801519094506200076b81620006c6565b60808801519093506200077e81620006c6565b60a08801519092506200079181620006c6565b809150509295509295509295565b600060208284031215620007b257600080fd5b5051919050565b600060208284031215620007cc57600080fd5b81518015158114620003c557600080fd5b60008251620007f181846020870162000602565b9190910192915050565b60208152600082518060208401526200081c81604085016020870162000602565b601f01601f19169190910160400192915050565b600181811c908216806200084557607f821691505b602082108114156200086757634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a0516136b4620008f56000396000818161052501528181610b1701528181611d580152818161288c01528181612a6d0152612abc0152600081816104f101528181610d6201528181610f360152818161160e0152818161195c01528181611a8001528181611b4101528181611c4f01528181611d1a0152612b4401526136b46000f3fe6080604052600436106102935760003560e01c80637c976cc61161015a578063cf9640b4116100c1578063ea1fd2df1161007a578063ea1fd2df14610837578063f0f4426014610857578063f2d348c214610877578063f2fde38b14610897578063f77c4791146108b7578063fc6b3204146108d757600080fd5b8063cf9640b41461075e578063d2c13da51461077e578063d786b6691461079e578063dabd2719146107be578063dc0e91eb146107de578063dd62ed3e146107f157600080fd5b8063a457c2d711610113578063a457c2d7146106bf578063a7ab6961146106df578063a9059cbb146106f5578063b5432b3114610715578063c646d14314610735578063cadc98fa1461074857600080fd5b80637c976cc61461061e5780637e2888221461063e5780638fbd1a6c1461065457806390c0a28b1461067457806392eefe9b1461068a57806395d89b41146106aa57600080fd5b806358f43751116101fe5780636b6f4a9d116101b75780636b6f4a9d146105675780636be2ca5f1461057d57806370a082311461059357806375e309ba146105c957806375f9fcb5146105e95780637712f5411461060957600080fd5b806358f437511461047f57806359cee29c1461049f57806361d027b3146104bf57806363315637146104df57806366666aa91461051357806366a0b0151461054757600080fd5b8063313ce56711610250578063313ce5671461037b57806339509351146103975780633b3ae2bb146103b75780633d18b912146103d757806352df49ec146103ec57806357ded9c91461046957600080fd5b806306fdde0314610298578063095ea7b3146102c35780630c340a24146102f357806318160ddd146103255780631c74a3011461034457806323b872dd1461035b575b600080fd5b3480156102a457600080fd5b506102ad6108f7565b6040516102ba9190612e19565b60405180910390f35b3480156102cf57600080fd5b506102e36102de366004612e61565b610989565b60405190151581526020016102ba565b3480156102ff57600080fd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016102ba565b34801561033157600080fd5b506002545b6040519081526020016102ba565b34801561035057600080fd5b506103596109a3565b005b34801561036757600080fd5b506102e3610376366004612e8d565b610a3e565b34801561038757600080fd5b50604051601281526020016102ba565b3480156103a357600080fd5b506102e36103b2366004612e61565b610a64565b3480156103c357600080fd5b506103596103d2366004612ece565b610aa3565b3480156103e357600080fd5b50610359610afb565b3480156103f857600080fd5b5061043d610407366004612ef0565b6042602052600090815260409020546001600160701b0380821691600160701b810490911690600160e01b900463ffffffff1683565b604080516001600160701b03948516815293909216602084015263ffffffff16908201526060016102ba565b34801561047557600080fd5b50610336603a5481565b34801561048b57600080fd5b5061035961049a366004612f59565b610b8f565b3480156104ab57600080fd5b506103596104ba366004613049565b610e70565b3480156104cb57600080fd5b50603c5461030d906001600160a01b031681565b3480156104eb57600080fd5b5061030d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561051f57600080fd5b5061030d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561055357600080fd5b50610359610562366004613062565b610e9f565b34801561057357600080fd5b50610336603b5481565b34801561058957600080fd5b50610336603f5481565b34801561059f57600080fd5b506103366105ae366004612ef0565b6001600160a01b031660009081526020819052604090205490565b3480156105d557600080fd5b506103366105e4366004612ece565b610fd0565b3480156105f557600080fd5b50610359610604366004613118565b610ffd565b34801561061557600080fd5b50610336611280565b34801561062a57600080fd5b50610359610639366004613049565b61128f565b34801561064a57600080fd5b5061033660405481565b34801561066057600080fd5b5061033661066f366004613049565b6112d1565b34801561068057600080fd5b50610336603d5481565b34801561069657600080fd5b506103596106a5366004612ef0565b6113ee565b3480156106b657600080fd5b506102ad61143a565b3480156106cb57600080fd5b506102e36106da366004612e61565b611449565b3480156106eb57600080fd5b5061033660415481565b34801561070157600080fd5b506102e3610710366004612e61565b6114e6565b34801561072157600080fd5b50610359610730366004613049565b6114f4565b6103596107433660046131a5565b6115e4565b34801561075457600080fd5b50610336603e5481565b34801561076a57600080fd5b50610359610779366004613244565b6117df565b34801561078a57600080fd5b50610359610799366004613049565b6118a5565b3480156107aa57600080fd5b506103366107b9366004613283565b6118d4565b3480156107ca57600080fd5b506103596107d9366004613049565b611903565b6103596107ec3660046131a5565b611932565b3480156107fd57600080fd5b5061033661080c3660046132af565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561084357600080fd5b506103596108523660046131a5565b611b3f565b34801561086357600080fd5b50610359610872366004612ef0565b611dd9565b34801561088357600080fd5b50610359610892366004612ef0565b611e25565b3480156108a357600080fd5b506103596108b2366004612ef0565b611e86565b3480156108c357600080fd5b5060395461030d906001600160a01b031681565b3480156108e357600080fd5b506005546001600160a01b031633146102e3565b606060038054610906906132e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610932906132e8565b801561097f5780601f106109545761010080835404028352916020019161097f565b820191906000526020600020905b81548152906001019060200180831161096257829003601f168201915b5050505050905090565b60003361099781858561205e565b60019150505b92915050565b6006546001600160a01b03163314610a175760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c792070656e64696e6720676f7665726e6f722063616e2063616c6c207460448201526b3434b990333ab731ba34b7b760a11b60648201526084015b60405180910390fd5b600654610a2c906001600160a01b0316612182565b600680546001600160a01b0319169055565b600033610a4c8582856121f1565b610a57858585612283565b60019150505b9392505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906109979082908690610a9e908790613339565b61205e565b6039546001600160a01b03163314610acd5760405162461bcd60e51b8152600401610a0e90613351565b6000610ad98383612451565b905080603f6000828254610aed9190613339565b909155505042604355505050565b604051637050ccd960e01b8152306004820152600160248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637050ccd9906044016020604051808303816000875af1158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c919061339c565b50565b336000818152604260208181526040808420815160608101835281546001600160701b038082168352600160701b8204168286015263ffffffff600160e01b9091048116938201938452878752949093529390935591511615801590610c045750806040015163ffffffff164263ffffffff16115b610c505760405162461bcd60e51b815260206004820152601b60248201527f5769746864726177616c206e6f742079657420616c6c6f7765642e00000000006044820152606401610a0e565b6000603960009054906101000a90046001600160a01b03166001600160a01b03166361c19974848e8c8c8c8c8c8c6040518963ffffffff1660e01b8152600401610ca19897969594939291906133f4565b6020604051808303816000875af1158015610cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce4919061339c565b9050610cee61256f565b6000610d0c83602001516001600160701b0316603f54603d54612633565b90508083600001516001600160701b03161015610d30575081516001600160701b03165b82602001516001600160701b031660406000828254610d4f9190613450565b90915550610d8990506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168e836126c8565b8115610df4578c6001600160a01b0316637dabc75785838f8f6040518563ffffffff1660e01b8152600401610dc19493929190613467565b600060405180830381600087803b158015610ddb57600080fd5b505af1158015610def573d6000803e3d6000fd5b505050505b8c6001600160a01b0316846001600160a01b03167f8e1e77f1fc31b0a9951d3ec7d02f21f3ec4f2248a09a6f4e37587303d0e961338386602001516001600160701b031642604051610e59939291909283526020830191909152604082015260600190565b60405180910390a350505050505050505050505050565b6039546001600160a01b03163314610e9a5760405162461bcd60e51b8152600401610a0e90613351565b603a55565b60395460405163f894849f60e01b81526001600160a01b039091169063f894849f90610edf908d908c908c908c908c908c908c908c908c906004016134af565b600060405180830381600087803b158015610ef957600080fd5b505af1158015610f0d573d6000803e3d6000fd5b50505050610f1961256f565b6000610f2789603f546126f8565b9050610f5e6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308c61275f565b610f688b82612797565b610f7189612876565b604080518a815260208101839052428183015290516001600160a01b038c811692908e169133917feca801b067fae3d181506c21fb55d44a644d16cdb863595643131a7e105b5f01919081900360600190a45050505050505050505050565b600080610fdc836112d1565b9050610ff58482603f54610ff09190613339565b6126f8565b949350505050565b6039546040516351374ca560e01b81526001600160a01b03909116906351374ca5906110399033908a908a908a908a908a908a90600401613509565b600060405180830381600087803b15801561105357600080fd5b505af1158015611067573d6000803e3d6000fd5b5050505061107361256f565b600061108488603f54603d54612633565b90506110903389612902565b61109981612a50565b87604060008282546110ab9190613339565b9091555050336000908152604260209081526040808320815160608101835290546001600160701b03808216808452600160701b830490911694830194909452600160e01b900463ffffffff1691810191909152919061110b9084613558565b9050600082602001518b61111f9190613558565b90506000604154426111319190613583565b90506040518060600160405280846001600160701b03168152602001836001600160701b031681526020018263ffffffff1681525060426000336001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a8154816001600160701b0302191690836001600160701b03160217905550602082015181600001600e6101000a8154816001600160701b0302191690836001600160701b03160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff160217905550905050336001600160a01b03167f0a5bed7081b3a25d92b911ed554f54dcff8d81e50faef20051436b4627625a8e868e8463ffffffff164260405161126a949392919093845260208401929092526040830152606082015260800190565b60405180910390a2505050505050505050505050565b600061128a612aa4565b905090565b6039546001600160a01b031633146112b95760405162461bcd60e51b8152600401610a0e90613351565b610ce48111156112cc57610ce4603d5550565b603d55565b600080603e54836112e29190613450565b905060006113e2603960009054906101000a90046001600160a01b03166001600160a01b03166357ded9c96040518163ffffffff1660e01b8152600401602060405180830381865afa15801561133c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136091906135a2565b603960009054906101000a90046001600160a01b03166001600160a01b031663e914ff6c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d791906135bb565b63ffffffff16612451565b9050610ff58282613339565b6005546001600160a01b031633146114185760405162461bcd60e51b8152600401610a0e906135e1565b603980546001600160a01b0319166001600160a01b0392909216919091179055565b606060048054610906906132e8565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156114ce5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610a0e565b6114db828686840361205e565b506001949350505050565b600033610997818585612283565b6039546001600160a01b0316331461151e5760405162461bcd60e51b8152600401610a0e90613351565b603e5481111561155157603e546115359082613450565b603f60008282546115469190613339565b909155506115869050565b600081603e546115619190613450565b905080603f5411611573576000611581565b80603f546115819190613450565b603f55505b603f54611591612aa4565b10156115df5760405162461bcd60e51b815260206004820152601760248201527f616d74466f7253616c6520697320746f6f20686967682e0000000000000000006044820152606401610a0e565b603e55565b603954604051637bdbfa3160e11b81526001600160a01b039091169063f7b7f46290611642908b907f0000000000000000000000000000000000000000000000000000000000000000908b908b908b908b908b908b906004016133f4565b600060405180830381600087803b15801561165c57600080fd5b505af1158015611670573d6000803e3d6000fd5b5050505061167c61256f565b6000612710603b548861168f9190613618565b6116999190613637565b6116a39088613450565b90506000670de0b6b3a76400006116ba8a84613618565b6116c49190613637565b905080341461170d5760405162461bcd60e51b815260206004820152601560248201527424b731b7b93932b1ba1022ba3432b91039b2b73a1760591b6044820152606401610a0e565b600061171b8a603f546126f8565b905089603f600082825461172f9190613450565b9091555061173f90508b82612797565b603c546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015611778573d6000803e3d6000fd5b50604080518b8152602081018390529081018a9052606081018390524260808201526001600160a01b038c16907f21945b242aeffcd052dd8b7c890383b76d0cc7d1249deeec70ac21cd42afe73e9060a00160405180910390a25050505050505050505050565b6039546001600160a01b031633146118095760405162461bcd60e51b8152600401610a0e90613351565b603c546001600160a01b0316156118715760405162461bcd60e51b815260206004820152602660248201527f436f6e74726163742068617320616c7265616479206265656e20696e697469616044820152653634bd32b21760d11b6064820152608401610a0e565b603a93909355603b91909155603c80546001600160a01b0319166001600160a01b0390921691909117905560415542604355565b6039546001600160a01b031633146118cf5760405162461bcd60e51b8152600401610a0e90613351565b604155565b6000806118e0846112d1565b90506118fa8582603f546118f49190613339565b85612633565b95945050505050565b6039546001600160a01b0316331461192d5760405162461bcd60e51b8152600401610a0e90613351565b603b55565b603954604051637bdbfa3160e11b81526001600160a01b039091169063f7b7f46290611990908b907f0000000000000000000000000000000000000000000000000000000000000000908b908b908b908b908b908b906004016133f4565b600060405180830381600087803b1580156119aa57600080fd5b505af11580156119be573d6000803e3d6000fd5b505050506119ca61256f565b6000612710603b54886119dd9190613618565b6119e79190613637565b6119f19088613450565b90506000670de0b6b3a7640000611a088a84613618565b611a129190613637565b9050803414611a5b5760405162461bcd60e51b815260206004820152601560248201527424b731b7b93932b1ba1022ba3432b91039b2b73a1760591b6044820152606401610a0e565b88603f6000828254611a6d9190613450565b90915550611aa790506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168b8b6126c8565b603c546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015611ae0573d6000803e3d6000fd5b50604080518a8152602081018390529081018990524260608201526001600160a01b038b16907fbb2ac200a6c3b8388dbcb5138a75011982b1d73b8ac94027392b22b64ef0fb4c9060800160405180910390a250505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b03161415611bc15760405162461bcd60e51b815260206004820152601b60248201527f63616e6e6f742062757920756e6465726c79696e6720746f6b656e00000000006044820152606401610a0e565b60395460405163644e0b0760e11b81526001600160a01b039091169063c89c160e90611bf7908b908a908a908a90600401613659565b60006040518083038186803b158015611c0f57600080fd5b505afa158015611c23573d6000803e3d6000fd5b505060395460405163644e0b0760e11b81526001600160a01b03909116925063c89c160e9150611c7d907f000000000000000000000000000000000000000000000000000000000000000090879087908790600401613659565b60006040518083038186803b158015611c9557600080fd5b505afa158015611ca9573d6000803e3d6000fd5b505050506000838789611cbc9190613618565b611cc69190613637565b603b5490915015611cf957612710603b5482611ce29190613618565b611cec9190613637565b611cf69082613450565b90505b611d0d6001600160a01b038a16338a6126c8565b611d426001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308461275f565b60405163534a7e1d60e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a694fc3a906024016020604051808303816000875af1158015611da9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dcd919061339c565b50505050505050505050565b6039546001600160a01b03163314611e035760405162461bcd60e51b8152600401610a0e90613351565b603c80546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b03163314611e4f5760405162461bcd60e51b8152600401610a0e906135e1565b6040516001600160a01b038216906108fc9060009081818181818888f19350505050158015611e82573d6000803e3d6000fd5b5050565b6005546001600160a01b03163314611eb05760405162461bcd60e51b8152600401610a0e906135e1565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907f23e1f881d1e797ea57a7247e53536f0bfc37c42e6645b3bdc4b1c9a0e0d8a13390600090a350565b801580611f7c5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7a91906135a2565b155b611fe75760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610a0e565b6040516001600160a01b03831660248201526044810182905261204a90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612bc1565b505050565b6060610ff58484600085612c93565b6001600160a01b0383166120c05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a0e565b6001600160a01b0382166121215760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a0e565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03811661219557600080fd5b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461227d57818110156122705760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610a0e565b61227d848484840361205e565b50505050565b6001600160a01b0383166122e75760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610a0e565b6001600160a01b0382166123495760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610a0e565b6001600160a01b038316600090815260208190526040902054818110156123c15760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610a0e565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906123f8908490613339565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161244491815260200190565b60405180910390a361227d565b60008061245c612aa4565b90506000670de0b6b3a7640000603a546124769190613618565b90506000604354426124889190613450565b90506043548511156124f8576000604354866124a49190613450565b603a546124b19190613618565b905060006124bf8742613450565b6124c99089613618565b905082670de0b6b3a76400006124df8385613339565b6124e99190613618565b6124f39190613637565b935050505b603f5483101561250e576000935050505061099d565b6000603f548461251e9190613450565b9050670de0b6b3a76400006127106301e133808461253c8786613618565b6125469190613618565b6125509190613637565b61255a9190613637565b6125649190613637565b979650505050505050565b603a541561262d576000612581612aa4565b9050603f548110156125905750565b6000604354426125a09190613450565b90506000603f54836125b29190613450565b90506000612710603d54836125c79190613618565b6125d19190613637565b6125db9083613450565b90506127106301e13380603a5485846125f49190613618565b6125fe9190613618565b6126089190613637565b6126129190613637565b603f60008282546126239190613339565b9091555050505050505b42604355565b60008061263e612aa4565b905061264960025490565b6126565784915050610a5d565b83811015612668576000915050610a5d565b6040546002546126789190613339565b856126838684613450565b61268d9190613618565b6126979190613637565b915082156126c0576127106126ac8484613618565b6126b69190613637565b6118fa9083613450565b509392505050565b6040516001600160a01b03831660248201526044810182905261204a90849063a9059cbb60e01b90606401612013565b600080612703612aa4565b90508015806127125750600254155b8061271c57508281105b1561272a578391505061099d565b6127348382613450565b8460405461274160025490565b61274b9190613339565b6127559190613618565b610ff59190613637565b6040516001600160a01b038085166024830152831660448201526064810182905261227d9085906323b872dd60e01b90608401612013565b6001600160a01b0382166127ed5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a0e565b80600260008282546127ff9190613339565b90915550506001600160a01b0382166000908152602081905260408120805483929061282c908490613339565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60405163534a7e1d60e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a694fc3a906024015b6020604051808303816000875af11580156128de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e82919061339c565b6001600160a01b0382166129625760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a0e565b6001600160a01b038216600090815260208190526040902054818110156129d65760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a0e565b6001600160a01b0383166000908152602081905260408120838303905560028054849290612a05908490613450565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b604051631c683a1b60e11b815260048101829052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906338d07436906044016128bf565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2f91906135a2565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612b93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb791906135a2565b61128a9190613339565b6000612c16826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661204f9092919063ffffffff16565b80519091501561204a5780806020019051810190612c34919061339c565b61204a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a0e565b606082471015612cf45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a0e565b6001600160a01b0385163b612d4b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a0e565b600080866001600160a01b03168587604051612d67919061368b565b60006040518083038185875af1925050503d8060008114612da4576040519150601f19603f3d011682016040523d82523d6000602084013e612da9565b606091505b509150915061256482828660608315612dc3575081610a5d565b825115612dd35782518084602001fd5b8160405162461bcd60e51b8152600401610a0e9190612e19565b60005b83811015612e08578181015183820152602001612df0565b8381111561227d5750506000910152565b6020815260008251806020840152612e38816040850160208701612ded565b601f01601f19169190910160400192915050565b6001600160a01b0381168114610b8c57600080fd5b60008060408385031215612e7457600080fd5b8235612e7f81612e4c565b946020939093013593505050565b600080600060608486031215612ea257600080fd5b8335612ead81612e4c565b92506020840135612ebd81612e4c565b929592945050506040919091013590565b60008060408385031215612ee157600080fd5b50508035926020909101359150565b600060208284031215612f0257600080fd5b8135610a5d81612e4c565b60008083601f840112612f1f57600080fd5b50813567ffffffffffffffff811115612f3757600080fd5b6020830191508360208260051b8501011115612f5257600080fd5b9250929050565b600080600080600080600080600060c08a8c031215612f7757600080fd5b8935612f8281612e4c565b985060208a013567ffffffffffffffff80821115612f9f57600080fd5b818c0191508c601f830112612fb357600080fd5b813581811115612fc257600080fd5b8d6020828501011115612fd457600080fd5b602083019a508099505060408c0135975060608c0135915080821115612ff957600080fd5b6130058d838e01612f0d565b909750955060808c0135945060a08c013591508082111561302557600080fd5b506130328c828d01612f0d565b915080935050809150509295985092959850929598565b60006020828403121561305b57600080fd5b5035919050565b6000806000806000806000806000806101208b8d03121561308257600080fd5b8a3561308d81612e4c565b995060208b013561309d81612e4c565b985060408b0135975060608b0135965060808b013560ff811681146130c157600080fd5b955060a08b0135945060c08b0135935060e08b013592506101008b013567ffffffffffffffff8111156130f357600080fd5b6130ff8d828e01612f0d565b915080935050809150509295989b9194979a5092959850565b600080600080600080600060a0888a03121561313357600080fd5b8735965060208801359550604088013567ffffffffffffffff8082111561315957600080fd5b6131658b838c01612f0d565b909750955060608a0135945060808a013591508082111561318557600080fd5b506131928a828b01612f0d565b989b979a50959850939692959293505050565b60008060008060008060008060c0898b0312156131c157600080fd5b88356131cc81612e4c565b97506020890135965060408901359550606089013567ffffffffffffffff808211156131f757600080fd5b6132038c838d01612f0d565b909750955060808b0135945060a08b013591508082111561322357600080fd5b506132308b828c01612f0d565b999c989b5096995094979396929594505050565b6000806000806080858703121561325a57600080fd5b8435935060208501359250604085013561327381612e4c565b9396929550929360600135925050565b60008060006060848603121561329857600080fd5b505081359360208301359350604090920135919050565b600080604083850312156132c257600080fd5b82356132cd81612e4c565b915060208301356132dd81612e4c565b809150509250929050565b600181811c908216806132fc57607f821691505b6020821081141561331d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561334c5761334c613323565b500190565b6020808252602b908201527f46756e6374696f6e206d757374206f6e6c792062652063616c6c65642062792060408201526a31b7b73a3937b63632b91760a91b606082015260800190565b6000602082840312156133ae57600080fd5b81518015158114610a5d57600080fd5b81835260006001600160fb1b038311156133d757600080fd5b8260051b8083602087013760009401602001938452509192915050565b6001600160a01b038981168252881660208201526040810187905260c06060820181905260009061342890830187896133be565b85608084015282810360a08401526134418185876133be565b9b9a5050505050505050505050565b60008282101561346257613462613323565b500390565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b600061010060018060a01b038c1683528a602084015289604084015260ff891660608401528760808401528660a08401528560c08401528060e08401526134f981840185876133be565b9c9b505050505050505050505050565b60018060a01b038816815286602082015260a06040820152600061353160a0830187896133be565b856060840152828103608084015261354a8185876133be565b9a9950505050505050505050565b60006001600160701b0380831681851680830382111561357a5761357a613323565b01949350505050565b600063ffffffff80831681851680830382111561357a5761357a613323565b6000602082840312156135b457600080fd5b5051919050565b6000602082840312156135cd57600080fd5b815163ffffffff81168114610a5d57600080fd5b60208082526017908201527f6d73672e73656e646572206973206e6f74206f776e6572000000000000000000604082015260600190565b600081600019048311821515161561363257613632613323565b500290565b60008261365457634e487b7160e01b600052601260045260246000fd5b500490565b60018060a01b03851681528360208201526060604082015260006136816060830184866133be565b9695505050505050565b6000825161369d818460208701612ded565b919091019291505056fea164736f6c634300080b000a00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba0000000000000000000000005afedef13bd7b3e363db724420d773caa8b88763000000000000000000000000ea5edef1a7106d9e2024240299df3d00c7d94767000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa00000000000000000000000000000000000000000000000000000000000000176376786372764356584554482045617365205661756c74000000000000000000000000000000000000000000000000000000000000000000000000000000000f657a2d6376786372764356584554480000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102935760003560e01c80637c976cc61161015a578063cf9640b4116100c1578063ea1fd2df1161007a578063ea1fd2df14610837578063f0f4426014610857578063f2d348c214610877578063f2fde38b14610897578063f77c4791146108b7578063fc6b3204146108d757600080fd5b8063cf9640b41461075e578063d2c13da51461077e578063d786b6691461079e578063dabd2719146107be578063dc0e91eb146107de578063dd62ed3e146107f157600080fd5b8063a457c2d711610113578063a457c2d7146106bf578063a7ab6961146106df578063a9059cbb146106f5578063b5432b3114610715578063c646d14314610735578063cadc98fa1461074857600080fd5b80637c976cc61461061e5780637e2888221461063e5780638fbd1a6c1461065457806390c0a28b1461067457806392eefe9b1461068a57806395d89b41146106aa57600080fd5b806358f43751116101fe5780636b6f4a9d116101b75780636b6f4a9d146105675780636be2ca5f1461057d57806370a082311461059357806375e309ba146105c957806375f9fcb5146105e95780637712f5411461060957600080fd5b806358f437511461047f57806359cee29c1461049f57806361d027b3146104bf57806363315637146104df57806366666aa91461051357806366a0b0151461054757600080fd5b8063313ce56711610250578063313ce5671461037b57806339509351146103975780633b3ae2bb146103b75780633d18b912146103d757806352df49ec146103ec57806357ded9c91461046957600080fd5b806306fdde0314610298578063095ea7b3146102c35780630c340a24146102f357806318160ddd146103255780631c74a3011461034457806323b872dd1461035b575b600080fd5b3480156102a457600080fd5b506102ad6108f7565b6040516102ba9190612e19565b60405180910390f35b3480156102cf57600080fd5b506102e36102de366004612e61565b610989565b60405190151581526020016102ba565b3480156102ff57600080fd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016102ba565b34801561033157600080fd5b506002545b6040519081526020016102ba565b34801561035057600080fd5b506103596109a3565b005b34801561036757600080fd5b506102e3610376366004612e8d565b610a3e565b34801561038757600080fd5b50604051601281526020016102ba565b3480156103a357600080fd5b506102e36103b2366004612e61565b610a64565b3480156103c357600080fd5b506103596103d2366004612ece565b610aa3565b3480156103e357600080fd5b50610359610afb565b3480156103f857600080fd5b5061043d610407366004612ef0565b6042602052600090815260409020546001600160701b0380821691600160701b810490911690600160e01b900463ffffffff1683565b604080516001600160701b03948516815293909216602084015263ffffffff16908201526060016102ba565b34801561047557600080fd5b50610336603a5481565b34801561048b57600080fd5b5061035961049a366004612f59565b610b8f565b3480156104ab57600080fd5b506103596104ba366004613049565b610e70565b3480156104cb57600080fd5b50603c5461030d906001600160a01b031681565b3480156104eb57600080fd5b5061030d7f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba81565b34801561051f57600080fd5b5061030d7f000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa81565b34801561055357600080fd5b50610359610562366004613062565b610e9f565b34801561057357600080fd5b50610336603b5481565b34801561058957600080fd5b50610336603f5481565b34801561059f57600080fd5b506103366105ae366004612ef0565b6001600160a01b031660009081526020819052604090205490565b3480156105d557600080fd5b506103366105e4366004612ece565b610fd0565b3480156105f557600080fd5b50610359610604366004613118565b610ffd565b34801561061557600080fd5b50610336611280565b34801561062a57600080fd5b50610359610639366004613049565b61128f565b34801561064a57600080fd5b5061033660405481565b34801561066057600080fd5b5061033661066f366004613049565b6112d1565b34801561068057600080fd5b50610336603d5481565b34801561069657600080fd5b506103596106a5366004612ef0565b6113ee565b3480156106b657600080fd5b506102ad61143a565b3480156106cb57600080fd5b506102e36106da366004612e61565b611449565b3480156106eb57600080fd5b5061033660415481565b34801561070157600080fd5b506102e3610710366004612e61565b6114e6565b34801561072157600080fd5b50610359610730366004613049565b6114f4565b6103596107433660046131a5565b6115e4565b34801561075457600080fd5b50610336603e5481565b34801561076a57600080fd5b50610359610779366004613244565b6117df565b34801561078a57600080fd5b50610359610799366004613049565b6118a5565b3480156107aa57600080fd5b506103366107b9366004613283565b6118d4565b3480156107ca57600080fd5b506103596107d9366004613049565b611903565b6103596107ec3660046131a5565b611932565b3480156107fd57600080fd5b5061033661080c3660046132af565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b34801561084357600080fd5b506103596108523660046131a5565b611b3f565b34801561086357600080fd5b50610359610872366004612ef0565b611dd9565b34801561088357600080fd5b50610359610892366004612ef0565b611e25565b3480156108a357600080fd5b506103596108b2366004612ef0565b611e86565b3480156108c357600080fd5b5060395461030d906001600160a01b031681565b3480156108e357600080fd5b506005546001600160a01b031633146102e3565b606060038054610906906132e8565b80601f0160208091040260200160405190810160405280929190818152602001828054610932906132e8565b801561097f5780601f106109545761010080835404028352916020019161097f565b820191906000526020600020905b81548152906001019060200180831161096257829003601f168201915b5050505050905090565b60003361099781858561205e565b60019150505b92915050565b6006546001600160a01b03163314610a175760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c792070656e64696e6720676f7665726e6f722063616e2063616c6c207460448201526b3434b990333ab731ba34b7b760a11b60648201526084015b60405180910390fd5b600654610a2c906001600160a01b0316612182565b600680546001600160a01b0319169055565b600033610a4c8582856121f1565b610a57858585612283565b60019150505b9392505050565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091906109979082908690610a9e908790613339565b61205e565b6039546001600160a01b03163314610acd5760405162461bcd60e51b8152600401610a0e90613351565b6000610ad98383612451565b905080603f6000828254610aed9190613339565b909155505042604355505050565b604051637050ccd960e01b8152306004820152600160248201527f000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa6001600160a01b031690637050ccd9906044016020604051808303816000875af1158015610b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8c919061339c565b50565b336000818152604260208181526040808420815160608101835281546001600160701b038082168352600160701b8204168286015263ffffffff600160e01b9091048116938201938452878752949093529390935591511615801590610c045750806040015163ffffffff164263ffffffff16115b610c505760405162461bcd60e51b815260206004820152601b60248201527f5769746864726177616c206e6f742079657420616c6c6f7765642e00000000006044820152606401610a0e565b6000603960009054906101000a90046001600160a01b03166001600160a01b03166361c19974848e8c8c8c8c8c8c6040518963ffffffff1660e01b8152600401610ca19897969594939291906133f4565b6020604051808303816000875af1158015610cc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce4919061339c565b9050610cee61256f565b6000610d0c83602001516001600160701b0316603f54603d54612633565b90508083600001516001600160701b03161015610d30575081516001600160701b03165b82602001516001600160701b031660406000828254610d4f9190613450565b90915550610d8990506001600160a01b037f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba168e836126c8565b8115610df4578c6001600160a01b0316637dabc75785838f8f6040518563ffffffff1660e01b8152600401610dc19493929190613467565b600060405180830381600087803b158015610ddb57600080fd5b505af1158015610def573d6000803e3d6000fd5b505050505b8c6001600160a01b0316846001600160a01b03167f8e1e77f1fc31b0a9951d3ec7d02f21f3ec4f2248a09a6f4e37587303d0e961338386602001516001600160701b031642604051610e59939291909283526020830191909152604082015260600190565b60405180910390a350505050505050505050505050565b6039546001600160a01b03163314610e9a5760405162461bcd60e51b8152600401610a0e90613351565b603a55565b60395460405163f894849f60e01b81526001600160a01b039091169063f894849f90610edf908d908c908c908c908c908c908c908c908c906004016134af565b600060405180830381600087803b158015610ef957600080fd5b505af1158015610f0d573d6000803e3d6000fd5b50505050610f1961256f565b6000610f2789603f546126f8565b9050610f5e6001600160a01b037f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba1633308c61275f565b610f688b82612797565b610f7189612876565b604080518a815260208101839052428183015290516001600160a01b038c811692908e169133917feca801b067fae3d181506c21fb55d44a644d16cdb863595643131a7e105b5f01919081900360600190a45050505050505050505050565b600080610fdc836112d1565b9050610ff58482603f54610ff09190613339565b6126f8565b949350505050565b6039546040516351374ca560e01b81526001600160a01b03909116906351374ca5906110399033908a908a908a908a908a908a90600401613509565b600060405180830381600087803b15801561105357600080fd5b505af1158015611067573d6000803e3d6000fd5b5050505061107361256f565b600061108488603f54603d54612633565b90506110903389612902565b61109981612a50565b87604060008282546110ab9190613339565b9091555050336000908152604260209081526040808320815160608101835290546001600160701b03808216808452600160701b830490911694830194909452600160e01b900463ffffffff1691810191909152919061110b9084613558565b9050600082602001518b61111f9190613558565b90506000604154426111319190613583565b90506040518060600160405280846001600160701b03168152602001836001600160701b031681526020018263ffffffff1681525060426000336001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a8154816001600160701b0302191690836001600160701b03160217905550602082015181600001600e6101000a8154816001600160701b0302191690836001600160701b03160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff160217905550905050336001600160a01b03167f0a5bed7081b3a25d92b911ed554f54dcff8d81e50faef20051436b4627625a8e868e8463ffffffff164260405161126a949392919093845260208401929092526040830152606082015260800190565b60405180910390a2505050505050505050505050565b600061128a612aa4565b905090565b6039546001600160a01b031633146112b95760405162461bcd60e51b8152600401610a0e90613351565b610ce48111156112cc57610ce4603d5550565b603d55565b600080603e54836112e29190613450565b905060006113e2603960009054906101000a90046001600160a01b03166001600160a01b03166357ded9c96040518163ffffffff1660e01b8152600401602060405180830381865afa15801561133c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136091906135a2565b603960009054906101000a90046001600160a01b03166001600160a01b031663e914ff6c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d791906135bb565b63ffffffff16612451565b9050610ff58282613339565b6005546001600160a01b031633146114185760405162461bcd60e51b8152600401610a0e906135e1565b603980546001600160a01b0319166001600160a01b0392909216919091179055565b606060048054610906906132e8565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909190838110156114ce5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610a0e565b6114db828686840361205e565b506001949350505050565b600033610997818585612283565b6039546001600160a01b0316331461151e5760405162461bcd60e51b8152600401610a0e90613351565b603e5481111561155157603e546115359082613450565b603f60008282546115469190613339565b909155506115869050565b600081603e546115619190613450565b905080603f5411611573576000611581565b80603f546115819190613450565b603f55505b603f54611591612aa4565b10156115df5760405162461bcd60e51b815260206004820152601760248201527f616d74466f7253616c6520697320746f6f20686967682e0000000000000000006044820152606401610a0e565b603e55565b603954604051637bdbfa3160e11b81526001600160a01b039091169063f7b7f46290611642908b907f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba908b908b908b908b908b908b906004016133f4565b600060405180830381600087803b15801561165c57600080fd5b505af1158015611670573d6000803e3d6000fd5b5050505061167c61256f565b6000612710603b548861168f9190613618565b6116999190613637565b6116a39088613450565b90506000670de0b6b3a76400006116ba8a84613618565b6116c49190613637565b905080341461170d5760405162461bcd60e51b815260206004820152601560248201527424b731b7b93932b1ba1022ba3432b91039b2b73a1760591b6044820152606401610a0e565b600061171b8a603f546126f8565b905089603f600082825461172f9190613450565b9091555061173f90508b82612797565b603c546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015611778573d6000803e3d6000fd5b50604080518b8152602081018390529081018a9052606081018390524260808201526001600160a01b038c16907f21945b242aeffcd052dd8b7c890383b76d0cc7d1249deeec70ac21cd42afe73e9060a00160405180910390a25050505050505050505050565b6039546001600160a01b031633146118095760405162461bcd60e51b8152600401610a0e90613351565b603c546001600160a01b0316156118715760405162461bcd60e51b815260206004820152602660248201527f436f6e74726163742068617320616c7265616479206265656e20696e697469616044820152653634bd32b21760d11b6064820152608401610a0e565b603a93909355603b91909155603c80546001600160a01b0319166001600160a01b0390921691909117905560415542604355565b6039546001600160a01b031633146118cf5760405162461bcd60e51b8152600401610a0e90613351565b604155565b6000806118e0846112d1565b90506118fa8582603f546118f49190613339565b85612633565b95945050505050565b6039546001600160a01b0316331461192d5760405162461bcd60e51b8152600401610a0e90613351565b603b55565b603954604051637bdbfa3160e11b81526001600160a01b039091169063f7b7f46290611990908b907f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba908b908b908b908b908b908b906004016133f4565b600060405180830381600087803b1580156119aa57600080fd5b505af11580156119be573d6000803e3d6000fd5b505050506119ca61256f565b6000612710603b54886119dd9190613618565b6119e79190613637565b6119f19088613450565b90506000670de0b6b3a7640000611a088a84613618565b611a129190613637565b9050803414611a5b5760405162461bcd60e51b815260206004820152601560248201527424b731b7b93932b1ba1022ba3432b91039b2b73a1760591b6044820152606401610a0e565b88603f6000828254611a6d9190613450565b90915550611aa790506001600160a01b037f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba168b8b6126c8565b603c546040516001600160a01b03909116903480156108fc02916000818181858888f19350505050158015611ae0573d6000803e3d6000fd5b50604080518a8152602081018390529081018990524260608201526001600160a01b038b16907fbb2ac200a6c3b8388dbcb5138a75011982b1d73b8ac94027392b22b64ef0fb4c9060800160405180910390a250505050505050505050565b7f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba6001600160a01b0316886001600160a01b03161415611bc15760405162461bcd60e51b815260206004820152601b60248201527f63616e6e6f742062757920756e6465726c79696e6720746f6b656e00000000006044820152606401610a0e565b60395460405163644e0b0760e11b81526001600160a01b039091169063c89c160e90611bf7908b908a908a908a90600401613659565b60006040518083038186803b158015611c0f57600080fd5b505afa158015611c23573d6000803e3d6000fd5b505060395460405163644e0b0760e11b81526001600160a01b03909116925063c89c160e9150611c7d907f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba90879087908790600401613659565b60006040518083038186803b158015611c9557600080fd5b505afa158015611ca9573d6000803e3d6000fd5b505050506000838789611cbc9190613618565b611cc69190613637565b603b5490915015611cf957612710603b5482611ce29190613618565b611cec9190613637565b611cf69082613450565b90505b611d0d6001600160a01b038a16338a6126c8565b611d426001600160a01b037f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba1633308461275f565b60405163534a7e1d60e11b8152600481018290527f000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa6001600160a01b03169063a694fc3a906024016020604051808303816000875af1158015611da9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dcd919061339c565b50505050505050505050565b6039546001600160a01b03163314611e035760405162461bcd60e51b8152600401610a0e90613351565b603c80546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b03163314611e4f5760405162461bcd60e51b8152600401610a0e906135e1565b6040516001600160a01b038216906108fc9060009081818181818888f19350505050158015611e82573d6000803e3d6000fd5b5050565b6005546001600160a01b03163314611eb05760405162461bcd60e51b8152600401610a0e906135e1565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907f23e1f881d1e797ea57a7247e53536f0bfc37c42e6645b3bdc4b1c9a0e0d8a13390600090a350565b801580611f7c5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7a91906135a2565b155b611fe75760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610a0e565b6040516001600160a01b03831660248201526044810182905261204a90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612bc1565b505050565b6060610ff58484600085612c93565b6001600160a01b0383166120c05760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a0e565b6001600160a01b0382166121215760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a0e565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03811661219557600080fd5b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461227d57818110156122705760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610a0e565b61227d848484840361205e565b50505050565b6001600160a01b0383166122e75760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610a0e565b6001600160a01b0382166123495760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610a0e565b6001600160a01b038316600090815260208190526040902054818110156123c15760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610a0e565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906123f8908490613339565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161244491815260200190565b60405180910390a361227d565b60008061245c612aa4565b90506000670de0b6b3a7640000603a546124769190613618565b90506000604354426124889190613450565b90506043548511156124f8576000604354866124a49190613450565b603a546124b19190613618565b905060006124bf8742613450565b6124c99089613618565b905082670de0b6b3a76400006124df8385613339565b6124e99190613618565b6124f39190613637565b935050505b603f5483101561250e576000935050505061099d565b6000603f548461251e9190613450565b9050670de0b6b3a76400006127106301e133808461253c8786613618565b6125469190613618565b6125509190613637565b61255a9190613637565b6125649190613637565b979650505050505050565b603a541561262d576000612581612aa4565b9050603f548110156125905750565b6000604354426125a09190613450565b90506000603f54836125b29190613450565b90506000612710603d54836125c79190613618565b6125d19190613637565b6125db9083613450565b90506127106301e13380603a5485846125f49190613618565b6125fe9190613618565b6126089190613637565b6126129190613637565b603f60008282546126239190613339565b9091555050505050505b42604355565b60008061263e612aa4565b905061264960025490565b6126565784915050610a5d565b83811015612668576000915050610a5d565b6040546002546126789190613339565b856126838684613450565b61268d9190613618565b6126979190613637565b915082156126c0576127106126ac8484613618565b6126b69190613637565b6118fa9083613450565b509392505050565b6040516001600160a01b03831660248201526044810182905261204a90849063a9059cbb60e01b90606401612013565b600080612703612aa4565b90508015806127125750600254155b8061271c57508281105b1561272a578391505061099d565b6127348382613450565b8460405461274160025490565b61274b9190613339565b6127559190613618565b610ff59190613637565b6040516001600160a01b038085166024830152831660448201526064810182905261227d9085906323b872dd60e01b90608401612013565b6001600160a01b0382166127ed5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a0e565b80600260008282546127ff9190613339565b90915550506001600160a01b0382166000908152602081905260408120805483929061282c908490613339565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60405163534a7e1d60e11b8152600481018290527f000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa6001600160a01b03169063a694fc3a906024015b6020604051808303816000875af11580156128de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e82919061339c565b6001600160a01b0382166129625760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a0e565b6001600160a01b038216600090815260208190526040902054818110156129d65760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a0e565b6001600160a01b0383166000908152602081905260408120838303905560028054849290612a05908490613450565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b604051631c683a1b60e11b815260048101829052600060248201527f000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa6001600160a01b0316906338d07436906044016128bf565b6040516370a0823160e01b81523060048201526000907f000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa6001600160a01b0316906370a0823190602401602060405180830381865afa158015612b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2f91906135a2565b6040516370a0823160e01b81523060048201527f0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba6001600160a01b0316906370a0823190602401602060405180830381865afa158015612b93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb791906135a2565b61128a9190613339565b6000612c16826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661204f9092919063ffffffff16565b80519091501561204a5780806020019051810190612c34919061339c565b61204a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a0e565b606082471015612cf45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a0e565b6001600160a01b0385163b612d4b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a0e565b600080866001600160a01b03168587604051612d67919061368b565b60006040518083038185875af1925050503d8060008114612da4576040519150601f19603f3d011682016040523d82523d6000602084013e612da9565b606091505b509150915061256482828660608315612dc3575081610a5d565b825115612dd35782518084602001fd5b8160405162461bcd60e51b8152600401610a0e9190612e19565b60005b83811015612e08578181015183820152602001612df0565b8381111561227d5750506000910152565b6020815260008251806020840152612e38816040850160208701612ded565b601f01601f19169190910160400192915050565b6001600160a01b0381168114610b8c57600080fd5b60008060408385031215612e7457600080fd5b8235612e7f81612e4c565b946020939093013593505050565b600080600060608486031215612ea257600080fd5b8335612ead81612e4c565b92506020840135612ebd81612e4c565b929592945050506040919091013590565b60008060408385031215612ee157600080fd5b50508035926020909101359150565b600060208284031215612f0257600080fd5b8135610a5d81612e4c565b60008083601f840112612f1f57600080fd5b50813567ffffffffffffffff811115612f3757600080fd5b6020830191508360208260051b8501011115612f5257600080fd5b9250929050565b600080600080600080600080600060c08a8c031215612f7757600080fd5b8935612f8281612e4c565b985060208a013567ffffffffffffffff80821115612f9f57600080fd5b818c0191508c601f830112612fb357600080fd5b813581811115612fc257600080fd5b8d6020828501011115612fd457600080fd5b602083019a508099505060408c0135975060608c0135915080821115612ff957600080fd5b6130058d838e01612f0d565b909750955060808c0135945060a08c013591508082111561302557600080fd5b506130328c828d01612f0d565b915080935050809150509295985092959850929598565b60006020828403121561305b57600080fd5b5035919050565b6000806000806000806000806000806101208b8d03121561308257600080fd5b8a3561308d81612e4c565b995060208b013561309d81612e4c565b985060408b0135975060608b0135965060808b013560ff811681146130c157600080fd5b955060a08b0135945060c08b0135935060e08b013592506101008b013567ffffffffffffffff8111156130f357600080fd5b6130ff8d828e01612f0d565b915080935050809150509295989b9194979a5092959850565b600080600080600080600060a0888a03121561313357600080fd5b8735965060208801359550604088013567ffffffffffffffff8082111561315957600080fd5b6131658b838c01612f0d565b909750955060608a0135945060808a013591508082111561318557600080fd5b506131928a828b01612f0d565b989b979a50959850939692959293505050565b60008060008060008060008060c0898b0312156131c157600080fd5b88356131cc81612e4c565b97506020890135965060408901359550606089013567ffffffffffffffff808211156131f757600080fd5b6132038c838d01612f0d565b909750955060808b0135945060a08b013591508082111561322357600080fd5b506132308b828c01612f0d565b999c989b5096995094979396929594505050565b6000806000806080858703121561325a57600080fd5b8435935060208501359250604085013561327381612e4c565b9396929550929360600135925050565b60008060006060848603121561329857600080fd5b505081359360208301359350604090920135919050565b600080604083850312156132c257600080fd5b82356132cd81612e4c565b915060208301356132dd81612e4c565b809150509250929050565b600181811c908216806132fc57607f821691505b6020821081141561331d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561334c5761334c613323565b500190565b6020808252602b908201527f46756e6374696f6e206d757374206f6e6c792062652063616c6c65642062792060408201526a31b7b73a3937b63632b91760a91b606082015260800190565b6000602082840312156133ae57600080fd5b81518015158114610a5d57600080fd5b81835260006001600160fb1b038311156133d757600080fd5b8260051b8083602087013760009401602001938452509192915050565b6001600160a01b038981168252881660208201526040810187905260c06060820181905260009061342890830187896133be565b85608084015282810360a08401526134418185876133be565b9b9a5050505050505050505050565b60008282101561346257613462613323565b500390565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b600061010060018060a01b038c1683528a602084015289604084015260ff891660608401528760808401528660a08401528560c08401528060e08401526134f981840185876133be565b9c9b505050505050505050505050565b60018060a01b038816815286602082015260a06040820152600061353160a0830187896133be565b856060840152828103608084015261354a8185876133be565b9a9950505050505050505050565b60006001600160701b0380831681851680830382111561357a5761357a613323565b01949350505050565b600063ffffffff80831681851680830382111561357a5761357a613323565b6000602082840312156135b457600080fd5b5051919050565b6000602082840312156135cd57600080fd5b815163ffffffff81168114610a5d57600080fd5b60208082526017908201527f6d73672e73656e646572206973206e6f74206f776e6572000000000000000000604082015260600190565b600081600019048311821515161561363257613632613323565b500290565b60008261365457634e487b7160e01b600052601260045260246000fd5b500490565b60018060a01b03851681528360208201526060604082015260006136816060830184866133be565b9695505050505050565b6000825161369d818460208701612ded565b919091019291505056fea164736f6c634300080b000a

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

00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba0000000000000000000000005afedef13bd7b3e363db724420d773caa8b88763000000000000000000000000ea5edef1a7106d9e2024240299df3d00c7d94767000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa00000000000000000000000000000000000000000000000000000000000000176376786372764356584554482045617365205661756c74000000000000000000000000000000000000000000000000000000000000000000000000000000000f657a2d6376786372764356584554480000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): cvxcrvCVXETH Ease Vault
Arg [1] : _symbol (string): ez-cvxcrvCVXETH
Arg [2] : _uToken (address): 0x0bC857f97c0554d1d0D602b56F2EEcE682016fBA
Arg [3] : _governance (address): 0x5AFeDEF13Bd7B3e363db724420D773cAa8B88763
Arg [4] : _controller (address): 0xEA5edEF1A7106D9e2024240299DF3D00C7D94767
Arg [5] : _rewardPool (address): 0xb1Fb0BA0676A1fFA83882c7F4805408bA232C1fA

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000000bc857f97c0554d1d0d602b56f2eece682016fba
Arg [3] : 0000000000000000000000005afedef13bd7b3e363db724420d773caa8b88763
Arg [4] : 000000000000000000000000ea5edef1a7106d9e2024240299df3d00c7d94767
Arg [5] : 000000000000000000000000b1fb0ba0676a1ffa83882c7f4805408ba232c1fa
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000017
Arg [7] : 6376786372764356584554482045617365205661756c74000000000000000000
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [9] : 657a2d6376786372764356584554480000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
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  ]

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.