ETH Price: $2,679.77 (-0.79%)

Contract

0x857b87171C99C234AC7DCD6A96859e78B1D1A625
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Redeem208460132024-09-28 2:01:3524 hrs ago1727488895IN
0x857b8717...8B1D1A625
0 ETH0.003250088.26740231
Redeem208169262024-09-24 0:40:235 days ago1727138423IN
0x857b8717...8B1D1A625
0 ETH0.0093968623.78069212
Redeem207871822024-09-19 20:58:599 days ago1726779539IN
0x857b8717...8B1D1A625
0 ETH0.002914698.45963285
Redeem207810532024-09-19 0:27:3510 days ago1726705655IN
0x857b8717...8B1D1A625
0 ETH0.003320349.18159729
Redeem207803612024-09-18 22:08:1110 days ago1726697291IN
0x857b8717...8B1D1A625
0 ETH0.002805947.75945749
Redeem207803402024-09-18 22:03:5910 days ago1726697039IN
0x857b8717...8B1D1A625
0 ETH0.002985627.55644937
Redeem207795912024-09-18 19:32:5910 days ago1726687979IN
0x857b8717...8B1D1A625
0 ETH0.0058358216.93921241
Withdraw207795712024-09-18 19:28:5910 days ago1726687739IN
0x857b8717...8B1D1A625
0 ETH0.0056183916.08814112
Deposit207752212024-09-18 4:53:5910 days ago1726635239IN
0x857b8717...8B1D1A625
0 ETH0.001819855.17166913
Deposit207751162024-09-18 4:32:5910 days ago1726633979IN
0x857b8717...8B1D1A625
0 ETH0.00139564.6418597
Deposit207655352024-09-16 20:22:5912 days ago1726518179IN
0x857b8717...8B1D1A625
0 ETH0.001798835.98326803
Deposit207650772024-09-16 18:51:1112 days ago1726512671IN
0x857b8717...8B1D1A625
0 ETH0.001231484.09598104
Deposit207619192024-09-16 8:13:2312 days ago1726474403IN
0x857b8717...8B1D1A625
0 ETH0.002153337.21007192
Deposit207582432024-09-15 19:55:1113 days ago1726430111IN
0x857b8717...8B1D1A625
0 ETH0.000550241.82999592
Deposit207556492024-09-15 11:14:3513 days ago1726398875IN
0x857b8717...8B1D1A625
0 ETH0.000432051.43696362
Redeem207509562024-09-14 19:32:4714 days ago1726342367IN
0x857b8717...8B1D1A625
0 ETH0.001025622.83601326
Withdraw207498172024-09-14 15:43:3514 days ago1726328615IN
0x857b8717...8B1D1A625
0 ETH0.000957282.61301847
Deposit207430702024-09-13 17:05:3515 days ago1726247135IN
0x857b8717...8B1D1A625
0 ETH0.001189783.95696479
Deposit207418232024-09-13 12:53:5915 days ago1726232039IN
0x857b8717...8B1D1A625
0 ETH0.000741672.07917863
Deposit207415132024-09-13 11:51:3515 days ago1726228295IN
0x857b8717...8B1D1A625
0 ETH0.000629462.09337219
Deposit207411542024-09-13 10:39:3515 days ago1726223975IN
0x857b8717...8B1D1A625
0 ETH0.000625181.96727477
Redeem207391522024-09-13 3:57:3515 days ago1726199855IN
0x857b8717...8B1D1A625
0 ETH0.000429411.18740484
Deposit207376652024-09-12 22:59:2316 days ago1726181963IN
0x857b8717...8B1D1A625
0 ETH0.000612492.00510012
Redeem207364642024-09-12 18:57:1116 days ago1726167431IN
0x857b8717...8B1D1A625
0 ETH0.001952785.39977364
Deposit207347602024-09-12 13:14:3516 days ago1726146875IN
0x857b8717...8B1D1A625
0 ETH0.00088362.51093339
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:
sINV

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion
File 1 of 5 : sInv.sol
// SPDX-License-Identifier: MIT License
pragma solidity ^0.8.21;

import "lib/solmate/src/tokens/ERC4626.sol";

interface IInvEscrow {
    function balance() external view returns (uint);
    function claimDBR() external;
    function claimable() external view returns (uint);
}

interface IMarket {
    function deposit(uint256 amount) external;
    function withdraw(uint256 amount) external;
    function dbr() external returns (address);
    function escrows(address user) external returns (address);
}

interface IERC20 {
    function transfer(address, uint) external returns (bool);
    function transferFrom(address, address, uint) external returns (bool);
    function balanceOf(address) external view returns (uint);
}

/**
 * @title sINV
 * @dev Auto-compounding ERC4626 wrapper for asset FiRM deposits utilizing xy=k auctions.
 * WARNING: While this vault is safe to be used as collateral in lending markets, it should not be allowed as a borrowable asset.
 * Any protocol in which sudden, large and atomic increases in the value of an asset may be a security risk should not integrate this vault.
 */
contract sINV is ERC4626{

    struct RevenueData {
        uint96 periodRevenue;
        uint96 lastPeriodRevenue;
        uint64 lastBuyPeriod;
    }

    struct KData {
        uint192 targetK;
        uint64 lastKUpdate;
    }
    
    uint256 public constant MIN_ASSETS = 10**16; // 1 cent
    uint256 public constant MIN_SHARES = 10**18;
    uint256 public constant MAX_ASSETS = 10**32; // 100 trillion asset
    uint256 public constant period = 7 days;
    uint256 public depositLimit;
    IMarket public immutable invMarket;
    IInvEscrow public immutable invEscrow;
    ERC20 public immutable DBR;
    RevenueData public revenueData;
    KData public kData;
    address public gov;
    address public guardian;
    address public pendingGov;
    uint256 public minBuffer;
    uint256 public prevK;

    function periodRevenue() external view returns(uint256){return revenueData.periodRevenue;}
    function lastPeriodRevenue() external view returns(uint256){return revenueData.lastPeriodRevenue;}
    function lastBuyPeriod() external view returns(uint256){return revenueData.lastBuyPeriod;}
    function targetK() external view returns(uint256){return kData.targetK;}
    function lastKUpdate() external view returns(uint256){return kData.lastKUpdate;}

    error OnlyGov();
    error OnlyPendingGov();
    error OnlyGuardian();
    error KTooLow(uint k, uint limit);
    error BelowMinShares();
    error AboveDepositLimit();
    error DepositLimitMustIncrease();
    error InsufficientAssets();
    error Invariant();
    error UnauthorizedTokenWithdrawal();

    /**
     * @dev Constructor for sINV contract.
     * WARNING: MIN_SHARES will always be unwithdrawable from the vault. Deployer should deposit enough to mint MIN_SHARES to avoid causing user grief.
     * @param _inv Address of the asset token.
     * @param _invMarket Address of the asset FiRM market.
     * @param _gov Address of the governance.
     * @param _K Initial value for the K variable used in calculations.
     */
    constructor(
        address _inv,
        address _invMarket,
        address _gov,
        address _guardian,
        uint256 _depositLimit,
        uint256 _K
    ) ERC4626(ERC20(_inv), "Staked Inv", "sINV") {
        if(_K == 0) revert KTooLow(_K, 1);
        IMarket(_invMarket).deposit(0); //creates an escrow on behalf of the sINV contract
        invEscrow = IInvEscrow(IMarket(_invMarket).escrows(address(this)));
        invMarket = IMarket(_invMarket);
        DBR = ERC20(IMarket(_invMarket).dbr());
        gov = _gov;
        guardian = _guardian;
        kData.targetK = uint192(_K);
        depositLimit = _depositLimit;
        prevK = _K;
        asset.approve(address(invMarket), type(uint).max);
    }

    modifier onlyGov() {
        if(msg.sender != gov) revert OnlyGov();
        _;
    }

    modifier onlyPendingGov() {
        if(msg.sender != pendingGov) revert OnlyPendingGov();
        _;
    }

    modifier onlyGuardian() {
        if(msg.sender != guardian) revert OnlyGuardian();
        _;
    }

    /**
     * @dev Hook that is called after tokens are deposited into the contract.
     */    
    function afterDeposit(uint256, uint256) internal override {
        if(totalSupply < MIN_SHARES) revert BelowMinShares();
        if(totalAssets() > depositLimit) revert AboveDepositLimit();
        uint256 invBal = asset.balanceOf(address(this));
        if(invBal > minBuffer){
            invMarket.deposit(invBal - minBuffer);
        }
    }

    /**
     * @dev Hook that is called before tokens are withdrawn from the contract.
     * @param assets The amount of assets to withdraw.
     * @param shares The amount of shares to withdraw
     */
    function beforeWithdraw(uint256 assets, uint256 shares) internal override {
        uint256 _totalAssets = totalAssets();
        if(_totalAssets < assets + MIN_ASSETS) revert InsufficientAssets();
        if(totalSupply < shares + MIN_SHARES) revert BelowMinShares();
        uint256 invBal = asset.balanceOf(address(this));
        if(assets > invBal) {
            uint256 withdrawAmount = assets - invBal + minBuffer;
            if(_totalAssets < withdrawAmount){
                invMarket.withdraw(assets - invBal);
            } else {
                invMarket.withdraw(withdrawAmount);
            }
        }
    }

    /**
     * @dev Calculates the total assets controlled by the contract.
     * Period revenue is distributed linearly over the following week.
     * @return The total assets in the contract.
     */
    function totalAssets() public view override returns (uint) {
        uint256 periodsSinceLastBuy = block.timestamp / period - revenueData.lastBuyPeriod;
        uint256 _lastPeriodRevenue = revenueData.lastPeriodRevenue;
        uint256 _periodRevenue = revenueData.periodRevenue;
        uint256 invBal = invEscrow.balance() + asset.balanceOf(address(this));
        if(periodsSinceLastBuy > 1){
            return invBal < MAX_ASSETS ? invBal : MAX_ASSETS;
        } else if(periodsSinceLastBuy == 1) {
            _lastPeriodRevenue = _periodRevenue;
            _periodRevenue = 0;
        }
        uint256 remainingLastRevenue = _lastPeriodRevenue * (period - block.timestamp % period) / period;
        uint256 lockedRevenue = remainingLastRevenue + _periodRevenue;
        uint256 actualAssets;
        if(invBal > lockedRevenue){
            actualAssets = invBal - lockedRevenue;
        }
        return actualAssets < MAX_ASSETS ? actualAssets : MAX_ASSETS;
    }

    function updatePeriodRevenue(uint96 newRevenue) internal {
        uint256 currentPeriod = block.timestamp / period;
        if(currentPeriod > revenueData.lastBuyPeriod) {
            revenueData.lastPeriodRevenue = revenueData.periodRevenue;
            revenueData.periodRevenue = newRevenue;
            revenueData.lastBuyPeriod = uint64(currentPeriod);
        } else {
            revenueData.periodRevenue += newRevenue;
        }
    }

    /**
     * @dev Returns the current value of K, which is a weighted average between prevK and kData.targetK.
     * @return The current value of K.
     */
    function getK() public view returns (uint) {
        uint256 timeElapsed = block.timestamp - kData.lastKUpdate;
        if(timeElapsed > period) {
            return kData.targetK;
        }
        uint256 prevWeight = period - timeElapsed;
        return (prevK * prevWeight + kData.targetK * timeElapsed) / period;
    }

    /**
     * @dev Calculates the asset reserve based on the current DBR reserve.
     * @return The calculated asset reserve.
     */
    function getInvReserve() public view returns (uint) {
        return getK() / getDbrReserve();
    }

    /**
     * @dev Calculates the asset reserve for a given DBR reserve.
     * @param DBRReserve The DBR reserve value.
     * @return The calculated asset reserve.
     */
    function getInvReserve(uint256 DBRReserve) public view returns (uint) {
        return getK() / DBRReserve;
    }

    /**
     * @dev Returns the current DBR reserve as the sum of DBR balance and claimable DBR
     * @return The current DBR reserve.
     */
    function getDbrReserve() public view returns (uint) {
        return DBR.balanceOf(address(this)) + invEscrow.claimable();
    }

    /**
     * @dev Sets a new target K value.
     * @param _K The new target K value.
     */
    function setTargetK(uint256 _K) external onlyGov {
        if(_K < getDbrReserve()) revert KTooLow(_K, getDbrReserve());
        prevK = getK();
        kData.targetK = uint192(_K);
        kData.lastKUpdate = uint64(block.timestamp);
        emit SetTargetK(_K);
    }

    /**
     * @notice Set the min buffer
     * @dev Min buffer is the buffer of INV held by the sINV contract, which can be withdrawn much more cheaply than if they were staked
     * @param _minBuffer The new min buffer
     */
    function setMinBuffer(uint256 _minBuffer) external onlyGov {
        minBuffer = _minBuffer;
        emit SetMinBuffer(_minBuffer);
    }

    /**
     * @dev Allows users to buy DBR with asset.
     * WARNING: Never expose this directly to a UI as it's likely to cause a loss unless a transaction is executed immediately.
     * Instead use the sINVHelper function or custom smart contract code.
     * @param exactInvIn The exact amount of asset to spend.
     * @param exactDbrOut The exact amount of DBR to receive.
     * @param to The address that will receive the DBR.
     */
    function buyDBR(uint256 exactInvIn, uint256 exactDbrOut, address to) external {
        require(exactInvIn <= type(uint96).max, "EXCEED UINT96");
        uint256 DBRBalance = DBR.balanceOf(address(this));
        if(exactDbrOut > DBRBalance){
            invEscrow.claimDBR();
            DBRBalance = DBR.balanceOf(address(this));
        } else {
            DBRBalance += invEscrow.claimable(); 
        }
        uint256 k = getK();
        uint256 DBRReserve = DBRBalance - exactDbrOut;
        uint256 invReserve = k / DBRBalance + exactInvIn;
        if(invReserve * DBRReserve < k) revert Invariant();
        updatePeriodRevenue(uint96(exactInvIn));
        asset.transferFrom(msg.sender, address(this), exactInvIn);
        DBR.transfer(to, exactDbrOut);
        emit Buy(msg.sender, to, exactInvIn, exactDbrOut);
    }

    /**
     * @notice Sets a new depositLimit. Only callable by guardian.
     * @dev Deposit limit must always increase
     * @param _depositLimit The new deposit limit
     */
    function setDepositLimit(uint _depositLimit) external onlyGuardian {
        if(_depositLimit <= depositLimit) revert DepositLimitMustIncrease();
        depositLimit = _depositLimit;
    }

    /**
     * @notice Sets the guardian that can increase the deposit limit. Only callable by governance.
     * @param _guardian The new guardian.
     */
    function setGuardian(address _guardian) external onlyGov {
        guardian = _guardian;
    }

    /**
     * @dev Sets a new pending governance address.
     * @param _gov The address of the new pending governance.
     */
    function setPendingGov(address _gov) external onlyGov {
        pendingGov = _gov;
    }

    /**
     * @dev Allows the pending governance to accept its role.
     */
    function acceptGov() external onlyPendingGov {
        gov = pendingGov;
        pendingGov = address(0);
    }

    /**
     * @dev Allows governance to sweep any ERC20 token from the contract.
     * @dev Excludes the ability to sweep DBR tokens.
     * @param token The address of the ERC20 token to sweep.
     * @param amount The amount of tokens to sweep.
     * @param to The recipient address of the swept tokens.
     */
    function sweep(address token, uint256 amount, address to) public onlyGov {
        if(address(DBR) == token ||
            address(asset) == token)
            revert UnauthorizedTokenWithdrawal();
        IERC20(token).transfer(to, amount);
    }
    
    /**
     * @notice Allows anyone to reapprove inv spending for invMarket
     */
    function reapprove() external {
        asset.approve(address(invMarket), type(uint).max);
    }
    

    event Buy(address indexed caller, address indexed to, uint256 exactInvIn, uint256 exactDbrOut);
    event SetTargetK(uint256 newTargetK);
    event SetMinBuffer(uint256 newMinBuffer);
}

File 2 of 5 : ERC4626.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";

/// @notice Minimal ERC4626 tokenized Vault implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol)
abstract contract ERC4626 is ERC20 {
    using SafeTransferLib for ERC20;
    using FixedPointMathLib for uint256;

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);

    event Withdraw(
        address indexed caller,
        address indexed receiver,
        address indexed owner,
        uint256 assets,
        uint256 shares
    );

    /*//////////////////////////////////////////////////////////////
                               IMMUTABLES
    //////////////////////////////////////////////////////////////*/

    ERC20 public immutable asset;

    constructor(
        ERC20 _asset,
        string memory _name,
        string memory _symbol
    ) ERC20(_name, _symbol, _asset.decimals()) {
        asset = _asset;
    }

    /*//////////////////////////////////////////////////////////////
                        DEPOSIT/WITHDRAWAL LOGIC
    //////////////////////////////////////////////////////////////*/

    function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {
        // Check for rounding error since we round down in previewDeposit.
        require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) {
        assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual returns (uint256 shares) {
        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.

        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public virtual returns (uint256 assets) {
        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        // Check for rounding error since we round down in previewRedeem.
        require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    /*//////////////////////////////////////////////////////////////
                            ACCOUNTING LOGIC
    //////////////////////////////////////////////////////////////*/

    function totalAssets() public view virtual returns (uint256);

    function convertToShares(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());
    }

    function convertToAssets(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
    }

    function previewDeposit(uint256 assets) public view virtual returns (uint256) {
        return convertToShares(assets);
    }

    function previewMint(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
    }

    function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());
    }

    function previewRedeem(uint256 shares) public view virtual returns (uint256) {
        return convertToAssets(shares);
    }

    /*//////////////////////////////////////////////////////////////
                     DEPOSIT/WITHDRAWAL LIMIT LOGIC
    //////////////////////////////////////////////////////////////*/

    function maxDeposit(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxMint(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxWithdraw(address owner) public view virtual returns (uint256) {
        return convertToAssets(balanceOf[owner]);
    }

    function maxRedeem(address owner) public view virtual returns (uint256) {
        return balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                          INTERNAL HOOKS LOGIC
    //////////////////////////////////////////////////////////////*/

    function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}

    function afterDeposit(uint256 assets, uint256 shares) internal virtual {}
}

File 3 of 5 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 4 of 5 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

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

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant MAX_UINT256 = 2**256 - 1;

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // Divide x * y by the denominator.
            z := div(mul(x, y), denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // If x * y modulo the denominator is strictly greater than 0,
            // 1 is added to round up the division of x * y by the denominator.
            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            let y := x // We start y at x, which will help us make our initial estimate.

            z := 181 // The "correct" value is 1, but this saves a multiplication later.

            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.

            // We check y >= 2^(k + 8) but shift right by k bits
            // each branch to ensure that if x >= 256, then y >= 256.
            if iszero(lt(y, 0x10000000000000000000000000000000000)) {
                y := shr(128, y)
                z := shl(64, z)
            }
            if iszero(lt(y, 0x1000000000000000000)) {
                y := shr(64, y)
                z := shl(32, z)
            }
            if iszero(lt(y, 0x10000000000)) {
                y := shr(32, y)
                z := shl(16, z)
            }
            if iszero(lt(y, 0x1000000)) {
                y := shr(16, y)
                z := shl(8, z)
            }

            // Goal was to get z*z*y within a small factor of x. More iterations could
            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).
            // We ensured y >= 256 so that the relative difference between y and y+1 is small.
            // That's not possible if x < 256 but we can just verify those cases exhaustively.

            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.

            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.

            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.

            // There is no overflow risk here since y < 2^136 after the first branch above.
            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.

            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // If x+1 is a perfect square, the Babylonian method cycles between
            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.
            z := sub(z, lt(div(x, z), z))
        }
    }

    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Mod x by y. Note this will return
            // 0 instead of reverting if y is zero.
            z := mod(x, y)
        }
    }

    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Divide x by y. Note this will return
            // 0 instead of reverting if y is zero.
            r := div(x, y)
        }
    }

    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Add 1 to x * y if x % y > 0. Note this will
            // return 0 instead of reverting if y is zero.
            z := add(gt(mod(x, y), 0), div(x, y))
        }
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ds-test/=lib/solmate/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_inv","type":"address"},{"internalType":"address","name":"_invMarket","type":"address"},{"internalType":"address","name":"_gov","type":"address"},{"internalType":"address","name":"_guardian","type":"address"},{"internalType":"uint256","name":"_depositLimit","type":"uint256"},{"internalType":"uint256","name":"_K","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AboveDepositLimit","type":"error"},{"inputs":[],"name":"BelowMinShares","type":"error"},{"inputs":[],"name":"DepositLimitMustIncrease","type":"error"},{"inputs":[],"name":"InsufficientAssets","type":"error"},{"inputs":[],"name":"Invariant","type":"error"},{"inputs":[{"internalType":"uint256","name":"k","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"KTooLow","type":"error"},{"inputs":[],"name":"OnlyGov","type":"error"},{"inputs":[],"name":"OnlyGuardian","type":"error"},{"inputs":[],"name":"OnlyPendingGov","type":"error"},{"inputs":[],"name":"UnauthorizedTokenWithdrawal","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"exactInvIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exactDbrOut","type":"uint256"}],"name":"Buy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinBuffer","type":"uint256"}],"name":"SetMinBuffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTargetK","type":"uint256"}],"name":"SetTargetK","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":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DBR","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ASSETS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_ASSETS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_SHARES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","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":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"exactInvIn","type":"uint256"},{"internalType":"uint256","name":"exactDbrOut","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"buyDBR","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","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":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDbrReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"DBRReserve","type":"uint256"}],"name":"getInvReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInvReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"invEscrow","outputs":[{"internalType":"contract IInvEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"invMarket","outputs":[{"internalType":"contract IMarket","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kData","outputs":[{"internalType":"uint192","name":"targetK","type":"uint192"},{"internalType":"uint64","name":"lastKUpdate","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBuyPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastKUpdate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPeriodRevenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBuffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"period","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodRevenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"prevK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reapprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revenueData","outputs":[{"internalType":"uint96","name":"periodRevenue","type":"uint96"},{"internalType":"uint96","name":"lastPeriodRevenue","type":"uint96"},{"internalType":"uint64","name":"lastBuyPeriod","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositLimit","type":"uint256"}],"name":"setDepositLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_guardian","type":"address"}],"name":"setGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minBuffer","type":"uint256"}],"name":"setMinBuffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setPendingGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_K","type":"uint256"}],"name":"setTargetK","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]

61016060405234801562000011575f80fd5b506040516200320538038062003205833981016040819052620000349162000417565b856040518060400160405280600a81526020016929ba30b5b2b21024b73b60b11b8152506040518060400160405280600481526020016339a4a72b60e11b8152508181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000b4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620000da919062000482565b5f620000e784826200054b565b506001620000f683826200054b565b5060ff81166080524660a0526200010c62000361565b60c0525050506001600160a01b0390921660e05250505f81900362000152576040516308b6d51360e31b8152600481018290526001602482015260440160405180910390fd5b60405163b6b55f2560e01b81525f60048201526001600160a01b0386169063b6b55f25906024015f604051808303815f87803b15801562000191575f80fd5b505af1158015620001a4573d5f803e3d5ffd5b50506040516323b9185960e11b81523060048201526001600160a01b038816925063477230b291506024016020604051808303815f875af1158015620001ec573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000212919062000613565b6001600160a01b039081166101205285166101008190526040805163c7ed69cd60e01b8152905163c7ed69cd9160048082019260209290919082900301815f875af115801562000264573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200028a919062000613565b6001600160a01b0390811661014052600980546001600160a01b031990811687841617909155600a8054909116858316179055600880546001600160c01b0319166001600160c01b0384161790556006839055600d82905560e0516101005160405163095ea7b360e01b815290831660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af11580156200032e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200035491906200062f565b50505050505050620006ca565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f60405162000393919062000650565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80516001600160a01b038116811462000412575f80fd5b919050565b5f805f805f8060c087890312156200042d575f80fd5b6200043887620003fb565b95506200044860208801620003fb565b94506200045860408801620003fb565b93506200046860608801620003fb565b92506080870151915060a087015190509295509295509295565b5f6020828403121562000493575f80fd5b815160ff81168114620004a4575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c90821680620004d457607f821691505b602082108103620004f357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000546575f81815260208120601f850160051c81016020861015620005215750805b601f850160051c820191505b8181101562000542578281556001016200052d565b5050505b505050565b81516001600160401b03811115620005675762000567620004ab565b6200057f81620005788454620004bf565b84620004f9565b602080601f831160018114620005b5575f84156200059d5750858301515b5f19600386901b1c1916600185901b17855562000542565b5f85815260208120601f198616915b82811015620005e557888601518255948401946001909101908401620005c4565b50858210156200060357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f6020828403121562000624575f80fd5b620004a482620003fb565b5f6020828403121562000640575f80fd5b81518015158114620004a4575f80fd5b5f8083546200065f81620004bf565b600182811680156200067a57600181146200069057620006be565b60ff1984168752821515830287019450620006be565b875f526020805f205f5b85811015620006b55781548a8201529084019082016200069a565b50505082870194505b50929695505050505050565b60805160a05160c05160e051610100516101205161014051612a48620007bd5f395f8181610607015281816110b7015281816112e8015281816113e4015281816116090152611cf501525f81816108b4015281816109eb0152818161102401528181611365015261146001525f818161049c01528181611c22015281816121a60152818161241701526124ac01525f81816105580152818161098001528181610e8e0152818161119801528181611570015281816117c50152818161190c01528181611c5101528181611d3001528181612127015261236f01525f610e0701525f610dd201525f6105170152612a485ff3fe608060405234801561000f575f80fd5b506004361061039e575f3560e01c80637bc6729b116101ea578063c6e6f59211610114578063dd62ed3e116100a9578063ee39e7a011610079578063ee39e7a0146108df578063ef78d4fd146108e7578063ef8b30f7146108f1578063efdf0bb014610904575f80fd5b8063dd62ed3e1461087d578063e1e59849146108a7578063eba872a7146108af578063ecf70858146108d6575f80fd5b8063d505accf116100e4578063d505accf14610827578063d818f23a1461083a578063d905777e14610842578063dc2c256f1461086a575f80fd5b8063c6e6f592146107d6578063cd153866146107e9578063ce96cb7714610801578063d0926e2614610814575f80fd5b8063a08b06db1161018a578063b460af941161015a578063b460af941461079d578063ba087652146107b0578063bdc8144b146107c3578063c63d75b61461057a575f80fd5b8063a08b06db1461075b578063a9059cbb14610764578063b23adea614610777578063b3d7f6b91461078a575f80fd5b80638a0dac4a116101c55780638a0dac4a146106cb57806394bf804d146106de57806394f5c9dc146106f157806395d89b4114610753575f80fd5b80637bc6729b1461069c5780637ecebe00146106a457806387a64c01146106c3575f80fd5b8063260a220b116102cb5780634cdad5061161026b57806370a082311161023b57806370a082311461063c5780637153a20d1461065b57806376b1d08f1461066e578063781f56de14610683575f80fd5b80634cdad506146105a1578063563e1709146105b45780636d124715146106025780636e553f6514610629575f80fd5b80633644e515116102a65780633644e5151461054b57806338d52e0f14610553578063402d267d1461057a578063452a93201461058e575f80fd5b8063260a220b146104f35780632b8dbaa714610501578063313ce56714610512575f80fd5b806312d43a51116103415780631d2fa930116103115780631d2fa930146104975780631fcd3080146104be57806323b872dd146104cd57806325240810146104e0575f80fd5b806312d43a5114610439578063140c67b21461046457806318160ddd1461047d5780631cd1cf6414610486575f80fd5b8063084219e81161037c578063084219e8146103e5578063095ea7b3146103fa5780630a28a4771461041d57806311e5ff3f14610430575f80fd5b806301e1d114146103a257806306fdde03146103bd57806307a2d13a146103d2575b5f80fd5b6103aa610917565b6040519081526020015b60405180910390f35b6103c5610b4c565b6040516103b491906125ee565b6103aa6103e0366004612639565b610bd7565b6103f86103f3366004612639565b610c03565b005b61040d61040836600461266b565b610c6a565b60405190151581526020016103b4565b6103aa61042b366004612639565b610cd6565b6103aa600c5481565b60095461044c906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b600754600160c01b900467ffffffffffffffff166103aa565b6103aa60025481565b6008546001600160c01b03166103aa565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa670de0b6b3a764000081565b61040d6104db366004612693565b610cf5565b600b5461044c906001600160a01b031681565b6103aa662386f26fc1000081565b6007546001600160601b03166103aa565b6105397f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103b4565b6103aa610dcf565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa6105883660046126cc565b505f1990565b600a5461044c906001600160a01b031681565b6103aa6105af366004612639565b610e29565b6008546105da906001600160c01b03811690600160c01b900467ffffffffffffffff1682565b604080516001600160c01b03909316835267ffffffffffffffff9091166020830152016103b4565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa6106373660046126e5565b610e33565b6103aa61064a3660046126cc565b60036020525f908152604090205481565b6103f8610669366004612639565b610f10565b6103aa6d04ee2d6d415b85acef810000000081565b600854600160c01b900467ffffffffffffffff166103aa565b6103f8610fcf565b6103aa6106b23660046126cc565b60056020525f908152604090205481565b6103aa611021565b6103f86106d93660046126cc565b611132565b6103aa6106ec3660046126e5565b61117f565b600754610723906001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff16908201526060016103b4565b6103c561121a565b6103aa600d5481565b61040d61077236600461266b565b611227565b6103f861078536600461270f565b61128a565b6103aa610798366004612639565b6116c4565b6103aa6107ab366004612741565b6116e2565b6103aa6107be366004612741565b6117ec565b6103f86107d1366004612639565b611933565b6103aa6107e4366004612639565b611985565b600754600160601b90046001600160601b03166103aa565b6103aa61080f3660046126cc565b6119a4565b6103aa610822366004612639565b6119c5565b6103f8610835366004612771565b6119d9565b6103f8611c0b565b6103aa6108503660046126cc565b6001600160a01b03165f9081526003602052604090205490565b6103f86108783660046127de565b611cbe565b6103aa61088b36600461280e565b600460209081525f928352604080842090915290825290205481565b6103aa611dee565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa60065481565b6103aa611e09565b6103aa62093a8081565b6103aa6108ff366004612639565b611e9f565b6103f86109123660046126cc565b611ea9565b6007545f908190600160c01b900467ffffffffffffffff1661093c62093a804261285e565b6109469190612871565b6007546040516370a0823160e01b81523060048201529192506001600160601b03600160601b82048116929116905f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156109c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e99190612884565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b69ef8a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a699190612884565b610a73919061289b565b90506001841115610ab2576d04ee2d6d415b85acef81000000008110610aa7576d04ee2d6d415b85acef8100000000610aa9565b805b94505050505090565b83600103610ac0579091505f905b5f62093a80610acf81426128ae565b610adc9062093a80612871565b610ae690866128c1565b610af0919061285e565b90505f610afd848361289b565b90505f81841115610b1557610b128285612871565b90505b6d04ee2d6d415b85acef81000000008110610b3e576d04ee2d6d415b85acef8100000000610b40565b805b97505050505050505090565b5f8054610b58906128d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b84906128d8565b8015610bcf5780601f10610ba657610100808354040283529160200191610bcf565b820191905f5260205f20905b815481529060010190602001808311610bb257829003601f168201915b505050505081565b6002545f908015610bfa57610bf5610bed610917565b849083611ef6565b610bfc565b825b9392505050565b6009546001600160a01b03163314610c2e57604051639097750360e01b815260040160405180910390fd5b600c8190556040518181527fc4ac55c04bc11a90cd33d7e0088129e6985b44c5d85a9f0acdeae027bfeeb50b906020015b60405180910390a150565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cc49086815260200190565b60405180910390a35060015b92915050565b6002545f908015610bfa57610bf581610ced610917565b859190611f11565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610d4e57610d2a8382612871565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d75908490612871565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f805160206129f383398151915290610dbc9087815260200190565b60405180910390a3506001949350505050565b5f7f00000000000000000000000000000000000000000000000000000000000000004614610e0457610dff611f34565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b5f610cd082610bd7565b5f610e3d83611e9f565b9050805f03610e815760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b610eb66001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086611fcc565b610ec08282612064565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd083826120bb565b6009546001600160a01b03163314610f3b57604051639097750360e01b815260040160405180910390fd5b610f43611021565b811015610f755780610f53611021565b6040516308b6d51360e31b815260048101929092526024820152604401610e78565b610f7d611e09565b600d556001600160c01b038116600160c01b4267ffffffffffffffff1602176008556040518181527f1fcc9c54f3c93fdac0b3691c0d36d64d222420c5ca56c6f1f28b43ab09cb8b7b90602001610c5f565b600b546001600160a01b03163314610ffa576040516307b70d3960e11b815260040160405180910390fd5b600b8054600980546001600160a01b03199081166001600160a01b03841617909155169055565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561107e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a29190612884565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611104573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111289190612884565b610dff919061289b565b6009546001600160a01b0316331461115d57604051639097750360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611189836116c4565b90506111c06001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084611fcc565b6111ca8284612064565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd081846120bb565b60018054610b58906128d8565b335f90815260036020526040812080548391908390611247908490612871565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f805160206129f383398151915290610cc49086815260200190565b6001600160601b038311156112d15760405162461bcd60e51b815260206004820152600d60248201526c22ac21a2a2a2102aa4a72a1c9b60991b6044820152606401610e78565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611335573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113599190612884565b90508083111561145e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c93f304e6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156113bb575f80fd5b505af11580156113cd573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506370a082319150602401602060405180830381865afa158015611433573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114579190612884565b90506114eb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114de9190612884565b6114e8908261289b565b90505b5f6114f4611e09565b90505f6115018584612871565b90505f8661150f858561285e565b611519919061289b565b90508261152683836128c1565b101561154557604051633876c51d60e11b815260040160405180910390fd5b61154e87612232565b6040516323b872dd60e01b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303815f875af11580156115be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e29190612910565b5060405163a9059cbb60e01b81526001600160a01b038681166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af115801561164f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116739190612910565b5060408051888152602081018890526001600160a01b0387169133917f89f5adc174562e07c9c9b1cae7109bbecb21cf9d1b2847e550042b8653c54a0e91015b60405180910390a350505050505050565b6002545f908015610bfa57610bf56116da610917565b849083611f11565b5f6116ec84610cd6565b9050336001600160a01b03831614611759576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611757576117338282612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61176384826122e8565b61176d8282612512565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168486612571565b5f336001600160a01b03831614611858576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611856576118328582612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61186184610e29565b9050805f036118a05760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401610e78565b6118aa81856122e8565b6118b48285612512565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168483612571565b600a546001600160a01b0316331461195e57604051636570ecab60e11b815260040160405180910390fd5b60065481116119805760405163062b386160e21b815260040160405180910390fd5b600655565b6002545f908015610bfa57610bf58161199c610917565b859190611ef6565b6001600160a01b0381165f90815260036020526040812054610cd090610bd7565b5f816119cf611e09565b610cd0919061285e565b42841015611a295760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610e78565b5f6001611a34610dcf565b6001600160a01b038a81165f8181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b3c573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615801590611b725750876001600160a01b0316816001600160a01b0316145b611baf5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610e78565b6001600160a01b039081165f9081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016116b3565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f1960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611c97573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cbb9190612910565b50565b6009546001600160a01b03163314611ce957604051639097750360e01b815260040160405180910390fd5b826001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161480611d5a5750826001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316145b15611d7857604051631b16270360e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb906044016020604051808303815f875af1158015611dc4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611de89190612910565b50505050565b5f611df7611021565b611dff611e09565b610dff919061285e565b6008545f908190611e2b90600160c01b900467ffffffffffffffff1642612871565b905062093a80811115611e495750506008546001600160c01b031690565b5f611e578262093a80612871565b60085490915062093a8090611e769084906001600160c01b03166128c1565b82600d54611e8491906128c1565b611e8e919061289b565b611e98919061285e565b9250505090565b5f610cd082611985565b6009546001600160a01b03163314611ed457604051639097750360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f825f190484118302158202611f0a575f80fd5b5091020490565b5f825f190484118302158202611f25575f80fd5b50910281810615159190040190565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f604051611f64919061292f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af13d15601f3d1160015f51141617169150508061205d5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610e78565b5050505050565b8060025f828254612075919061289b565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f805160206129f383398151915291015b60405180910390a35050565b670de0b6b3a764000060025410156120e65760405163b6af011960e01b815260040160405180910390fd5b6006546120f1610917565b1115612110576040516301d8a97b60e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612174573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121989190612884565b9050600c5481111561222d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b6b55f25600c54836121e19190612871565b6040518263ffffffff1660e01b81526004016121ff91815260200190565b5f604051808303815f87803b158015612216575f80fd5b505af1158015612228573d5f803e3d5ffd5b505050505b505050565b5f61224062093a804261285e565b600754909150600160c01b900467ffffffffffffffff168111156122a3576007805467ffffffffffffffff8316600160c01b02600160601b6001600160601b03928316026bffffffffffffffffffffffff60601b16918516919091171790555050565b600780548391905f906122c09084906001600160601b03166129cb565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b5f6122f1610917565b9050612304662386f26fc100008461289b565b811015612324576040516396d8043360e01b815260040160405180910390fd5b612336670de0b6b3a76400008361289b565b60025410156123585760405163b6af011960e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156123bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123e09190612884565b905080841115611de857600c545f906123f98387612871565b612403919061289b565b905080831015612496576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632e1a7d4d6124468488612871565b6040518263ffffffff1660e01b815260040161246491815260200190565b5f604051808303815f87803b15801561247b575f80fd5b505af115801561248d573d5f803e3d5ffd5b5050505061205d565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b1580156124f5575f80fd5b505af1158015612507573d5f803e3d5ffd5b505050505050505050565b6001600160a01b0382165f9081526003602052604081208054839290612539908490612871565b90915550506002805482900390556040518181525f906001600160a01b038416905f805160206129f3833981519152906020016120af565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f511416171691505080611de85760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610e78565b5f6020808352835180828501525f5b81811015612619578581018301518582016040015282016125fd565b505f604082860101526040601f19601f8301168501019250505092915050565b5f60208284031215612649575f80fd5b5035919050565b80356001600160a01b0381168114612666575f80fd5b919050565b5f806040838503121561267c575f80fd5b61268583612650565b946020939093013593505050565b5f805f606084860312156126a5575f80fd5b6126ae84612650565b92506126bc60208501612650565b9150604084013590509250925092565b5f602082840312156126dc575f80fd5b610bfc82612650565b5f80604083850312156126f6575f80fd5b8235915061270660208401612650565b90509250929050565b5f805f60608486031215612721575f80fd5b833592506020840135915061273860408501612650565b90509250925092565b5f805f60608486031215612753575f80fd5b8335925061276360208501612650565b915061273860408501612650565b5f805f805f805f60e0888a031215612787575f80fd5b61279088612650565b965061279e60208901612650565b95506040880135945060608801359350608088013560ff811681146127c1575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f805f606084860312156127f0575f80fd5b6127f984612650565b92506020840135915061273860408501612650565b5f806040838503121561281f575f80fd5b61282883612650565b915061270660208401612650565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f8261286c5761286c612836565b500490565b81810381811115610cd057610cd061284a565b5f60208284031215612894575f80fd5b5051919050565b80820180821115610cd057610cd061284a565b5f826128bc576128bc612836565b500690565b8082028115828204841417610cd057610cd061284a565b600181811c908216806128ec57607f821691505b60208210810361290a57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612920575f80fd5b81518015158114610bfc575f80fd5b5f80835481600182811c91508083168061294a57607f831692505b6020808410820361296957634e487b7160e01b86526022600452602486fd5b81801561297d5760018114612992576129bd565b60ff19861689528415158502890196506129bd565b5f8a8152602090205f5b868110156129b55781548b82015290850190830161299c565b505084890196505b509498975050505050505050565b6001600160601b038181168382160190808211156129eb576129eb61284a565b509291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ac64fd4779813955d236993620cf2ef7c782e9b1323433d4bdc9d80584beb30d64736f6c6343000815003300000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b700000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000007dd08b930c64a15497342287480000000000

Deployed Bytecode

0x608060405234801561000f575f80fd5b506004361061039e575f3560e01c80637bc6729b116101ea578063c6e6f59211610114578063dd62ed3e116100a9578063ee39e7a011610079578063ee39e7a0146108df578063ef78d4fd146108e7578063ef8b30f7146108f1578063efdf0bb014610904575f80fd5b8063dd62ed3e1461087d578063e1e59849146108a7578063eba872a7146108af578063ecf70858146108d6575f80fd5b8063d505accf116100e4578063d505accf14610827578063d818f23a1461083a578063d905777e14610842578063dc2c256f1461086a575f80fd5b8063c6e6f592146107d6578063cd153866146107e9578063ce96cb7714610801578063d0926e2614610814575f80fd5b8063a08b06db1161018a578063b460af941161015a578063b460af941461079d578063ba087652146107b0578063bdc8144b146107c3578063c63d75b61461057a575f80fd5b8063a08b06db1461075b578063a9059cbb14610764578063b23adea614610777578063b3d7f6b91461078a575f80fd5b80638a0dac4a116101c55780638a0dac4a146106cb57806394bf804d146106de57806394f5c9dc146106f157806395d89b4114610753575f80fd5b80637bc6729b1461069c5780637ecebe00146106a457806387a64c01146106c3575f80fd5b8063260a220b116102cb5780634cdad5061161026b57806370a082311161023b57806370a082311461063c5780637153a20d1461065b57806376b1d08f1461066e578063781f56de14610683575f80fd5b80634cdad506146105a1578063563e1709146105b45780636d124715146106025780636e553f6514610629575f80fd5b80633644e515116102a65780633644e5151461054b57806338d52e0f14610553578063402d267d1461057a578063452a93201461058e575f80fd5b8063260a220b146104f35780632b8dbaa714610501578063313ce56714610512575f80fd5b806312d43a51116103415780631d2fa930116103115780631d2fa930146104975780631fcd3080146104be57806323b872dd146104cd57806325240810146104e0575f80fd5b806312d43a5114610439578063140c67b21461046457806318160ddd1461047d5780631cd1cf6414610486575f80fd5b8063084219e81161037c578063084219e8146103e5578063095ea7b3146103fa5780630a28a4771461041d57806311e5ff3f14610430575f80fd5b806301e1d114146103a257806306fdde03146103bd57806307a2d13a146103d2575b5f80fd5b6103aa610917565b6040519081526020015b60405180910390f35b6103c5610b4c565b6040516103b491906125ee565b6103aa6103e0366004612639565b610bd7565b6103f86103f3366004612639565b610c03565b005b61040d61040836600461266b565b610c6a565b60405190151581526020016103b4565b6103aa61042b366004612639565b610cd6565b6103aa600c5481565b60095461044c906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b600754600160c01b900467ffffffffffffffff166103aa565b6103aa60025481565b6008546001600160c01b03166103aa565b61044c7f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b81565b6103aa670de0b6b3a764000081565b61040d6104db366004612693565b610cf5565b600b5461044c906001600160a01b031681565b6103aa662386f26fc1000081565b6007546001600160601b03166103aa565b6105397f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016103b4565b6103aa610dcf565b61044c7f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6881565b6103aa6105883660046126cc565b505f1990565b600a5461044c906001600160a01b031681565b6103aa6105af366004612639565b610e29565b6008546105da906001600160c01b03811690600160c01b900467ffffffffffffffff1682565b604080516001600160c01b03909316835267ffffffffffffffff9091166020830152016103b4565b61044c7f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d71081565b6103aa6106373660046126e5565b610e33565b6103aa61064a3660046126cc565b60036020525f908152604090205481565b6103f8610669366004612639565b610f10565b6103aa6d04ee2d6d415b85acef810000000081565b600854600160c01b900467ffffffffffffffff166103aa565b6103f8610fcf565b6103aa6106b23660046126cc565b60056020525f908152604090205481565b6103aa611021565b6103f86106d93660046126cc565b611132565b6103aa6106ec3660046126e5565b61117f565b600754610723906001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff16908201526060016103b4565b6103c561121a565b6103aa600d5481565b61040d61077236600461266b565b611227565b6103f861078536600461270f565b61128a565b6103aa610798366004612639565b6116c4565b6103aa6107ab366004612741565b6116e2565b6103aa6107be366004612741565b6117ec565b6103f86107d1366004612639565b611933565b6103aa6107e4366004612639565b611985565b600754600160601b90046001600160601b03166103aa565b6103aa61080f3660046126cc565b6119a4565b6103aa610822366004612639565b6119c5565b6103f8610835366004612771565b6119d9565b6103f8611c0b565b6103aa6108503660046126cc565b6001600160a01b03165f9081526003602052604090205490565b6103f86108783660046127de565b611cbe565b6103aa61088b36600461280e565b600460209081525f928352604080842090915290825290205481565b6103aa611dee565b61044c7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac81565b6103aa60065481565b6103aa611e09565b6103aa62093a8081565b6103aa6108ff366004612639565b611e9f565b6103f86109123660046126cc565b611ea9565b6007545f908190600160c01b900467ffffffffffffffff1661093c62093a804261285e565b6109469190612871565b6007546040516370a0823160e01b81523060048201529192506001600160601b03600160601b82048116929116905f906001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816906370a0823190602401602060405180830381865afa1580156109c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e99190612884565b7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663b69ef8a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a699190612884565b610a73919061289b565b90506001841115610ab2576d04ee2d6d415b85acef81000000008110610aa7576d04ee2d6d415b85acef8100000000610aa9565b805b94505050505090565b83600103610ac0579091505f905b5f62093a80610acf81426128ae565b610adc9062093a80612871565b610ae690866128c1565b610af0919061285e565b90505f610afd848361289b565b90505f81841115610b1557610b128285612871565b90505b6d04ee2d6d415b85acef81000000008110610b3e576d04ee2d6d415b85acef8100000000610b40565b805b97505050505050505090565b5f8054610b58906128d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b84906128d8565b8015610bcf5780601f10610ba657610100808354040283529160200191610bcf565b820191905f5260205f20905b815481529060010190602001808311610bb257829003601f168201915b505050505081565b6002545f908015610bfa57610bf5610bed610917565b849083611ef6565b610bfc565b825b9392505050565b6009546001600160a01b03163314610c2e57604051639097750360e01b815260040160405180910390fd5b600c8190556040518181527fc4ac55c04bc11a90cd33d7e0088129e6985b44c5d85a9f0acdeae027bfeeb50b906020015b60405180910390a150565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cc49086815260200190565b60405180910390a35060015b92915050565b6002545f908015610bfa57610bf581610ced610917565b859190611f11565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610d4e57610d2a8382612871565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d75908490612871565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f805160206129f383398151915290610dbc9087815260200190565b60405180910390a3506001949350505050565b5f7f00000000000000000000000000000000000000000000000000000000000000014614610e0457610dff611f34565b905090565b507f6045e987479f1722ac43c9eec26a51ee86e35c3e20d2a5a941cb80ef10e0bfde90565b5f610cd082610bd7565b5f610e3d83611e9f565b9050805f03610e815760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b610eb66001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816333086611fcc565b610ec08282612064565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd083826120bb565b6009546001600160a01b03163314610f3b57604051639097750360e01b815260040160405180910390fd5b610f43611021565b811015610f755780610f53611021565b6040516308b6d51360e31b815260048101929092526024820152604401610e78565b610f7d611e09565b600d556001600160c01b038116600160c01b4267ffffffffffffffff1602176008556040518181527f1fcc9c54f3c93fdac0b3691c0d36d64d222420c5ca56c6f1f28b43ab09cb8b7b90602001610c5f565b600b546001600160a01b03163314610ffa576040516307b70d3960e11b815260040160405180910390fd5b600b8054600980546001600160a01b03199081166001600160a01b03841617909155169055565b5f7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561107e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a29190612884565b6040516370a0823160e01b81523060048201527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b0316906370a0823190602401602060405180830381865afa158015611104573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111289190612884565b610dff919061289b565b6009546001600160a01b0316331461115d57604051639097750360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611189836116c4565b90506111c06001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816333084611fcc565b6111ca8284612064565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd081846120bb565b60018054610b58906128d8565b335f90815260036020526040812080548391908390611247908490612871565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f805160206129f383398151915290610cc49086815260200190565b6001600160601b038311156112d15760405162461bcd60e51b815260206004820152600d60248201526c22ac21a2a2a2102aa4a72a1c9b60991b6044820152606401610e78565b6040516370a0823160e01b81523060048201525f907f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b0316906370a0823190602401602060405180830381865afa158015611335573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113599190612884565b90508083111561145e577f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663c93f304e6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156113bb575f80fd5b505af11580156113cd573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b031692506370a082319150602401602060405180830381865afa158015611433573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114579190612884565b90506114eb565b7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114de9190612884565b6114e8908261289b565b90505b5f6114f4611e09565b90505f6115018584612871565b90505f8661150f858561285e565b611519919061289b565b90508261152683836128c1565b101561154557604051633876c51d60e11b815260040160405180910390fd5b61154e87612232565b6040516323b872dd60e01b8152336004820152306024820152604481018890527f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906323b872dd906064016020604051808303815f875af11580156115be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e29190612910565b5060405163a9059cbb60e01b81526001600160a01b038681166004830152602482018890527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d710169063a9059cbb906044016020604051808303815f875af115801561164f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116739190612910565b5060408051888152602081018890526001600160a01b0387169133917f89f5adc174562e07c9c9b1cae7109bbecb21cf9d1b2847e550042b8653c54a0e91015b60405180910390a350505050505050565b6002545f908015610bfa57610bf56116da610917565b849083611f11565b5f6116ec84610cd6565b9050336001600160a01b03831614611759576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611757576117338282612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61176384826122e8565b61176d8282612512565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68168486612571565b5f336001600160a01b03831614611858576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611856576118328582612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61186184610e29565b9050805f036118a05760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401610e78565b6118aa81856122e8565b6118b48285612512565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68168483612571565b600a546001600160a01b0316331461195e57604051636570ecab60e11b815260040160405180910390fd5b60065481116119805760405163062b386160e21b815260040160405180910390fd5b600655565b6002545f908015610bfa57610bf58161199c610917565b859190611ef6565b6001600160a01b0381165f90815260036020526040812054610cd090610bd7565b5f816119cf611e09565b610cd0919061285e565b42841015611a295760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610e78565b5f6001611a34610dcf565b6001600160a01b038a81165f8181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b3c573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615801590611b725750876001600160a01b0316816001600160a01b0316145b611baf5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610e78565b6001600160a01b039081165f9081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016116b3565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b811660048301525f1960248301527f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68169063095ea7b3906044016020604051808303815f875af1158015611c97573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cbb9190612910565b50565b6009546001600160a01b03163314611ce957604051639097750360e01b815260040160405180910390fd5b826001600160a01b03167f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b03161480611d5a5750826001600160a01b03167f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316145b15611d7857604051631b16270360e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb906044016020604051808303815f875af1158015611dc4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611de89190612910565b50505050565b5f611df7611021565b611dff611e09565b610dff919061285e565b6008545f908190611e2b90600160c01b900467ffffffffffffffff1642612871565b905062093a80811115611e495750506008546001600160c01b031690565b5f611e578262093a80612871565b60085490915062093a8090611e769084906001600160c01b03166128c1565b82600d54611e8491906128c1565b611e8e919061289b565b611e98919061285e565b9250505090565b5f610cd082611985565b6009546001600160a01b03163314611ed457604051639097750360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f825f190484118302158202611f0a575f80fd5b5091020490565b5f825f190484118302158202611f25575f80fd5b50910281810615159190040190565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f604051611f64919061292f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af13d15601f3d1160015f51141617169150508061205d5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610e78565b5050505050565b8060025f828254612075919061289b565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f805160206129f383398151915291015b60405180910390a35050565b670de0b6b3a764000060025410156120e65760405163b6af011960e01b815260040160405180910390fd5b6006546120f1610917565b1115612110576040516301d8a97b60e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906370a0823190602401602060405180830381865afa158015612174573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121989190612884565b9050600c5481111561222d577f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b6001600160a01b031663b6b55f25600c54836121e19190612871565b6040518263ffffffff1660e01b81526004016121ff91815260200190565b5f604051808303815f87803b158015612216575f80fd5b505af1158015612228573d5f803e3d5ffd5b505050505b505050565b5f61224062093a804261285e565b600754909150600160c01b900467ffffffffffffffff168111156122a3576007805467ffffffffffffffff8316600160c01b02600160601b6001600160601b03928316026bffffffffffffffffffffffff60601b16918516919091171790555050565b600780548391905f906122c09084906001600160601b03166129cb565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b5f6122f1610917565b9050612304662386f26fc100008461289b565b811015612324576040516396d8043360e01b815260040160405180910390fd5b612336670de0b6b3a76400008361289b565b60025410156123585760405163b6af011960e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906370a0823190602401602060405180830381865afa1580156123bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123e09190612884565b905080841115611de857600c545f906123f98387612871565b612403919061289b565b905080831015612496576001600160a01b037f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b16632e1a7d4d6124468488612871565b6040518263ffffffff1660e01b815260040161246491815260200190565b5f604051808303815f87803b15801561247b575f80fd5b505af115801561248d573d5f803e3d5ffd5b5050505061205d565b604051632e1a7d4d60e01b8152600481018290527f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b6001600160a01b031690632e1a7d4d906024015f604051808303815f87803b1580156124f5575f80fd5b505af1158015612507573d5f803e3d5ffd5b505050505050505050565b6001600160a01b0382165f9081526003602052604081208054839290612539908490612871565b90915550506002805482900390556040518181525f906001600160a01b038416905f805160206129f3833981519152906020016120af565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f511416171691505080611de85760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610e78565b5f6020808352835180828501525f5b81811015612619578581018301518582016040015282016125fd565b505f604082860101526040601f19601f8301168501019250505092915050565b5f60208284031215612649575f80fd5b5035919050565b80356001600160a01b0381168114612666575f80fd5b919050565b5f806040838503121561267c575f80fd5b61268583612650565b946020939093013593505050565b5f805f606084860312156126a5575f80fd5b6126ae84612650565b92506126bc60208501612650565b9150604084013590509250925092565b5f602082840312156126dc575f80fd5b610bfc82612650565b5f80604083850312156126f6575f80fd5b8235915061270660208401612650565b90509250929050565b5f805f60608486031215612721575f80fd5b833592506020840135915061273860408501612650565b90509250925092565b5f805f60608486031215612753575f80fd5b8335925061276360208501612650565b915061273860408501612650565b5f805f805f805f60e0888a031215612787575f80fd5b61279088612650565b965061279e60208901612650565b95506040880135945060608801359350608088013560ff811681146127c1575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f805f606084860312156127f0575f80fd5b6127f984612650565b92506020840135915061273860408501612650565b5f806040838503121561281f575f80fd5b61282883612650565b915061270660208401612650565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f8261286c5761286c612836565b500490565b81810381811115610cd057610cd061284a565b5f60208284031215612894575f80fd5b5051919050565b80820180821115610cd057610cd061284a565b5f826128bc576128bc612836565b500690565b8082028115828204841417610cd057610cd061284a565b600181811c908216806128ec57607f821691505b60208210810361290a57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612920575f80fd5b81518015158114610bfc575f80fd5b5f80835481600182811c91508083168061294a57607f831692505b6020808410820361296957634e487b7160e01b86526022600452602486fd5b81801561297d5760018114612992576129bd565b60ff19861689528415158502890196506129bd565b5f8a8152602090205f5b868110156129b55781548b82015290850190830161299c565b505084890196505b509498975050505050505050565b6001600160601b038181168382160190808211156129eb576129eb61284a565b509291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ac64fd4779813955d236993620cf2ef7c782e9b1323433d4bdc9d80584beb30d64736f6c63430008150033

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

00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b700000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000007dd08b930c64a15497342287480000000000

-----Decoded View---------------
Arg [0] : _inv (address): 0x41D5D79431A913C4aE7d69a668ecdfE5fF9DFB68
Arg [1] : _invMarket (address): 0xb516247596Ca36bf32876199FBdCaD6B3322330B
Arg [2] : _gov (address): 0x926dF14a23BE491164dCF93f4c468A50ef659D5B
Arg [3] : _guardian (address): 0x4b6c63E6a94ef26E2dF60b89372db2d8e211F1B7
Arg [4] : _depositLimit (uint256): 10000000000000000000000
Arg [5] : _K (uint256): 10960000000000000000000000000000000000000000

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68
Arg [1] : 000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b
Arg [2] : 000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b
Arg [3] : 0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b7
Arg [4] : 00000000000000000000000000000000000000000000021e19e0c9bab2400000
Arg [5] : 00000000000000000000000000007dd08b930c64a15497342287480000000000


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.