creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/velo-fed/OptiFedCCTP.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport \"../interfaces/IERC20.sol\";\nimport \"../interfaces/velo/IDola.sol\";\nimport \"../interfaces/velo/IL1ERC20Bridge.sol\";\nimport \"../interfaces/velo/ICurvePool.sol\";\n\ninterface ICCTP {\n      /**\n     * @notice Deposits and burns tokens from sender to be minted on destination domain.\n     * Emits a `DepositForBurn` event.\n     * @dev reverts if:\n     * - given burnToken is not supported\n     * - given destinationDomain has no TokenMessenger registered\n     * - transferFrom() reverts. For example, if sender's burnToken balance or approved allowance\n     * to this contract is less than `amount`.\n     * - burn() reverts. For example, if `amount` is 0.\n     * - MessageTransmitter returns false or reverts.\n     * @param amount amount of tokens to burn\n     * @param destinationDomain destination domain\n     * @param mintRecipient address of mint recipient on destination domain\n     * @param burnToken address of contract to burn deposited tokens, on local domain\n     * @return _nonce unique nonce reserved by message\n     */\n    function depositForBurn(\n        uint256 amount,\n        uint32 destinationDomain,\n        bytes32 mintRecipient,\n        address burnToken\n    ) external returns (uint64 _nonce);\n}\n\n\ncontract OptiFedCCTP {\n    address public chair;\n    address public gov;\n    address public pendingGov;\n    uint public dolaSupply;\n    uint public maxSlippageBpsDolaToUsdc;\n    uint public maxSlippageBpsUsdcToDola;\n\n    uint constant PRECISION = 10_000;\n    uint public constant DOLA_USDC_CONVERSION_MULTI= 1e12;\n\n    IDola public constant DOLA = IDola(0x865377367054516e17014CcdED1e7d814EDC9ce4);\n    IERC20 public constant USDC = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);\n    IL1ERC20Bridge public constant optiBridge = IL1ERC20Bridge(0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1);\n    address public constant DOLA_OPTI = 0x8aE125E8653821E851F12A49F7765db9a9ce7384;\n    address public constant USDC_OPTI = 0x7F5c764cBc14f9669B88837ca1490cCa17c31607;\n    ICurvePool public curvePool = ICurvePool(0xE57180685E3348589E9521aa53Af0BCD497E884d);\n    ICCTP public constant CCTP = ICCTP(0xBd3fa81B58Ba92a82136038B25aDec7066af3155);\n    uint32 public constant OPTIMISM_CCTP_DOMAIN = 2;\n    address public veloFarmer;\n\n    event Expansion(uint amount);\n    event Contraction(uint amount);\n\n    error OnlyGov();\n    error OnlyPendingGov();\n    error OnlyChair();\n    error CantBurnZeroDOLA();\n    error MaxSlippageTooHigh();\n    error DeltaAboveMax();\n    error SwapMoreDolaThanMinted();\n\n    constructor(\n            address gov_,\n            address chair_,\n            address veloFarmer_,\n            uint maxSlippageBpsDolaToUsdc_,\n            uint maxSlippageBpsUsdcToDola_)\n    {\n        gov = gov_;\n        chair = chair_;\n        veloFarmer = veloFarmer_;\n        maxSlippageBpsDolaToUsdc = maxSlippageBpsDolaToUsdc_;\n        maxSlippageBpsUsdcToDola = maxSlippageBpsUsdcToDola_;\n    }\n\n    /**\n    @notice Mints `dolaAmount` of DOLA, swaps `dolaToSwap` of DOLA to USDC, then transfers all to `veloFarmer` through optimism bridge\n    @param dolaAmount Amount of DOLA to mint\n    @param dolaToSwap Amount of DOLA to swap for USDC\n    @param useCCTP If true, will use CCTP to bridge USDC. If false, will use Optimism bridge\n    */\n    function expansionAndSwap(uint dolaAmount, uint dolaToSwap, bool useCCTP) external {\n        if (msg.sender != chair) revert OnlyChair();\n        if (dolaToSwap > dolaAmount) revert SwapMoreDolaThanMinted();\n        \n        dolaSupply += dolaAmount;\n        DOLA.mint(address(this), dolaAmount);\n\n        DOLA.approve(address(curvePool), dolaToSwap);\n        uint usdcAmount = curvePool.exchange_underlying(0, 2, dolaToSwap, dolaToSwap * (PRECISION - maxSlippageBpsDolaToUsdc) / PRECISION / DOLA_USDC_CONVERSION_MULTI);\n\n        uint dolaToBridge = dolaAmount - dolaToSwap;\n        DOLA.approve(address(optiBridge), dolaToBridge);\n        \n        optiBridge.depositERC20To(address(DOLA), DOLA_OPTI, veloFarmer, dolaToBridge, 200_000, \"\");\n\n        if(useCCTP){\n            USDC.approve(address(CCTP), usdcAmount);\n            CCTP.depositForBurn(usdcAmount, OPTIMISM_CCTP_DOMAIN, bytes32(uint256(uint160(veloFarmer))), address(USDC));\n        } else {\n            USDC.approve(address(optiBridge), usdcAmount);\n            optiBridge.depositERC20To(address(USDC), USDC_OPTI, veloFarmer, usdcAmount, 200_000, \"\");\n        }\n\n        emit Expansion(dolaAmount);\n    }\n\n    /**\n    @notice Mints & deposits `amountUnderlying` of `underlying` tokens into Optimism bridge to the `veloFarmer` contract\n    @param dolaAmount Amount of underlying token to mint & deposit into Velodrome farmer on Optimism\n    */\n    function expansion(uint dolaAmount) external {\n        if (msg.sender != chair) revert OnlyChair();\n        \n        dolaSupply += dolaAmount;\n        DOLA.mint(address(this), dolaAmount);\n\n        DOLA.approve(address(optiBridge), dolaAmount);\n        optiBridge.depositERC20To(address(DOLA), DOLA_OPTI, veloFarmer, dolaAmount, 200_000, \"\");\n\n        emit Expansion(dolaAmount);\n    }\n\n    /**\n    @notice Burns `dolaAmount` of DOLA held in this contract\n    @param dolaAmount Amount of DOLA to burn\n    */\n    function contraction(uint dolaAmount) public {\n        if (msg.sender != chair) revert OnlyChair();\n\n        _contraction(dolaAmount);\n    }\n\n    /**\n    @notice Attempts to contract (burn) all DOLA held by this contract\n    */\n    function contractAll() external {\n        if (msg.sender != chair) revert OnlyChair();\n\n        _contraction(DOLA.balanceOf(address(this)));\n    }\n\n    /**\n    @notice Attempts to contract (burn) `amount` of DOLA. Sends remainder to `gov` if `amount` > DOLA minted by this fed.\n    @param amount Amount of DOLA to contract.\n    */\n    function _contraction(uint amount) internal{\n        if (amount == 0) revert CantBurnZeroDOLA();\n        if(amount > dolaSupply){\n            DOLA.burn(dolaSupply);\n            DOLA.transfer(gov, amount - dolaSupply);\n            emit Contraction(dolaSupply);\n            dolaSupply = 0;\n        } else {\n            DOLA.burn(amount);\n            dolaSupply -= amount;\n            emit Contraction(amount);\n        }\n    }\n\n    /**\n    @notice Swap `usdcAmount` of USDC for DOLA through curve.\n    @dev Will revert if actual slippage > `maxSlippageBpsUsdcToDola`\n    @param usdcAmount Amount of USDC to be swapped to DOLA through curve.\n    */\n    function swapUSDCtoDOLA(uint usdcAmount) external {\n        if (msg.sender != chair) revert OnlyChair();\n        \n        USDC.approve(address(curvePool), usdcAmount);\n        curvePool.exchange_underlying(2, 0, usdcAmount, usdcAmount * (PRECISION - maxSlippageBpsUsdcToDola) / PRECISION * DOLA_USDC_CONVERSION_MULTI);\n    }\n\n    /**\n    @notice Swap `dolaAmount` of DOLA for USDC through curve.\n    @dev Will revert if actual slippage > `maxSlippageBpsDolaToUsdc`\n    @param dolaAmount Amount of DOLA to be swapped to USDC through curve.\n    */\n    function swapDOLAtoUSDC(uint dolaAmount) external {\n        if (msg.sender != chair) revert OnlyChair();\n        \n        DOLA.approve(address(curvePool), dolaAmount);\n        curvePool.exchange_underlying(0, 2, dolaAmount, dolaAmount * (PRECISION - maxSlippageBpsDolaToUsdc) / PRECISION / DOLA_USDC_CONVERSION_MULTI);\n    }\n\n    /**\n    @notice Method for current chair of the Opti FED to resign\n    */\n    function resign() external {\n        if (msg.sender != chair) revert OnlyChair();\n        chair = address(0);\n    }\n\n    /**\n    @notice Governance only function for setting acceptable slippage when swapping DOLA -> USDC\n    @param newMaxSlippageBps The new maximum allowed loss for DOLA -> USDC swaps. 1 = 0.01%\n    */\n    function setMaxSlippageDolaToUsdc(uint newMaxSlippageBps) external {\n        if (msg.sender != gov) revert OnlyGov();\n        if (newMaxSlippageBps > 10000) revert MaxSlippageTooHigh();\n        maxSlippageBpsDolaToUsdc = newMaxSlippageBps;\n    }\n\n    /**\n    @notice Governance only function for setting acceptable slippage when swapping USDC -> DOLA\n    @param newMaxSlippageBps The new maximum allowed loss for USDC -> DOLA swaps. 1 = 0.01%\n    */\n    function setMaxSlippageUsdcToDola(uint newMaxSlippageBps) external {\n        if (msg.sender != gov) revert OnlyGov();\n        if (newMaxSlippageBps > 10000) revert MaxSlippageTooHigh();\n        maxSlippageBpsUsdcToDola = newMaxSlippageBps;\n    }\n\n    /**\n    @notice Method for `gov` to change `pendingGov` address\n    @dev `pendingGov` will have to call `claimGov` to complete `gov` transfer\n    @param newPendingGov_ Address to be set as `pendingGov`\n    */\n    function setPendingGov(address newPendingGov_) external {\n        if (msg.sender != gov) revert OnlyGov();\n        pendingGov = newPendingGov_;\n    }\n\n    /**\n    @notice Method for `pendingGov` to claim `gov` role.\n    */\n    function claimGov() external {\n        if (msg.sender != pendingGov) revert OnlyPendingGov();\n        gov = pendingGov;\n        pendingGov = address(0);\n    }\n\n    /**\n    @notice Method for gov to change the chair\n    @param newChair_ Address to be set as chair\n    */\n    function changeChair(address newChair_) external {\n        if (msg.sender != gov) revert OnlyGov();\n        chair = newChair_;\n    }\n\n    /**\n    @notice Method for gov to change the L2 veloFarmer address\n    @dev veloFarmer is the L2 address that receives all bridged DOLA from expansion\n    @param newVeloFarmer_ L2 address to be set as veloFarmer\n    */\n     function changeVeloFarmer(address newVeloFarmer_) external {\n        if (msg.sender != gov) revert OnlyGov();\n        veloFarmer = newVeloFarmer_;\n    }\n\n    /**\n    @notice Method for gov to change the curve pool address\n    @param newCurvePool_ Address to be set as curvePool\n    */\n     function changeCurvePool(address newCurvePool_) external {\n        if (msg.sender != gov) revert OnlyGov();\n        curvePool = ICurvePool(newCurvePool_);\n    }\n}"
      },
      "src/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n\n     * @dev Returns the decimal points used by the token.\n     */\n    function decimals() external view returns (uint8);\n\n    /**\n     \n    * @dev Returns the amount of tokens owned by `account`.\n    */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n    \n    /**\n     * @dev Burns `amount` of token, shringking total supply\n     */\n    function burn(uint amount) external;\n\n    /**\n     * @dev Mints `amount` of token to address `to` increasing total supply\n     */\n    function mint(address to, uint amount) external;\n\n    //For testing\n    function addMinter(address minter_) external;\n}\n"
      },
      "src/interfaces/velo/IDola.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IDola {\n    function decimals() external view returns (uint8);\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    function mint(address recipient, uint256 amount) external;\n    function burn(uint256 amount) external;\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    function addMinter(address minter) external;\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "src/interfaces/velo/IL1ERC20Bridge.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >0.5.0 <0.9.0;\n\n/**\n * @title IL1ERC20Bridge\n */\ninterface IL1ERC20Bridge {\n    /**********\n     * Events *\n     **********/\n\n    event ERC20DepositInitiated(\n        address indexed _l1Token,\n        address indexed _l2Token,\n        address indexed _from,\n        address _to,\n        uint256 _amount,\n        bytes _data\n    );\n\n    event ERC20WithdrawalFinalized(\n        address indexed _l1Token,\n        address indexed _l2Token,\n        address indexed _from,\n        address _to,\n        uint256 _amount,\n        bytes _data\n    );\n\n    /********************\n     * Public Functions *\n     ********************/\n\n    /**\n     * @dev get the address of the corresponding L2 bridge contract.\n     * @return Address of the corresponding L2 bridge contract.\n     */\n    function l2TokenBridge() external returns (address);\n\n    /**\n     * @dev deposit an amount of the ERC20 to the caller's balance on L2.\n     * @param _l1Token Address of the L1 ERC20 we are depositing\n     * @param _l2Token Address of the L1 respective L2 ERC20\n     * @param _amount Amount of the ERC20 to deposit\n     * @param _l2Gas Gas limit required to complete the deposit on L2.\n     * @param _data Optional data to forward to L2. This data is provided\n     *        solely as a convenience for external contracts. Aside from enforcing a maximum\n     *        length, these contracts provide no guarantees about its content.\n     */\n    function depositERC20(\n        address _l1Token,\n        address _l2Token,\n        uint256 _amount,\n        uint32 _l2Gas,\n        bytes calldata _data\n    ) external;\n\n    /**\n     * @dev deposit an amount of ERC20 to a recipient's balance on L2.\n     * @param _l1Token Address of the L1 ERC20 we are depositing\n     * @param _l2Token Address of the L1 respective L2 ERC20\n     * @param _to L2 address to credit the withdrawal to.\n     * @param _amount Amount of the ERC20 to deposit.\n     * @param _l2Gas Gas limit required to complete the deposit on L2.\n     * @param _data Optional data to forward to L2. This data is provided\n     *        solely as a convenience for external contracts. Aside from enforcing a maximum\n     *        length, these contracts provide no guarantees about its content.\n     */\n    function depositERC20To(\n        address _l1Token,\n        address _l2Token,\n        address _to,\n        uint256 _amount,\n        uint32 _l2Gas,\n        bytes calldata _data\n    ) external;\n\n    /*************************\n     * Cross-chain Functions *\n     *************************/\n\n    /**\n     * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the\n     * L1 ERC20 token.\n     * This call will fail if the initialized withdrawal from L2 has not been finalized.\n     *\n     * @param _l1Token Address of L1 token to finalizeWithdrawal for.\n     * @param _l2Token Address of L2 token where withdrawal was initiated.\n     * @param _from L2 address initiating the transfer.\n     * @param _to L1 address to credit the withdrawal to.\n     * @param _amount Amount of the ERC20 to deposit.\n     * @param _data Data provided by the sender on L2. This data is provided\n     *   solely as a convenience for external contracts. Aside from enforcing a maximum\n     *   length, these contracts provide no guarantees about its content.\n     */\n    function finalizeERC20Withdrawal(\n        address _l1Token,\n        address _l2Token,\n        address _from,\n        address _to,\n        uint256 _amount,\n        bytes calldata _data\n    ) external;\n}"
      },
      "src/interfaces/velo/ICurvePool.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.11;\n\ninterface ICurvePool {\n\n\t// Deployment\n\tfunction __init__() external;\n\tfunction initialize(string memory _name, string memory _symbol, address _coin, uint _decimals, uint _A, uint _fee, address _admin) external;\n\n\t// ERC20 Standard\n\tfunction decimals() external view returns (uint);\n\tfunction transfer(address _to, uint _value) external returns (uint256);\n\tfunction transferFrom(address _from, address _to, uint _value) external returns (bool);\n\tfunction approve(address _spender, uint _value) external returns (bool);\n\tfunction balanceOf(address _owner) external view returns (uint256);\n\tfunction totalSupply() external view returns (uint256);\n\n\n\t// StableSwap Functionality\n\tfunction get_previous_balances() external view returns (uint[2] memory);\n\tfunction get_twap_balances(uint[2] memory _first_balances, uint[2] memory _last_balances, uint _time_elapsed) external view returns (uint[2] memory);\n\tfunction get_price_cumulative_last() external view returns (uint[2] memory);\n\tfunction admin_fee() external view returns (uint);\n\tfunction A() external view returns (uint);\n\tfunction A_precise() external view returns (uint);\n\tfunction get_virtual_price() external view returns (uint);\n\tfunction calc_token_amount(uint[2] memory _amounts, bool _is_deposit) external view returns (uint);\n\tfunction calc_token_amount(uint[2] memory _amounts, bool _is_deposit, bool _previous) external view returns (uint);\n\tfunction add_liquidity(uint[2] memory _amounts, uint _min_mint_amount) external returns (uint);\n\tfunction add_liquidity(uint[3] memory _amounts, uint _min_mint_amount) external;\n\tfunction add_liquidity(uint[2] memory _amounts, uint _min_mint_amount, address _receiver) external returns (uint);\n\tfunction get_dy(int128 i, int128 j, uint256 dx) external view returns (uint256);\n\tfunction get_dy(int128 i, int128 j, uint256 dx, uint256[2] memory _balances) external view returns (uint256);\n\tfunction get_dy_underlying(int128 i, int128 j, uint256 dx) external view returns (uint256);\n\tfunction get_dy_underlying(int128 i, int128 j, uint256 dx, uint256[2] memory _balances) external view returns (uint256);\n\tfunction exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256);\n\tfunction exchange(int128 i, int128 j, uint256 dx, uint256 min_dy, address _receiver) external returns (uint256);\n\tfunction exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256);\n\tfunction exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy, address _receiver) external returns (uint256);\n\tfunction remove_liquidity(uint256 _burn_amount, uint256[2] memory _min_amounts) external returns (uint256[2] memory);\n\tfunction remove_liquidity(uint256 _burn_amount, uint256[2] memory _min_amounts, address _receiver) external returns (uint256[2] memory);\n\tfunction remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount) external returns (uint256);\n\tfunction remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount, address _receiver) external returns (uint256);\n\tfunction calc_withdraw_one_coin(uint256 _burn_amount, int128 i) external view returns (uint256);\n\tfunction calc_withdraw_one_coin(uint256 _burn_amount, int128 i, bool _previous) external view returns (uint256);\n\tfunction remove_liquidity_one_coin(uint256 _burn_amount, int128 i, uint256 _min_received) external returns (uint256);\n\tfunction remove_liquidity_one_coin(uint256 _burn_amount, int128 i, uint256 _min_received, address _receiver) external returns (uint256);\n\tfunction ramp_A(uint256 _future_A, uint256 _future_time) external;\n\tfunction stop_ramp_A() external;\n\tfunction admin_balances(uint256 i) external view returns (uint256);\n\tfunction withdraw_admin_fees() external;\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "arbitrum/=lib/arbitrum/contracts/",
        "@arbitrum/=lib/arbitrum/node_modules/@arbitrum/",
        "@offchainlabs/=lib/arbitrum/node_modules/@offchainlabs/",
        "@openzeppelin/contracts-upgradeable/=lib/arbitrum/node_modules/@openzeppelin/contracts-upgradeable/",
        "@openzeppelin/contracts/=lib/openzeppelin/contracts/",
        "arbitrum-nitro/=lib/arbitrum-nitro/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "nitro-contracts/=lib/arbitrum/lib/nitro-contracts/src/",
        "openzeppelin/=lib/openzeppelin/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs"
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "london",
      "viaIR": false,
      "libraries": {}
    }
  }}