creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IAuthorizerAdaptor.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"../solidity-utils/helpers/IAuthentication.sol\";\nimport \"../vault/IVault.sol\";\n\ninterface IAuthorizerAdaptor is IAuthentication {\n    /**\n     * @notice Returns the Balancer Vault\n     */\n    function getVault() external view returns (IVault);\n\n    /**\n     * @notice Returns the Authorizer\n     */\n    function getAuthorizer() external view returns (IAuthorizer);\n\n    /**\n     * @notice Performs an arbitrary function call on a target contract, provided the caller is authorized to do so.\n     * @param target - Address of the contract to be called\n     * @param data - Calldata to be sent to the target contract\n     * @return The bytes encoded return value from the performed function call\n     */\n    function performAction(address target, bytes calldata data) external payable returns (bytes memory);\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/vault/IAuthorizer.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\ninterface IAuthorizer {\n    /**\n     * @dev Returns true if `account` can perform the action described by `actionId` in the contract `where`.\n     */\n    function canPerform(\n        bytes32 actionId,\n        address account,\n        address where\n    ) external view returns (bool);\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma experimental ABIEncoderV2;\n\nimport \"../solidity-utils/openzeppelin/IERC20.sol\";\nimport \"../solidity-utils/helpers/IAuthentication.sol\";\nimport \"../solidity-utils/helpers/ISignaturesValidator.sol\";\nimport \"../solidity-utils/helpers/ITemporarilyPausable.sol\";\nimport \"../solidity-utils/misc/IWETH.sol\";\n\nimport \"./IAsset.sol\";\nimport \"./IAuthorizer.sol\";\nimport \"./IFlashLoanRecipient.sol\";\nimport \"./IProtocolFeesCollector.sol\";\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Full external interface for the Vault core contract - no external or public methods exist in the contract that\n * don't override one of these declarations.\n */\ninterface IVault is ISignaturesValidator, ITemporarilyPausable, IAuthentication {\n    // Generalities about the Vault:\n    //\n    // - Whenever documentation refers to 'tokens', it strictly refers to ERC20-compliant token contracts. Tokens are\n    // transferred out of the Vault by calling the `IERC20.transfer` function, and transferred in by calling\n    // `IERC20.transferFrom`. In these cases, the sender must have previously allowed the Vault to use their tokens by\n    // calling `IERC20.approve`. The only deviation from the ERC20 standard that is supported is functions not returning\n    // a boolean value: in these scenarios, a non-reverting call is assumed to be successful.\n    //\n    // - All non-view functions in the Vault are non-reentrant: calling them while another one is mid-execution (e.g.\n    // while execution control is transferred to a token contract during a swap) will result in a revert. View\n    // functions can be called in a re-reentrant way, but doing so might cause them to return inconsistent results.\n    // Contracts calling view functions in the Vault must make sure the Vault has not already been entered.\n    //\n    // - View functions revert if referring to either unregistered Pools, or unregistered tokens for registered Pools.\n\n    // Authorizer\n    //\n    // Some system actions are permissioned, like setting and collecting protocol fees. This permissioning system exists\n    // outside of the Vault in the Authorizer contract: the Vault simply calls the Authorizer to check if the caller\n    // can perform a given action.\n\n    /**\n     * @dev Returns the Vault's Authorizer.\n     */\n    function getAuthorizer() external view returns (IAuthorizer);\n\n    /**\n     * @dev Sets a new Authorizer for the Vault. The caller must be allowed by the current Authorizer to do this.\n     *\n     * Emits an `AuthorizerChanged` event.\n     */\n    function setAuthorizer(IAuthorizer newAuthorizer) external;\n\n    /**\n     * @dev Emitted when a new authorizer is set by `setAuthorizer`.\n     */\n    event AuthorizerChanged(IAuthorizer indexed newAuthorizer);\n\n    // Relayers\n    //\n    // Additionally, it is possible for an account to perform certain actions on behalf of another one, using their\n    // Vault ERC20 allowance and Internal Balance. These accounts are said to be 'relayers' for these Vault functions,\n    // and are expected to be smart contracts with sound authentication mechanisms. For an account to be able to wield\n    // this power, two things must occur:\n    //  - The Authorizer must grant the account the permission to be a relayer for the relevant Vault function. This\n    //    means that Balancer governance must approve each individual contract to act as a relayer for the intended\n    //    functions.\n    //  - Each user must approve the relayer to act on their behalf.\n    // This double protection means users cannot be tricked into approving malicious relayers (because they will not\n    // have been allowed by the Authorizer via governance), nor can malicious relayers approved by a compromised\n    // Authorizer or governance drain user funds, since they would also need to be approved by each individual user.\n\n    /**\n     * @dev Returns true if `user` has approved `relayer` to act as a relayer for them.\n     */\n    function hasApprovedRelayer(address user, address relayer) external view returns (bool);\n\n    /**\n     * @dev Allows `relayer` to act as a relayer for `sender` if `approved` is true, and disallows it otherwise.\n     *\n     * Emits a `RelayerApprovalChanged` event.\n     */\n    function setRelayerApproval(\n        address sender,\n        address relayer,\n        bool approved\n    ) external;\n\n    /**\n     * @dev Emitted every time a relayer is approved or disapproved by `setRelayerApproval`.\n     */\n    event RelayerApprovalChanged(address indexed relayer, address indexed sender, bool approved);\n\n    // Internal Balance\n    //\n    // Users can deposit tokens into the Vault, where they are allocated to their Internal Balance, and later\n    // transferred or withdrawn. It can also be used as a source of tokens when joining Pools, as a destination\n    // when exiting them, and as either when performing swaps. This usage of Internal Balance results in greatly reduced\n    // gas costs when compared to relying on plain ERC20 transfers, leading to large savings for frequent users.\n    //\n    // Internal Balance management features batching, which means a single contract call can be used to perform multiple\n    // operations of different kinds, with different senders and recipients, at once.\n\n    /**\n     * @dev Returns `user`'s Internal Balance for a set of tokens.\n     */\n    function getInternalBalance(address user, IERC20[] memory tokens) external view returns (uint256[] memory);\n\n    /**\n     * @dev Performs a set of user balance operations, which involve Internal Balance (deposit, withdraw or transfer)\n     * and plain ERC20 transfers using the Vault's allowance. This last feature is particularly useful for relayers, as\n     * it lets integrators reuse a user's Vault allowance.\n     *\n     * For each operation, if the caller is not `sender`, it must be an authorized relayer for them.\n     */\n    function manageUserBalance(UserBalanceOp[] memory ops) external payable;\n\n    /**\n     * @dev Data for `manageUserBalance` operations, which include the possibility for ETH to be sent and received\n     without manual WETH wrapping or unwrapping.\n     */\n    struct UserBalanceOp {\n        UserBalanceOpKind kind;\n        IAsset asset;\n        uint256 amount;\n        address sender;\n        address payable recipient;\n    }\n\n    // There are four possible operations in `manageUserBalance`:\n    //\n    // - DEPOSIT_INTERNAL\n    // Increases the Internal Balance of the `recipient` account by transferring tokens from the corresponding\n    // `sender`. The sender must have allowed the Vault to use their tokens via `IERC20.approve()`.\n    //\n    // ETH can be used by passing the ETH sentinel value as the asset and forwarding ETH in the call: it will be wrapped\n    // and deposited as WETH. Any ETH amount remaining will be sent back to the caller (not the sender, which is\n    // relevant for relayers).\n    //\n    // Emits an `InternalBalanceChanged` event.\n    //\n    //\n    // - WITHDRAW_INTERNAL\n    // Decreases the Internal Balance of the `sender` account by transferring tokens to the `recipient`.\n    //\n    // ETH can be used by passing the ETH sentinel value as the asset. This will deduct WETH instead, unwrap it and send\n    // it to the recipient as ETH.\n    //\n    // Emits an `InternalBalanceChanged` event.\n    //\n    //\n    // - TRANSFER_INTERNAL\n    // Transfers tokens from the Internal Balance of the `sender` account to the Internal Balance of `recipient`.\n    //\n    // Reverts if the ETH sentinel value is passed.\n    //\n    // Emits an `InternalBalanceChanged` event.\n    //\n    //\n    // - TRANSFER_EXTERNAL\n    // Transfers tokens from `sender` to `recipient`, using the Vault's ERC20 allowance. This is typically used by\n    // relayers, as it lets them reuse a user's Vault allowance.\n    //\n    // Reverts if the ETH sentinel value is passed.\n    //\n    // Emits an `ExternalBalanceTransfer` event.\n\n    enum UserBalanceOpKind { DEPOSIT_INTERNAL, WITHDRAW_INTERNAL, TRANSFER_INTERNAL, TRANSFER_EXTERNAL }\n\n    /**\n     * @dev Emitted when a user's Internal Balance changes, either from calls to `manageUserBalance`, or through\n     * interacting with Pools using Internal Balance.\n     *\n     * Because Internal Balance works exclusively with ERC20 tokens, ETH deposits and withdrawals will use the WETH\n     * address.\n     */\n    event InternalBalanceChanged(address indexed user, IERC20 indexed token, int256 delta);\n\n    /**\n     * @dev Emitted when a user's Vault ERC20 allowance is used by the Vault to transfer tokens to an external account.\n     */\n    event ExternalBalanceTransfer(IERC20 indexed token, address indexed sender, address recipient, uint256 amount);\n\n    // Pools\n    //\n    // There are three specialization settings for Pools, which allow for cheaper swaps at the cost of reduced\n    // functionality:\n    //\n    //  - General: no specialization, suited for all Pools. IGeneralPool is used for swap request callbacks, passing the\n    // balance of all tokens in the Pool. These Pools have the largest swap costs (because of the extra storage reads),\n    // which increase with the number of registered tokens.\n    //\n    //  - Minimal Swap Info: IMinimalSwapInfoPool is used instead of IGeneralPool, which saves gas by only passing the\n    // balance of the two tokens involved in the swap. This is suitable for some pricing algorithms, like the weighted\n    // constant product one popularized by Balancer V1. Swap costs are smaller compared to general Pools, and are\n    // independent of the number of registered tokens.\n    //\n    //  - Two Token: only allows two tokens to be registered. This achieves the lowest possible swap gas cost. Like\n    // minimal swap info Pools, these are called via IMinimalSwapInfoPool.\n\n    enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN }\n\n    /**\n     * @dev Registers the caller account as a Pool with a given specialization setting. Returns the Pool's ID, which\n     * is used in all Pool-related functions. Pools cannot be deregistered, nor can the Pool's specialization be\n     * changed.\n     *\n     * The caller is expected to be a smart contract that implements either `IGeneralPool` or `IMinimalSwapInfoPool`,\n     * depending on the chosen specialization setting. This contract is known as the Pool's contract.\n     *\n     * Note that the same contract may register itself as multiple Pools with unique Pool IDs, or in other words,\n     * multiple Pools may share the same contract.\n     *\n     * Emits a `PoolRegistered` event.\n     */\n    function registerPool(PoolSpecialization specialization) external returns (bytes32);\n\n    /**\n     * @dev Emitted when a Pool is registered by calling `registerPool`.\n     */\n    event PoolRegistered(bytes32 indexed poolId, address indexed poolAddress, PoolSpecialization specialization);\n\n    /**\n     * @dev Returns a Pool's contract address and specialization setting.\n     */\n    function getPool(bytes32 poolId) external view returns (address, PoolSpecialization);\n\n    /**\n     * @dev Registers `tokens` for the `poolId` Pool. Must be called by the Pool's contract.\n     *\n     * Pools can only interact with tokens they have registered. Users join a Pool by transferring registered tokens,\n     * exit by receiving registered tokens, and can only swap registered tokens.\n     *\n     * Each token can only be registered once. For Pools with the Two Token specialization, `tokens` must have a length\n     * of two, that is, both tokens must be registered in the same `registerTokens` call, and they must be sorted in\n     * ascending order.\n     *\n     * The `tokens` and `assetManagers` arrays must have the same length, and each entry in these indicates the Asset\n     * Manager for the corresponding token. Asset Managers can manage a Pool's tokens via `managePoolBalance`,\n     * depositing and withdrawing them directly, and can even set their balance to arbitrary amounts. They are therefore\n     * expected to be highly secured smart contracts with sound design principles, and the decision to register an\n     * Asset Manager should not be made lightly.\n     *\n     * Pools can choose not to assign an Asset Manager to a given token by passing in the zero address. Once an Asset\n     * Manager is set, it cannot be changed except by deregistering the associated token and registering again with a\n     * different Asset Manager.\n     *\n     * Emits a `TokensRegistered` event.\n     */\n    function registerTokens(\n        bytes32 poolId,\n        IERC20[] memory tokens,\n        address[] memory assetManagers\n    ) external;\n\n    /**\n     * @dev Emitted when a Pool registers tokens by calling `registerTokens`.\n     */\n    event TokensRegistered(bytes32 indexed poolId, IERC20[] tokens, address[] assetManagers);\n\n    /**\n     * @dev Deregisters `tokens` for the `poolId` Pool. Must be called by the Pool's contract.\n     *\n     * Only registered tokens (via `registerTokens`) can be deregistered. Additionally, they must have zero total\n     * balance. For Pools with the Two Token specialization, `tokens` must have a length of two, that is, both tokens\n     * must be deregistered in the same `deregisterTokens` call.\n     *\n     * A deregistered token can be re-registered later on, possibly with a different Asset Manager.\n     *\n     * Emits a `TokensDeregistered` event.\n     */\n    function deregisterTokens(bytes32 poolId, IERC20[] memory tokens) external;\n\n    /**\n     * @dev Emitted when a Pool deregisters tokens by calling `deregisterTokens`.\n     */\n    event TokensDeregistered(bytes32 indexed poolId, IERC20[] tokens);\n\n    /**\n     * @dev Returns detailed information for a Pool's registered token.\n     *\n     * `cash` is the number of tokens the Vault currently holds for the Pool. `managed` is the number of tokens\n     * withdrawn and held outside the Vault by the Pool's token Asset Manager. The Pool's total balance for `token`\n     * equals the sum of `cash` and `managed`.\n     *\n     * Internally, `cash` and `managed` are stored using 112 bits. No action can ever cause a Pool's token `cash`,\n     * `managed` or `total` balance to be greater than 2^112 - 1.\n     *\n     * `lastChangeBlock` is the number of the block in which `token`'s total balance was last modified (via either a\n     * join, exit, swap, or Asset Manager update). This value is useful to avoid so-called 'sandwich attacks', for\n     * example when developing price oracles. A change of zero (e.g. caused by a swap with amount zero) is considered a\n     * change for this purpose, and will update `lastChangeBlock`.\n     *\n     * `assetManager` is the Pool's token Asset Manager.\n     */\n    function getPoolTokenInfo(bytes32 poolId, IERC20 token)\n        external\n        view\n        returns (\n            uint256 cash,\n            uint256 managed,\n            uint256 lastChangeBlock,\n            address assetManager\n        );\n\n    /**\n     * @dev Returns a Pool's registered tokens, the total balance for each, and the latest block when *any* of\n     * the tokens' `balances` changed.\n     *\n     * The order of the `tokens` array is the same order that will be used in `joinPool`, `exitPool`, as well as in all\n     * Pool hooks (where applicable). Calls to `registerTokens` and `deregisterTokens` may change this order.\n     *\n     * If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same\n     * order as passed to `registerTokens`.\n     *\n     * Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are\n     * the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use `getPoolTokenInfo`\n     * instead.\n     */\n    function getPoolTokens(bytes32 poolId)\n        external\n        view\n        returns (\n            IERC20[] memory tokens,\n            uint256[] memory balances,\n            uint256 lastChangeBlock\n        );\n\n    /**\n     * @dev Called by users to join a Pool, which transfers tokens from `sender` into the Pool's balance. This will\n     * trigger custom Pool behavior, which will typically grant something in return to `recipient` - often tokenized\n     * Pool shares.\n     *\n     * If the caller is not `sender`, it must be an authorized relayer for them.\n     *\n     * The `assets` and `maxAmountsIn` arrays must have the same length, and each entry indicates the maximum amount\n     * to send for each asset. The amounts to send are decided by the Pool and not the Vault: it just enforces\n     * these maximums.\n     *\n     * If joining a Pool that holds WETH, it is possible to send ETH directly: the Vault will do the wrapping. To enable\n     * this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead of the\n     * WETH address. Note that it is not possible to combine ETH and WETH in the same join. Any excess ETH will be sent\n     * back to the caller (not the sender, which is important for relayers).\n     *\n     * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when\n     * interacting with Pools that register and deregister tokens frequently. If sending ETH however, the array must be\n     * sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the final\n     * `assets` array might not be sorted. Pools with no registered tokens cannot be joined.\n     *\n     * If `fromInternalBalance` is true, the caller's Internal Balance will be preferred: ERC20 transfers will only\n     * be made for the difference between the requested amount and Internal Balance (if any). Note that ETH cannot be\n     * withdrawn from Internal Balance: attempting to do so will trigger a revert.\n     *\n     * This causes the Vault to call the `IBasePool.onJoinPool` hook on the Pool's contract, where Pools implement\n     * their own custom logic. This typically requires additional information from the user (such as the expected number\n     * of Pool shares). This can be encoded in the `userData` argument, which is ignored by the Vault and passed\n     * directly to the Pool's contract, as is `recipient`.\n     *\n     * Emits a `PoolBalanceChanged` event.\n     */\n    function joinPool(\n        bytes32 poolId,\n        address sender,\n        address recipient,\n        JoinPoolRequest memory request\n    ) external payable;\n\n    struct JoinPoolRequest {\n        IAsset[] assets;\n        uint256[] maxAmountsIn;\n        bytes userData;\n        bool fromInternalBalance;\n    }\n\n    /**\n     * @dev Called by users to exit a Pool, which transfers tokens from the Pool's balance to `recipient`. This will\n     * trigger custom Pool behavior, which will typically ask for something in return from `sender` - often tokenized\n     * Pool shares. The amount of tokens that can be withdrawn is limited by the Pool's `cash` balance (see\n     * `getPoolTokenInfo`).\n     *\n     * If the caller is not `sender`, it must be an authorized relayer for them.\n     *\n     * The `tokens` and `minAmountsOut` arrays must have the same length, and each entry in these indicates the minimum\n     * token amount to receive for each token contract. The amounts to send are decided by the Pool and not the Vault:\n     * it just enforces these minimums.\n     *\n     * If exiting a Pool that holds WETH, it is possible to receive ETH directly: the Vault will do the unwrapping. To\n     * enable this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead\n     * of the WETH address. Note that it is not possible to combine ETH and WETH in the same exit.\n     *\n     * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when\n     * interacting with Pools that register and deregister tokens frequently. If receiving ETH however, the array must\n     * be sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the\n     * final `assets` array might not be sorted. Pools with no registered tokens cannot be exited.\n     *\n     * If `toInternalBalance` is true, the tokens will be deposited to `recipient`'s Internal Balance. Otherwise,\n     * an ERC20 transfer will be performed. Note that ETH cannot be deposited to Internal Balance: attempting to\n     * do so will trigger a revert.\n     *\n     * `minAmountsOut` is the minimum amount of tokens the user expects to get out of the Pool, for each token in the\n     * `tokens` array. This array must match the Pool's registered tokens.\n     *\n     * This causes the Vault to call the `IBasePool.onExitPool` hook on the Pool's contract, where Pools implement\n     * their own custom logic. This typically requires additional information from the user (such as the expected number\n     * of Pool shares to return). This can be encoded in the `userData` argument, which is ignored by the Vault and\n     * passed directly to the Pool's contract.\n     *\n     * Emits a `PoolBalanceChanged` event.\n     */\n    function exitPool(\n        bytes32 poolId,\n        address sender,\n        address payable recipient,\n        ExitPoolRequest memory request\n    ) external;\n\n    struct ExitPoolRequest {\n        IAsset[] assets;\n        uint256[] minAmountsOut;\n        bytes userData;\n        bool toInternalBalance;\n    }\n\n    /**\n     * @dev Emitted when a user joins or exits a Pool by calling `joinPool` or `exitPool`, respectively.\n     */\n    event PoolBalanceChanged(\n        bytes32 indexed poolId,\n        address indexed liquidityProvider,\n        IERC20[] tokens,\n        int256[] deltas,\n        uint256[] protocolFeeAmounts\n    );\n\n    enum PoolBalanceChangeKind { JOIN, EXIT }\n\n    // Swaps\n    //\n    // Users can swap tokens with Pools by calling the `swap` and `batchSwap` functions. To do this,\n    // they need not trust Pool contracts in any way: all security checks are made by the Vault. They must however be\n    // aware of the Pools' pricing algorithms in order to estimate the prices Pools will quote.\n    //\n    // The `swap` function executes a single swap, while `batchSwap` can perform multiple swaps in sequence.\n    // In each individual swap, tokens of one kind are sent from the sender to the Pool (this is the 'token in'),\n    // and tokens of another kind are sent from the Pool to the recipient in exchange (this is the 'token out').\n    // More complex swaps, such as one token in to multiple tokens out can be achieved by batching together\n    // individual swaps.\n    //\n    // There are two swap kinds:\n    //  - 'given in' swaps, where the amount of tokens in (sent to the Pool) is known, and the Pool determines (via the\n    // `onSwap` hook) the amount of tokens out (to send to the recipient).\n    //  - 'given out' swaps, where the amount of tokens out (received from the Pool) is known, and the Pool determines\n    // (via the `onSwap` hook) the amount of tokens in (to receive from the sender).\n    //\n    // Additionally, it is possible to chain swaps using a placeholder input amount, which the Vault replaces with\n    // the calculated output of the previous swap. If the previous swap was 'given in', this will be the calculated\n    // tokenOut amount. If the previous swap was 'given out', it will use the calculated tokenIn amount. These extended\n    // swaps are known as 'multihop' swaps, since they 'hop' through a number of intermediate tokens before arriving at\n    // the final intended token.\n    //\n    // In all cases, tokens are only transferred in and out of the Vault (or withdrawn from and deposited into Internal\n    // Balance) after all individual swaps have been completed, and the net token balance change computed. This makes\n    // certain swap patterns, such as multihops, or swaps that interact with the same token pair in multiple Pools, cost\n    // much less gas than they would otherwise.\n    //\n    // It also means that under certain conditions it is possible to perform arbitrage by swapping with multiple\n    // Pools in a way that results in net token movement out of the Vault (profit), with no tokens being sent in (only\n    // updating the Pool's internal accounting).\n    //\n    // To protect users from front-running or the market changing rapidly, they supply a list of 'limits' for each token\n    // involved in the swap, where either the maximum number of tokens to send (by passing a positive value) or the\n    // minimum amount of tokens to receive (by passing a negative value) is specified.\n    //\n    // Additionally, a 'deadline' timestamp can also be provided, forcing the swap to fail if it occurs after\n    // this point in time (e.g. if the transaction failed to be included in a block promptly).\n    //\n    // If interacting with Pools that hold WETH, it is possible to both send and receive ETH directly: the Vault will do\n    // the wrapping and unwrapping. To enable this mechanism, the IAsset sentinel value (the zero address) must be\n    // passed in the `assets` array instead of the WETH address. Note that it is possible to combine ETH and WETH in the\n    // same swap. Any excess ETH will be sent back to the caller (not the sender, which is relevant for relayers).\n    //\n    // Finally, Internal Balance can be used when either sending or receiving tokens.\n\n    enum SwapKind { GIVEN_IN, GIVEN_OUT }\n\n    /**\n     * @dev Performs a swap with a single Pool.\n     *\n     * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens\n     * taken from the Pool, which must be greater than or equal to `limit`.\n     *\n     * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens\n     * sent to the Pool, which must be less than or equal to `limit`.\n     *\n     * Internal Balance usage and the recipient are determined by the `funds` struct.\n     *\n     * Emits a `Swap` event.\n     */\n    function swap(\n        SingleSwap memory singleSwap,\n        FundManagement memory funds,\n        uint256 limit,\n        uint256 deadline\n    ) external payable returns (uint256);\n\n    /**\n     * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on\n     * the `kind` value.\n     *\n     * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address).\n     * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault.\n     *\n     * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be\n     * used to extend swap behavior.\n     */\n    struct SingleSwap {\n        bytes32 poolId;\n        SwapKind kind;\n        IAsset assetIn;\n        IAsset assetOut;\n        uint256 amount;\n        bytes userData;\n    }\n\n    /**\n     * @dev Performs a series of swaps with one or multiple Pools. In each individual swap, the caller determines either\n     * the amount of tokens sent to or received from the Pool, depending on the `kind` value.\n     *\n     * Returns an array with the net Vault asset balance deltas. Positive amounts represent tokens (or ETH) sent to the\n     * Vault, and negative amounts represent tokens (or ETH) sent by the Vault. Each delta corresponds to the asset at\n     * the same index in the `assets` array.\n     *\n     * Swaps are executed sequentially, in the order specified by the `swaps` array. Each array element describes a\n     * Pool, the token to be sent to this Pool, the token to receive from it, and an amount that is either `amountIn` or\n     * `amountOut` depending on the swap kind.\n     *\n     * Multihop swaps can be executed by passing an `amount` value of zero for a swap. This will cause the amount in/out\n     * of the previous swap to be used as the amount in for the current one. In a 'given in' swap, 'tokenIn' must equal\n     * the previous swap's `tokenOut`. For a 'given out' swap, `tokenOut` must equal the previous swap's `tokenIn`.\n     *\n     * The `assets` array contains the addresses of all assets involved in the swaps. These are either token addresses,\n     * or the IAsset sentinel value for ETH (the zero address). Each entry in the `swaps` array specifies tokens in and\n     * out by referencing an index in `assets`. Note that Pools never interact with ETH directly: it will be wrapped to\n     * or unwrapped from WETH by the Vault.\n     *\n     * Internal Balance usage, sender, and recipient are determined by the `funds` struct. The `limits` array specifies\n     * the minimum or maximum amount of each token the vault is allowed to transfer.\n     *\n     * `batchSwap` can be used to make a single swap, like `swap` does, but doing so requires more gas than the\n     * equivalent `swap` call.\n     *\n     * Emits `Swap` events.\n     */\n    function batchSwap(\n        SwapKind kind,\n        BatchSwapStep[] memory swaps,\n        IAsset[] memory assets,\n        FundManagement memory funds,\n        int256[] memory limits,\n        uint256 deadline\n    ) external payable returns (int256[] memory);\n\n    /**\n     * @dev Data for each individual swap executed by `batchSwap`. The asset in and out fields are indexes into the\n     * `assets` array passed to that function, and ETH assets are converted to WETH.\n     *\n     * If `amount` is zero, the multihop mechanism is used to determine the actual amount based on the amount in/out\n     * from the previous swap, depending on the swap kind.\n     *\n     * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be\n     * used to extend swap behavior.\n     */\n    struct BatchSwapStep {\n        bytes32 poolId;\n        uint256 assetInIndex;\n        uint256 assetOutIndex;\n        uint256 amount;\n        bytes userData;\n    }\n\n    /**\n     * @dev Emitted for each individual swap performed by `swap` or `batchSwap`.\n     */\n    event Swap(\n        bytes32 indexed poolId,\n        IERC20 indexed tokenIn,\n        IERC20 indexed tokenOut,\n        uint256 amountIn,\n        uint256 amountOut\n    );\n\n    /**\n     * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the\n     * `recipient` account.\n     *\n     * If the caller is not `sender`, it must be an authorized relayer for them.\n     *\n     * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20\n     * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender`\n     * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of\n     * `joinPool`.\n     *\n     * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of\n     * transferred. This matches the behavior of `exitPool`.\n     *\n     * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a\n     * revert.\n     */\n    struct FundManagement {\n        address sender;\n        bool fromInternalBalance;\n        address payable recipient;\n        bool toInternalBalance;\n    }\n\n    /**\n     * @dev Simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be\n     * simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result.\n     *\n     * Each element in the array corresponds to the asset at the same index, and indicates the number of tokens (or ETH)\n     * the Vault would take from the sender (if positive) or send to the recipient (if negative). The arguments it\n     * receives are the same that an equivalent `batchSwap` call would receive.\n     *\n     * Unlike `batchSwap`, this function performs no checks on the sender or recipient field in the `funds` struct.\n     * This makes it suitable to be called by off-chain applications via eth_call without needing to hold tokens,\n     * approve them for the Vault, or even know a user's address.\n     *\n     * Note that this function is not 'view' (due to implementation details): the client code must explicitly execute\n     * eth_call instead of eth_sendTransaction.\n     */\n    function queryBatchSwap(\n        SwapKind kind,\n        BatchSwapStep[] memory swaps,\n        IAsset[] memory assets,\n        FundManagement memory funds\n    ) external returns (int256[] memory assetDeltas);\n\n    // Flash Loans\n\n    /**\n     * @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it,\n     * and then reverting unless the tokens plus a proportional protocol fee have been returned.\n     *\n     * The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount\n     * for each token contract. `tokens` must be sorted in ascending order.\n     *\n     * The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the\n     * `receiveFlashLoan` call.\n     *\n     * Emits `FlashLoan` events.\n     */\n    function flashLoan(\n        IFlashLoanRecipient recipient,\n        IERC20[] memory tokens,\n        uint256[] memory amounts,\n        bytes memory userData\n    ) external;\n\n    /**\n     * @dev Emitted for each individual flash loan performed by `flashLoan`.\n     */\n    event FlashLoan(IFlashLoanRecipient indexed recipient, IERC20 indexed token, uint256 amount, uint256 feeAmount);\n\n    // Asset Management\n    //\n    // Each token registered for a Pool can be assigned an Asset Manager, which is able to freely withdraw the Pool's\n    // tokens from the Vault, deposit them, or assign arbitrary values to its `managed` balance (see\n    // `getPoolTokenInfo`). This makes them extremely powerful and dangerous. Even if an Asset Manager only directly\n    // controls one of the tokens in a Pool, a malicious manager could set that token's balance to manipulate the\n    // prices of the other tokens, and then drain the Pool with swaps. The risk of using Asset Managers is therefore\n    // not constrained to the tokens they are managing, but extends to the entire Pool's holdings.\n    //\n    // However, a properly designed Asset Manager smart contract can be safely used for the Pool's benefit,\n    // for example by lending unused tokens out for interest, or using them to participate in voting protocols.\n    //\n    // This concept is unrelated to the IAsset interface.\n\n    /**\n     * @dev Performs a set of Pool balance operations, which may be either withdrawals, deposits or updates.\n     *\n     * Pool Balance management features batching, which means a single contract call can be used to perform multiple\n     * operations of different kinds, with different Pools and tokens, at once.\n     *\n     * For each operation, the caller must be registered as the Asset Manager for `token` in `poolId`.\n     */\n    function managePoolBalance(PoolBalanceOp[] memory ops) external;\n\n    struct PoolBalanceOp {\n        PoolBalanceOpKind kind;\n        bytes32 poolId;\n        IERC20 token;\n        uint256 amount;\n    }\n\n    /**\n     * Withdrawals decrease the Pool's cash, but increase its managed balance, leaving the total balance unchanged.\n     *\n     * Deposits increase the Pool's cash, but decrease its managed balance, leaving the total balance unchanged.\n     *\n     * Updates don't affect the Pool's cash balance, but because the managed balance changes, it does alter the total.\n     * The external amount can be either increased or decreased by this call (i.e., reporting a gain or a loss).\n     */\n    enum PoolBalanceOpKind { WITHDRAW, DEPOSIT, UPDATE }\n\n    /**\n     * @dev Emitted when a Pool's token Asset Manager alters its balance via `managePoolBalance`.\n     */\n    event PoolBalanceManaged(\n        bytes32 indexed poolId,\n        address indexed assetManager,\n        IERC20 indexed token,\n        int256 cashDelta,\n        int256 managedDelta\n    );\n\n    // Protocol Fees\n    //\n    // Some operations cause the Vault to collect tokens in the form of protocol fees, which can then be withdrawn by\n    // permissioned accounts.\n    //\n    // There are two kinds of protocol fees:\n    //\n    //  - flash loan fees: charged on all flash loans, as a percentage of the amounts lent.\n    //\n    //  - swap fees: a percentage of the fees charged by Pools when performing swaps. For a number of reasons, including\n    // swap gas costs and interface simplicity, protocol swap fees are not charged on each individual swap. Rather,\n    // Pools are expected to keep track of how much they have charged in swap fees, and pay any outstanding debts to the\n    // Vault when they are joined or exited. This prevents users from joining a Pool with unpaid debt, as well as\n    // exiting a Pool in debt without first paying their share.\n\n    /**\n     * @dev Returns the current protocol fee module.\n     */\n    function getProtocolFeesCollector() external view returns (IProtocolFeesCollector);\n\n    /**\n     * @dev Safety mechanism to pause most Vault operations in the event of an emergency - typically detection of an\n     * error in some part of the system.\n     *\n     * The Vault can only be paused during an initial time period, after which pausing is forever disabled.\n     *\n     * While the contract is paused, the following features are disabled:\n     * - depositing and transferring internal balance\n     * - transferring external balance (using the Vault's allowance)\n     * - swaps\n     * - joining Pools\n     * - Asset Manager interactions\n     *\n     * Internal Balance can still be withdrawn, and Pools exited.\n     */\n    function setPaused(bool paused) external;\n\n    /**\n     * @dev Returns the Vault's WETH instance.\n     */\n    function WETH() external view returns (IWETH);\n    // solhint-disable-previous-line func-name-mixedcase\n}\n"
      },
      "@balancer-labs/v2-solidity-utils/contracts/openzeppelin/ReentrancyGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\n// Based on the ReentrancyGuard library from OpenZeppelin Contracts, altered to reduce bytecode size.\n// Modifier code is inlined by the compiler, which causes its code to appear multiple times in the codebase. By using\n// private functions, we achieve the same end result with slightly higher runtime gas costs, but reduced bytecode size.\n\npragma solidity ^0.7.0;\n\nimport \"@balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor() {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and make it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _enterNonReentrant();\n        _;\n        _exitNonReentrant();\n    }\n\n    function _enterNonReentrant() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        _require(_status != _ENTERED, Errors.REENTRANCY);\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _exitNonReentrant() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/IAuthentication.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\ninterface IAuthentication {\n    /**\n     * @dev Returns the action identifier associated with the external function described by `selector`.\n     */\n    function getActionId(bytes4 selector) external view returns (bytes32);\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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    /**\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(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\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"
      },
      "@balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ISignaturesValidator.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface for the SignatureValidator helper, used to support meta-transactions.\n */\ninterface ISignaturesValidator {\n    /**\n     * @dev Returns the EIP712 domain separator.\n     */\n    function getDomainSeparator() external view returns (bytes32);\n\n    /**\n     * @dev Returns the next nonce used by an address to sign messages.\n     */\n    function getNextNonce(address user) external view returns (uint256);\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/ITemporarilyPausable.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface for the TemporarilyPausable helper.\n */\ninterface ITemporarilyPausable {\n    /**\n     * @dev Emitted every time the pause state changes by `_setPaused`.\n     */\n    event PausedStateChanged(bool paused);\n\n    /**\n     * @dev Returns the current paused state.\n     */\n    function getPausedState()\n        external\n        view\n        returns (\n            bool paused,\n            uint256 pauseWindowEndTime,\n            uint256 bufferPeriodEndTime\n        );\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IWETH.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"../openzeppelin/IERC20.sol\";\n\n/**\n * @dev Interface for WETH9.\n * See https://github.com/gnosis/canonical-weth/blob/0dd1ea3e295eef916d0c6223ec63141137d22d67/contracts/WETH9.sol\n */\ninterface IWETH is IERC20 {\n    function deposit() external payable;\n\n    function withdraw(uint256 amount) external;\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/vault/IAsset.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\n/**\n * @dev This is an empty interface used to represent either ERC20-conforming token contracts or ETH (using the zero\n * address sentinel value). We're just relying on the fact that `interface` can be used to declare new address-like\n * types.\n *\n * This concept is unrelated to a Pool's Asset Managers.\n */\ninterface IAsset {\n    // solhint-disable-previous-line no-empty-blocks\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/vault/IFlashLoanRecipient.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\n// Inspired by Aave Protocol's IFlashLoanReceiver.\n\nimport \"../solidity-utils/openzeppelin/IERC20.sol\";\n\ninterface IFlashLoanRecipient {\n    /**\n     * @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient.\n     *\n     * At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this\n     * call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the\n     * Vault, or else the entire flash loan will revert.\n     *\n     * `userData` is the same value passed in the `IVault.flashLoan` call.\n     */\n    function receiveFlashLoan(\n        IERC20[] memory tokens,\n        uint256[] memory amounts,\n        uint256[] memory feeAmounts,\n        bytes memory userData\n    ) external;\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/vault/IProtocolFeesCollector.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\npragma experimental ABIEncoderV2;\n\nimport \"../solidity-utils/openzeppelin/IERC20.sol\";\n\nimport \"./IVault.sol\";\nimport \"./IAuthorizer.sol\";\n\ninterface IProtocolFeesCollector {\n    event SwapFeePercentageChanged(uint256 newSwapFeePercentage);\n    event FlashLoanFeePercentageChanged(uint256 newFlashLoanFeePercentage);\n\n    function withdrawCollectedFees(\n        IERC20[] calldata tokens,\n        uint256[] calldata amounts,\n        address recipient\n    ) external;\n\n    function setSwapFeePercentage(uint256 newSwapFeePercentage) external;\n\n    function setFlashLoanFeePercentage(uint256 newFlashLoanFeePercentage) external;\n\n    function getSwapFeePercentage() external view returns (uint256);\n\n    function getFlashLoanFeePercentage() external view returns (uint256);\n\n    function getCollectedFeeAmounts(IERC20[] memory tokens) external view returns (uint256[] memory feeAmounts);\n\n    function getAuthorizer() external view returns (IAuthorizer);\n\n    function vault() external view returns (IVault);\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\n// solhint-disable\n\n/**\n * @dev Reverts if `condition` is false, with a revert reason containing `errorCode`. Only codes up to 999 are\n * supported.\n * Uses the default 'BAL' prefix for the error code\n */\nfunction _require(bool condition, uint256 errorCode) pure {\n    if (!condition) _revert(errorCode);\n}\n\n/**\n * @dev Reverts if `condition` is false, with a revert reason containing `errorCode`. Only codes up to 999 are\n * supported.\n */\nfunction _require(bool condition, uint256 errorCode, bytes3 prefix) pure {\n    if (!condition) _revert(errorCode, prefix);\n}\n\n/**\n * @dev Reverts with a revert reason containing `errorCode`. Only codes up to 999 are supported.\n * Uses the default 'BAL' prefix for the error code\n */\nfunction _revert(uint256 errorCode) pure {\n    _revert(errorCode, 0x42414c); // This is the raw byte representation of \"BAL\"\n}\n\n/**\n * @dev Reverts with a revert reason containing `errorCode`. Only codes up to 999 are supported.\n */\nfunction _revert(uint256 errorCode, bytes3 prefix) pure {\n    uint256 prefixUint = uint256(uint24(prefix));\n    // We're going to dynamically create a revert string based on the error code, with the following format:\n    // 'BAL#{errorCode}'\n    // where the code is left-padded with zeroes to three digits (so they range from 000 to 999).\n    //\n    // We don't have revert strings embedded in the contract to save bytecode size: it takes much less space to store a\n    // number (8 to 16 bits) than the individual string characters.\n    //\n    // The dynamic string creation algorithm that follows could be implemented in Solidity, but assembly allows for a\n    // much denser implementation, again saving bytecode size. Given this function unconditionally reverts, this is a\n    // safe place to rely on it without worrying about how its usage might affect e.g. memory contents.\n    assembly {\n        // First, we need to compute the ASCII representation of the error code. We assume that it is in the 0-999\n        // range, so we only need to convert three digits. To convert the digits to ASCII, we add 0x30, the value for\n        // the '0' character.\n\n        let units := add(mod(errorCode, 10), 0x30)\n\n        errorCode := div(errorCode, 10)\n        let tenths := add(mod(errorCode, 10), 0x30)\n\n        errorCode := div(errorCode, 10)\n        let hundreds := add(mod(errorCode, 10), 0x30)\n\n        // With the individual characters, we can now construct the full string.\n        // We first append the '#' character (0x23) to the prefix. In the case of 'BAL', it results in 0x42414c23 ('BAL#')\n        // Then, we shift this by 24 (to provide space for the 3 bytes of the error code), and add the\n        // characters to it, each shifted by a multiple of 8.\n        // The revert reason is then shifted left by 200 bits (256 minus the length of the string, 7 characters * 8 bits\n        // per character = 56) to locate it in the most significant part of the 256 slot (the beginning of a byte\n        // array).\n        let formattedPrefix := shl(24, add(0x23, shl(8, prefixUint)))\n\n        let revertReason := shl(200, add(formattedPrefix, add(add(units, shl(8, tenths)), shl(16, hundreds))))\n\n        // We can now encode the reason in memory, which can be safely overwritten as we're about to revert. The encoded\n        // message will have the following layout:\n        // [ revert reason identifier ] [ string location offset ] [ string length ] [ string contents ]\n\n        // The Solidity revert reason identifier is 0x08c739a0, the function selector of the Error(string) function. We\n        // also write zeroes to the next 28 bytes of memory, but those are about to be overwritten.\n        mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n        // Next is the offset to the location of the string, which will be placed immediately after (20 bytes away).\n        mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020)\n        // The string length is fixed: 7 characters.\n        mstore(0x24, 7)\n        // Finally, the string itself is stored.\n        mstore(0x44, revertReason)\n\n        // Even if the string is only 7 bytes long, we need to return a full 32 byte slot containing it. The length of\n        // the encoded message is therefore 4 + 32 + 32 + 32 = 100.\n        revert(0, 100)\n    }\n}\n\nlibrary Errors {\n    // Math\n    uint256 internal constant ADD_OVERFLOW = 0;\n    uint256 internal constant SUB_OVERFLOW = 1;\n    uint256 internal constant SUB_UNDERFLOW = 2;\n    uint256 internal constant MUL_OVERFLOW = 3;\n    uint256 internal constant ZERO_DIVISION = 4;\n    uint256 internal constant DIV_INTERNAL = 5;\n    uint256 internal constant X_OUT_OF_BOUNDS = 6;\n    uint256 internal constant Y_OUT_OF_BOUNDS = 7;\n    uint256 internal constant PRODUCT_OUT_OF_BOUNDS = 8;\n    uint256 internal constant INVALID_EXPONENT = 9;\n\n    // Input\n    uint256 internal constant OUT_OF_BOUNDS = 100;\n    uint256 internal constant UNSORTED_ARRAY = 101;\n    uint256 internal constant UNSORTED_TOKENS = 102;\n    uint256 internal constant INPUT_LENGTH_MISMATCH = 103;\n    uint256 internal constant ZERO_TOKEN = 104;\n\n    // Shared pools\n    uint256 internal constant MIN_TOKENS = 200;\n    uint256 internal constant MAX_TOKENS = 201;\n    uint256 internal constant MAX_SWAP_FEE_PERCENTAGE = 202;\n    uint256 internal constant MIN_SWAP_FEE_PERCENTAGE = 203;\n    uint256 internal constant MINIMUM_BPT = 204;\n    uint256 internal constant CALLER_NOT_VAULT = 205;\n    uint256 internal constant UNINITIALIZED = 206;\n    uint256 internal constant BPT_IN_MAX_AMOUNT = 207;\n    uint256 internal constant BPT_OUT_MIN_AMOUNT = 208;\n    uint256 internal constant EXPIRED_PERMIT = 209;\n    uint256 internal constant NOT_TWO_TOKENS = 210;\n    uint256 internal constant DISABLED = 211;\n\n    // Pools\n    uint256 internal constant MIN_AMP = 300;\n    uint256 internal constant MAX_AMP = 301;\n    uint256 internal constant MIN_WEIGHT = 302;\n    uint256 internal constant MAX_STABLE_TOKENS = 303;\n    uint256 internal constant MAX_IN_RATIO = 304;\n    uint256 internal constant MAX_OUT_RATIO = 305;\n    uint256 internal constant MIN_BPT_IN_FOR_TOKEN_OUT = 306;\n    uint256 internal constant MAX_OUT_BPT_FOR_TOKEN_IN = 307;\n    uint256 internal constant NORMALIZED_WEIGHT_INVARIANT = 308;\n    uint256 internal constant INVALID_TOKEN = 309;\n    uint256 internal constant UNHANDLED_JOIN_KIND = 310;\n    uint256 internal constant ZERO_INVARIANT = 311;\n    uint256 internal constant ORACLE_INVALID_SECONDS_QUERY = 312;\n    uint256 internal constant ORACLE_NOT_INITIALIZED = 313;\n    uint256 internal constant ORACLE_QUERY_TOO_OLD = 314;\n    uint256 internal constant ORACLE_INVALID_INDEX = 315;\n    uint256 internal constant ORACLE_BAD_SECS = 316;\n    uint256 internal constant AMP_END_TIME_TOO_CLOSE = 317;\n    uint256 internal constant AMP_ONGOING_UPDATE = 318;\n    uint256 internal constant AMP_RATE_TOO_HIGH = 319;\n    uint256 internal constant AMP_NO_ONGOING_UPDATE = 320;\n    uint256 internal constant STABLE_INVARIANT_DIDNT_CONVERGE = 321;\n    uint256 internal constant STABLE_GET_BALANCE_DIDNT_CONVERGE = 322;\n    uint256 internal constant RELAYER_NOT_CONTRACT = 323;\n    uint256 internal constant BASE_POOL_RELAYER_NOT_CALLED = 324;\n    uint256 internal constant REBALANCING_RELAYER_REENTERED = 325;\n    uint256 internal constant GRADUAL_UPDATE_TIME_TRAVEL = 326;\n    uint256 internal constant SWAPS_DISABLED = 327;\n    uint256 internal constant CALLER_IS_NOT_LBP_OWNER = 328;\n    uint256 internal constant PRICE_RATE_OVERFLOW = 329;\n    uint256 internal constant INVALID_JOIN_EXIT_KIND_WHILE_SWAPS_DISABLED = 330;\n    uint256 internal constant WEIGHT_CHANGE_TOO_FAST = 331;\n    uint256 internal constant LOWER_GREATER_THAN_UPPER_TARGET = 332;\n    uint256 internal constant UPPER_TARGET_TOO_HIGH = 333;\n    uint256 internal constant UNHANDLED_BY_LINEAR_POOL = 334;\n    uint256 internal constant OUT_OF_TARGET_RANGE = 335;\n    uint256 internal constant UNHANDLED_EXIT_KIND = 336;\n    uint256 internal constant UNAUTHORIZED_EXIT = 337;\n    uint256 internal constant MAX_MANAGEMENT_SWAP_FEE_PERCENTAGE = 338;\n    uint256 internal constant UNHANDLED_BY_MANAGED_POOL = 339;\n    uint256 internal constant UNHANDLED_BY_PHANTOM_POOL = 340;\n    uint256 internal constant TOKEN_DOES_NOT_HAVE_RATE_PROVIDER = 341;\n    uint256 internal constant INVALID_INITIALIZATION = 342;\n    uint256 internal constant OUT_OF_NEW_TARGET_RANGE = 343;\n    uint256 internal constant FEATURE_DISABLED = 344;\n    uint256 internal constant UNINITIALIZED_POOL_CONTROLLER = 345;\n    uint256 internal constant SET_SWAP_FEE_DURING_FEE_CHANGE = 346;\n    uint256 internal constant SET_SWAP_FEE_PENDING_FEE_CHANGE = 347;\n    uint256 internal constant CHANGE_TOKENS_DURING_WEIGHT_CHANGE = 348;\n    uint256 internal constant CHANGE_TOKENS_PENDING_WEIGHT_CHANGE = 349;\n    uint256 internal constant MAX_WEIGHT = 350;\n    uint256 internal constant UNAUTHORIZED_JOIN = 351;\n    uint256 internal constant MAX_MANAGEMENT_AUM_FEE_PERCENTAGE = 352;\n    uint256 internal constant FRACTIONAL_TARGET = 353;\n\n    // Lib\n    uint256 internal constant REENTRANCY = 400;\n    uint256 internal constant SENDER_NOT_ALLOWED = 401;\n    uint256 internal constant PAUSED = 402;\n    uint256 internal constant PAUSE_WINDOW_EXPIRED = 403;\n    uint256 internal constant MAX_PAUSE_WINDOW_DURATION = 404;\n    uint256 internal constant MAX_BUFFER_PERIOD_DURATION = 405;\n    uint256 internal constant INSUFFICIENT_BALANCE = 406;\n    uint256 internal constant INSUFFICIENT_ALLOWANCE = 407;\n    uint256 internal constant ERC20_TRANSFER_FROM_ZERO_ADDRESS = 408;\n    uint256 internal constant ERC20_TRANSFER_TO_ZERO_ADDRESS = 409;\n    uint256 internal constant ERC20_MINT_TO_ZERO_ADDRESS = 410;\n    uint256 internal constant ERC20_BURN_FROM_ZERO_ADDRESS = 411;\n    uint256 internal constant ERC20_APPROVE_FROM_ZERO_ADDRESS = 412;\n    uint256 internal constant ERC20_APPROVE_TO_ZERO_ADDRESS = 413;\n    uint256 internal constant ERC20_TRANSFER_EXCEEDS_ALLOWANCE = 414;\n    uint256 internal constant ERC20_DECREASED_ALLOWANCE_BELOW_ZERO = 415;\n    uint256 internal constant ERC20_TRANSFER_EXCEEDS_BALANCE = 416;\n    uint256 internal constant ERC20_BURN_EXCEEDS_ALLOWANCE = 417;\n    uint256 internal constant SAFE_ERC20_CALL_FAILED = 418;\n    uint256 internal constant ADDRESS_INSUFFICIENT_BALANCE = 419;\n    uint256 internal constant ADDRESS_CANNOT_SEND_VALUE = 420;\n    uint256 internal constant SAFE_CAST_VALUE_CANT_FIT_INT256 = 421;\n    uint256 internal constant GRANT_SENDER_NOT_ADMIN = 422;\n    uint256 internal constant REVOKE_SENDER_NOT_ADMIN = 423;\n    uint256 internal constant RENOUNCE_SENDER_NOT_ALLOWED = 424;\n    uint256 internal constant BUFFER_PERIOD_EXPIRED = 425;\n    uint256 internal constant CALLER_IS_NOT_OWNER = 426;\n    uint256 internal constant NEW_OWNER_IS_ZERO = 427;\n    uint256 internal constant CODE_DEPLOYMENT_FAILED = 428;\n    uint256 internal constant CALL_TO_NON_CONTRACT = 429;\n    uint256 internal constant LOW_LEVEL_CALL_FAILED = 430;\n    uint256 internal constant NOT_PAUSED = 431;\n    uint256 internal constant ADDRESS_ALREADY_ALLOWLISTED = 432;\n    uint256 internal constant ADDRESS_NOT_ALLOWLISTED = 433;\n    uint256 internal constant ERC20_BURN_EXCEEDS_BALANCE = 434;\n    uint256 internal constant INVALID_OPERATION = 435;\n    uint256 internal constant CODEC_OVERFLOW = 436;\n    uint256 internal constant IN_RECOVERY_MODE = 437;\n    uint256 internal constant NOT_IN_RECOVERY_MODE = 438;\n    uint256 internal constant INDUCED_FAILURE = 439;\n    uint256 internal constant EXPIRED_SIGNATURE = 440;\n    uint256 internal constant MALFORMED_SIGNATURE = 441;\n    uint256 internal constant SAFE_CAST_VALUE_CANT_FIT_UINT64 = 442;\n    uint256 internal constant UNHANDLED_FEE_TYPE = 443;\n\n    // Vault\n    uint256 internal constant INVALID_POOL_ID = 500;\n    uint256 internal constant CALLER_NOT_POOL = 501;\n    uint256 internal constant SENDER_NOT_ASSET_MANAGER = 502;\n    uint256 internal constant USER_DOESNT_ALLOW_RELAYER = 503;\n    uint256 internal constant INVALID_SIGNATURE = 504;\n    uint256 internal constant EXIT_BELOW_MIN = 505;\n    uint256 internal constant JOIN_ABOVE_MAX = 506;\n    uint256 internal constant SWAP_LIMIT = 507;\n    uint256 internal constant SWAP_DEADLINE = 508;\n    uint256 internal constant CANNOT_SWAP_SAME_TOKEN = 509;\n    uint256 internal constant UNKNOWN_AMOUNT_IN_FIRST_SWAP = 510;\n    uint256 internal constant MALCONSTRUCTED_MULTIHOP_SWAP = 511;\n    uint256 internal constant INTERNAL_BALANCE_OVERFLOW = 512;\n    uint256 internal constant INSUFFICIENT_INTERNAL_BALANCE = 513;\n    uint256 internal constant INVALID_ETH_INTERNAL_BALANCE = 514;\n    uint256 internal constant INVALID_POST_LOAN_BALANCE = 515;\n    uint256 internal constant INSUFFICIENT_ETH = 516;\n    uint256 internal constant UNALLOCATED_ETH = 517;\n    uint256 internal constant ETH_TRANSFER = 518;\n    uint256 internal constant CANNOT_USE_ETH_SENTINEL = 519;\n    uint256 internal constant TOKENS_MISMATCH = 520;\n    uint256 internal constant TOKEN_NOT_REGISTERED = 521;\n    uint256 internal constant TOKEN_ALREADY_REGISTERED = 522;\n    uint256 internal constant TOKENS_ALREADY_SET = 523;\n    uint256 internal constant TOKENS_LENGTH_MUST_BE_2 = 524;\n    uint256 internal constant NONZERO_TOKEN_BALANCE = 525;\n    uint256 internal constant BALANCE_TOTAL_OVERFLOW = 526;\n    uint256 internal constant POOL_NO_TOKENS = 527;\n    uint256 internal constant INSUFFICIENT_FLASH_LOAN_BALANCE = 528;\n\n    // Fees\n    uint256 internal constant SWAP_FEE_PERCENTAGE_TOO_HIGH = 600;\n    uint256 internal constant FLASH_LOAN_FEE_PERCENTAGE_TOO_HIGH = 601;\n    uint256 internal constant INSUFFICIENT_FLASH_LOAN_FEE_AMOUNT = 602;\n    uint256 internal constant AUM_FEE_PERCENTAGE_TOO_HIGH = 603;\n\n    // Misc\n    uint256 internal constant UNIMPLEMENTED = 998;\n    uint256 internal constant SHOULD_NOT_HAPPEN = 999;\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IVotingEscrow.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IAuthorizerAdaptor.sol\";\n\n// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case\n// naming convention.\n// solhint-disable func-name-mixedcase\n\ninterface IVotingEscrow {\n    struct Point {\n        int128 bias;\n        int128 slope; // - dweight / dt\n        uint256 ts;\n        uint256 blk; // block\n    }\n\n    function epoch() external view returns (uint256);\n\n    function totalSupply(uint256 timestamp) external view returns (uint256);\n\n    function user_point_epoch(address user) external view returns (uint256);\n\n    function point_history(uint256 timestamp) external view returns (Point memory);\n\n    function user_point_history(address user, uint256 timestamp) external view returns (Point memory);\n\n    function checkpoint() external;\n\n    function admin() external view returns (IAuthorizerAdaptor);\n\n    function smart_wallet_checker() external view returns (address);\n\n    function commit_smart_wallet_checker(address newSmartWalletChecker) external;\n\n    function apply_smart_wallet_checker() external;\n}\n"
      },
      "@balancer-labs/v2-solidity-utils/contracts/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"@balancer-labs/v2-interfaces/contracts/solidity-utils/helpers/BalancerErrors.sol\";\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow checks.\n * Adapted from OpenZeppelin's SafeMath library.\n */\nlibrary Math {\n    /**\n     * @dev Returns the absolute value of a signed integer.\n     */\n    function abs(int256 a) internal pure returns (uint256) {\n        return a > 0 ? uint256(a) : uint256(-a);\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers of 256 bits, reverting on overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        _require(c >= a, Errors.ADD_OVERFLOW);\n        return c;\n    }\n\n    /**\n     * @dev Returns the addition of two signed integers, reverting on overflow.\n     */\n    function add(int256 a, int256 b) internal pure returns (int256) {\n        int256 c = a + b;\n        _require((b >= 0 && c >= a) || (b < 0 && c < a), Errors.ADD_OVERFLOW);\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers of 256 bits, reverting on overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        _require(b <= a, Errors.SUB_OVERFLOW);\n        uint256 c = a - b;\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two signed integers, reverting on overflow.\n     */\n    function sub(int256 a, int256 b) internal pure returns (int256) {\n        int256 c = a - b;\n        _require((b >= 0 && c <= a) || (b < 0 && c > a), Errors.SUB_OVERFLOW);\n        return c;\n    }\n\n    /**\n     * @dev Returns the largest of two numbers of 256 bits.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a >= b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers of 256 bits.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a * b;\n        _require(a == 0 || c / a == b, Errors.MUL_OVERFLOW);\n        return c;\n    }\n\n    function div(\n        uint256 a,\n        uint256 b,\n        bool roundUp\n    ) internal pure returns (uint256) {\n        return roundUp ? divUp(a, b) : divDown(a, b);\n    }\n\n    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        _require(b != 0, Errors.ZERO_DIVISION);\n        return a / b;\n    }\n\n    function divUp(uint256 a, uint256 b) internal pure returns (uint256) {\n        _require(b != 0, Errors.ZERO_DIVISION);\n\n        if (a == 0) {\n            return 0;\n        } else {\n            return 1 + (a - 1) / b;\n        }\n    }\n}\n"
      },
      "contracts/gauges/StakelessGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"@balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol\";\nimport \"@balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerMinter.sol\";\nimport \"@balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerTokenAdmin.sol\";\nimport \"@balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeController.sol\";\nimport \"@balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakelessGauge.sol\";\n\nimport \"@balancer-labs/v2-solidity-utils/contracts/math/Math.sol\";\nimport \"@balancer-labs/v2-solidity-utils/contracts/openzeppelin/ReentrancyGuard.sol\";\n\nabstract contract StakelessGauge is IStakelessGauge, ReentrancyGuard {\n    uint256 public constant MAX_RELATIVE_WEIGHT_CAP = 1e18;\n\n    IERC20 internal immutable _balToken;\n    IBalancerTokenAdmin private immutable _tokenAdmin;\n    IBalancerMinter private immutable _minter;\n    IGaugeController private immutable _gaugeController;\n    IAuthorizerAdaptor private immutable _authorizerAdaptor;\n\n    event Checkpoint(uint256 indexed periodTime, uint256 periodEmissions);\n\n    // solhint-disable var-name-mixedcase\n    uint256 private immutable _RATE_REDUCTION_TIME;\n    uint256 private immutable _RATE_REDUCTION_COEFFICIENT;\n    uint256 private immutable _RATE_DENOMINATOR;\n    // solhint-enable var-name-mixedcase\n\n    uint256 private _rate;\n    uint256 private _period;\n    uint256 private _startEpochTime;\n\n    uint256 private _emissions;\n    bool private _isKilled;\n\n    uint256 private _relativeWeightCap;\n\n    constructor(IBalancerMinter minter) {\n        IBalancerTokenAdmin tokenAdmin = IBalancerTokenAdmin(minter.getBalancerTokenAdmin());\n        IERC20 balToken = tokenAdmin.getBalancerToken();\n        IGaugeController gaugeController = minter.getGaugeController();\n\n        _balToken = balToken;\n        _tokenAdmin = tokenAdmin;\n        _minter = minter;\n        _gaugeController = gaugeController;\n        _authorizerAdaptor = gaugeController.admin();\n\n        _RATE_REDUCTION_TIME = tokenAdmin.RATE_REDUCTION_TIME();\n        _RATE_REDUCTION_COEFFICIENT = tokenAdmin.RATE_REDUCTION_COEFFICIENT();\n        _RATE_DENOMINATOR = tokenAdmin.RATE_DENOMINATOR();\n\n        // Prevent initialisation of implementation contract\n        // Choice of `type(uint256).max` prevents implementation from being checkpointed\n        _period = type(uint256).max;\n    }\n\n    // solhint-disable-next-line func-name-mixedcase\n    function __StakelessGauge_init(uint256 relativeWeightCap) internal {\n        require(_period == 0, \"Already initialized\");\n\n        // Because we calculate the rate locally, this gauge cannot\n        // be used prior to the start of the first emission period\n        uint256 rate = _tokenAdmin.rate();\n        require(rate != 0, \"BalancerTokenAdmin not yet activated\");\n\n        _rate = rate;\n        _period = _currentPeriod();\n        _startEpochTime = _tokenAdmin.startEpochTimeWrite();\n        _setRelativeWeightCap(relativeWeightCap);\n    }\n\n    function checkpoint() external payable override nonReentrant returns (bool) {\n        require(msg.sender == address(_authorizerAdaptor), \"SENDER_NOT_ALLOWED\");\n        uint256 lastPeriod = _period;\n        uint256 currentPeriod = _currentPeriod();\n\n        if (lastPeriod < currentPeriod) {\n            _gaugeController.checkpoint_gauge(address(this));\n\n            uint256 rate = _rate;\n            uint256 newEmissions = 0;\n            lastPeriod += 1;\n            uint256 nextEpochTime = _startEpochTime + _RATE_REDUCTION_TIME;\n            for (uint256 i = lastPeriod; i < lastPeriod + 255; ++i) {\n                if (i > currentPeriod) break;\n\n                uint256 periodTime = i * 1 weeks;\n                uint256 periodEmission = 0;\n                uint256 gaugeWeight = getCappedRelativeWeight(periodTime);\n\n                if (nextEpochTime >= periodTime && nextEpochTime < periodTime + 1 weeks) {\n                    // If the period crosses an epoch, we calculate a reduction in the rate\n                    // using the same formula as used in `BalancerTokenAdmin`. We perform the calculation\n                    // locally instead of calling to `BalancerTokenAdmin.rate()` because we are generating\n                    // the emissions for the upcoming week, so there is a possibility the new\n                    // rate has not yet been applied.\n\n                    // Calculate emission up until the epoch change\n                    uint256 durationInCurrentEpoch = nextEpochTime - periodTime;\n                    periodEmission = (gaugeWeight * rate * durationInCurrentEpoch) / 10**18;\n                    // Action the decrease in rate\n                    rate = (rate * _RATE_DENOMINATOR) / _RATE_REDUCTION_COEFFICIENT;\n                    // Calculate emission from epoch change to end of period\n                    uint256 durationInNewEpoch = 1 weeks - durationInCurrentEpoch;\n                    periodEmission += (gaugeWeight * rate * durationInNewEpoch) / 10**18;\n\n                    _rate = rate;\n                    _startEpochTime = nextEpochTime;\n                    nextEpochTime += _RATE_REDUCTION_TIME;\n                } else {\n                    periodEmission = (gaugeWeight * rate * 1 weeks) / 10**18;\n                }\n\n                emit Checkpoint(periodTime, periodEmission);\n                newEmissions += periodEmission;\n            }\n\n            _period = currentPeriod;\n            _emissions += newEmissions;\n\n            if (newEmissions > 0 && !_isKilled) {\n                _minter.mint(address(this));\n                _postMintAction(newEmissions);\n            }\n        }\n\n        return true;\n    }\n\n    function _currentPeriod() internal view returns (uint256) {\n        // solhint-disable-next-line not-rely-on-time\n        return (block.timestamp / 1 weeks) - 1;\n    }\n\n    function _postMintAction(uint256 mintAmount) internal virtual;\n\n    // solhint-disable func-name-mixedcase\n\n    function user_checkpoint(address) external pure override returns (bool) {\n        return true;\n    }\n\n    function integrate_fraction(address user) external view override returns (uint256) {\n        require(user == address(this), \"Gauge can only mint for itself\");\n        return _emissions;\n    }\n\n    function is_killed() external view override returns (bool) {\n        return _isKilled;\n    }\n\n    function killGauge() external override {\n        require(msg.sender == address(_authorizerAdaptor), \"SENDER_NOT_ALLOWED\");\n        _isKilled = true;\n    }\n\n    function unkillGauge() external override {\n        require(msg.sender == address(_authorizerAdaptor), \"SENDER_NOT_ALLOWED\");\n        _isKilled = false;\n    }\n\n    function setRelativeWeightCap(uint256 relativeWeightCap) external override {\n        require(msg.sender == address(_authorizerAdaptor), \"SENDER_NOT_ALLOWED\");\n        _setRelativeWeightCap(relativeWeightCap);\n    }\n\n    function _setRelativeWeightCap(uint256 relativeWeightCap) internal {\n        require(relativeWeightCap <= MAX_RELATIVE_WEIGHT_CAP, \"Relative weight cap exceeds allowed absolute maximum\");\n        _relativeWeightCap = relativeWeightCap;\n        emit RelativeWeightCapChanged(relativeWeightCap);\n    }\n\n    function getRelativeWeightCap() external view override returns (uint256) {\n        return _relativeWeightCap;\n    }\n\n    function getCappedRelativeWeight(uint256 time) public view override returns (uint256) {\n        return Math.min(_gaugeController.gauge_relative_weight(address(this), time), _relativeWeightCap);\n    }\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerMinter.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"./IBalancerTokenAdmin.sol\";\nimport \"./IGaugeController.sol\";\n\ninterface IBalancerMinter {\n    event Minted(address indexed recipient, address gauge, uint256 minted);\n\n    /**\n     * @notice Returns the address of the Balancer Governance Token\n     */\n    function getBalancerToken() external view returns (IERC20);\n\n    /**\n     * @notice Returns the address of the Balancer Token Admin contract\n     */\n    function getBalancerTokenAdmin() external view returns (IBalancerTokenAdmin);\n\n    /**\n     * @notice Returns the address of the Gauge Controller\n     */\n    function getGaugeController() external view returns (IGaugeController);\n\n    /**\n     * @notice Mint everything which belongs to `msg.sender` and send to them\n     * @param gauge `LiquidityGauge` address to get mintable amount from\n     */\n    function mint(address gauge) external returns (uint256);\n\n    /**\n     * @notice Mint everything which belongs to `msg.sender` across multiple gauges\n     * @param gauges List of `LiquidityGauge` addresses\n     */\n    function mintMany(address[] calldata gauges) external returns (uint256);\n\n    /**\n     * @notice Mint tokens for `user`\n     * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf\n     * @param gauge `LiquidityGauge` address to get mintable amount from\n     * @param user Address to mint to\n     */\n    function mintFor(address gauge, address user) external returns (uint256);\n\n    /**\n     * @notice Mint tokens for `user` across multiple gauges\n     * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf\n     * @param gauges List of `LiquidityGauge` addresses\n     * @param user Address to mint to\n     */\n    function mintManyFor(address[] calldata gauges, address user) external returns (uint256);\n\n    /**\n     * @notice The total number of tokens minted for `user` from `gauge`\n     */\n    function minted(address user, address gauge) external view returns (uint256);\n\n    /**\n     * @notice Whether `minter` is approved to mint tokens for `user`\n     */\n    function getMinterApproval(address minter, address user) external view returns (bool);\n\n    /**\n     * @notice Set whether `minter` is approved to mint tokens on your behalf\n     */\n    function setMinterApproval(address minter, bool approval) external;\n\n    /**\n     * @notice Set whether `minter` is approved to mint tokens on behalf of `user`, who has signed a message authorizing\n     * them.\n     */\n    function setMinterApprovalWithSignature(\n        address minter,\n        bool approval,\n        address user,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    // The below functions are near-duplicates of functions available above.\n    // They are included for ABI compatibility with snake_casing as used in vyper contracts.\n    // solhint-disable func-name-mixedcase\n\n    /**\n     * @notice Whether `minter` is approved to mint tokens for `user`\n     */\n    function allowed_to_mint_for(address minter, address user) external view returns (bool);\n\n    /**\n     * @notice Mint everything which belongs to `msg.sender` across multiple gauges\n     * @dev This function is not recommended as `mintMany()` is more flexible and gas efficient\n     * @param gauges List of `LiquidityGauge` addresses\n     */\n    function mint_many(address[8] calldata gauges) external;\n\n    /**\n     * @notice Mint tokens for `user`\n     * @dev Only possible when `msg.sender` has been approved by `user` to mint on their behalf\n     * @param gauge `LiquidityGauge` address to get mintable amount from\n     * @param user Address to mint to\n     */\n    function mint_for(address gauge, address user) external;\n\n    /**\n     * @notice Toggle whether `minter` is approved to mint tokens for `user`\n     */\n    function toggle_approve_mint(address minter) external;\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerTokenAdmin.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"../solidity-utils/helpers/IAuthentication.sol\";\n\nimport \"./IBalancerToken.sol\";\n\ninterface IBalancerTokenAdmin is IAuthentication {\n    // solhint-disable func-name-mixedcase\n    function INITIAL_RATE() external view returns (uint256);\n\n    function RATE_REDUCTION_TIME() external view returns (uint256);\n\n    function RATE_REDUCTION_COEFFICIENT() external view returns (uint256);\n\n    function RATE_DENOMINATOR() external view returns (uint256);\n\n    // solhint-enable func-name-mixedcase\n\n    /**\n     * @notice Returns the address of the Balancer Governance Token\n     */\n    function getBalancerToken() external view returns (IBalancerToken);\n\n    function activate() external;\n\n    function rate() external view returns (uint256);\n\n    function startEpochTimeWrite() external returns (uint256);\n\n    function mint(address to, uint256 amount) external;\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IGaugeController.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"../solidity-utils/openzeppelin/IERC20.sol\";\n\nimport \"./IAuthorizerAdaptor.sol\";\nimport \"./IVotingEscrow.sol\";\n\n// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case\n// naming convention.\n// solhint-disable func-name-mixedcase\n\ninterface IGaugeController {\n    function checkpoint_gauge(address gauge) external;\n\n    function gauge_relative_weight(address gauge, uint256 time) external view returns (uint256);\n\n    function voting_escrow() external view returns (IVotingEscrow);\n\n    function token() external view returns (IERC20);\n\n    function add_type(string calldata name, uint256 weight) external;\n\n    function change_type_weight(int128 typeId, uint256 weight) external;\n\n    function add_gauge(address gauge, int128 gaugeType) external;\n\n    function n_gauge_types() external view returns (int128);\n\n    function gauge_types(address gauge) external view returns (int128);\n\n    function admin() external view returns (IAuthorizerAdaptor);\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IStakelessGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"./ILiquidityGauge.sol\";\n\ninterface IStakelessGauge is ILiquidityGauge {\n    function checkpoint() external payable returns (bool);\n\n    function getRecipient() external view returns (address);\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IBalancerToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"../solidity-utils/openzeppelin/IERC20.sol\";\n\ninterface IBalancerToken is IERC20 {\n    function mint(address to, uint256 amount) external;\n\n    function getRoleMemberCount(bytes32 role) external view returns (uint256);\n\n    function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    function grantRole(bytes32 role, address account) external;\n\n    function revokeRole(bytes32 role, address account) external;\n\n    // solhint-disable-next-line func-name-mixedcase\n    function DEFAULT_ADMIN_ROLE() external view returns (bytes32);\n\n    // solhint-disable-next-line func-name-mixedcase\n    function MINTER_ROLE() external view returns (bytes32);\n\n    // solhint-disable-next-line func-name-mixedcase\n    function SNAPSHOT_ROLE() external view returns (bytes32);\n\n    function snapshot() external;\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/ILiquidityGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\n// For compatibility, we're keeping the same function names as in the original Curve code, including the mixed-case\n// naming convention.\n// solhint-disable func-name-mixedcase\n// solhint-disable func-param-name-mixedcase\n\ninterface ILiquidityGauge {\n    // solhint-disable-next-line var-name-mixedcase\n    event RelativeWeightCapChanged(uint256 new_relative_weight_cap);\n\n    /**\n     * @notice Returns BAL liquidity emissions calculated during checkpoints for the given user.\n     * @param user User address.\n     * @return uint256 BAL amount to issue for the address.\n     */\n    function integrate_fraction(address user) external view returns (uint256);\n\n    /**\n     * @notice Record a checkpoint for a given user.\n     * @param user User address.\n     * @return bool Always true.\n     */\n    function user_checkpoint(address user) external returns (bool);\n\n    /**\n     * @notice Returns true if gauge is killed; false otherwise.\n     */\n    function is_killed() external view returns (bool);\n\n    /**\n     * @notice Kills the gauge so it cannot mint BAL.\n     */\n    function killGauge() external;\n\n    /**\n     * @notice Unkills the gauge so it can mint BAL again.\n     */\n    function unkillGauge() external;\n\n    /**\n     * @notice Sets a new relative weight cap for the gauge.\n     * The value shall be normalized to 1e18, and not greater than MAX_RELATIVE_WEIGHT_CAP.\n     * @param relativeWeightCap New relative weight cap.\n     */\n    function setRelativeWeightCap(uint256 relativeWeightCap) external;\n\n    /**\n     * @notice Gets the relative weight cap for the gauge.\n     */\n    function getRelativeWeightCap() external view returns (uint256);\n\n    /**\n     * @notice Returns the gauge's relative weight for a given time, capped to its relative weight cap attribute.\n     * @param time Timestamp in the past or present.\n     */\n    function getCappedRelativeWeight(uint256 time) external view returns (uint256);\n}\n"
      },
      "contracts/gauges/arbitrum/IGatewayRouter.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"@balancer-labs/v2-interfaces/contracts/solidity-utils/openzeppelin/IERC20.sol\";\n\ninterface IGatewayRouter {\n    function outboundTransfer(\n        IERC20 token,\n        address recipient,\n        uint256 amount,\n        uint256 gasLimit,\n        uint256 gasPrice,\n        bytes calldata data\n    ) external payable;\n\n    function getGateway(address token) external view returns (address gateway);\n}\n"
      },
      "contracts/gauges/arbitrum/ArbitrumRootGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\nimport \"@balancer-labs/v2-interfaces/contracts/liquidity-mining/IArbitrumFeeProvider.sol\";\n\nimport \"../StakelessGauge.sol\";\nimport \"./IGatewayRouter.sol\";\n\ncontract ArbitrumRootGauge is StakelessGauge {\n    address private immutable _gateway;\n    IGatewayRouter private immutable _gatewayRouter;\n    IArbitrumFeeProvider private immutable _factory;\n\n    address private _recipient;\n\n    constructor(IBalancerMinter minter, IGatewayRouter gatewayRouter) StakelessGauge(minter) {\n        _gateway = gatewayRouter.getGateway(address(minter.getBalancerToken()));\n        _gatewayRouter = gatewayRouter;\n        _factory = IArbitrumFeeProvider(msg.sender);\n    }\n\n    function initialize(address recipient, uint256 relativeWeightCap) external {\n        // This will revert in all calls except the first one\n        __StakelessGauge_init(relativeWeightCap);\n\n        _recipient = recipient;\n    }\n\n    function getRecipient() external view override returns (address) {\n        return _recipient;\n    }\n\n    function _postMintAction(uint256 mintAmount) internal override {\n        // Token needs to be approved on the gateway NOT the gateway router\n        _balToken.approve(_gateway, mintAmount);\n\n        (uint256 gasLimit, uint256 gasPrice, uint256 maxSubmissionCost) = _factory.getArbitrumFees();\n        uint256 totalBridgeCost = _getTotalBridgeCost(gasLimit, gasPrice, maxSubmissionCost);\n        require(msg.value == totalBridgeCost, \"Incorrect msg.value passed\");\n\n        // After bridging, the BAL should arrive on Arbitrum within 10 minutes. If it\n        // does not, the L2 transaction may have failed due to an insufficient amount\n        // within `max_submission_cost + (gas_limit * gas_price)`\n        // In this case, the transaction can be manually broadcasted on Arbitrum by calling\n        // `ArbRetryableTicket(0x000000000000000000000000000000000000006e).redeem(redemption-TxID)`\n        // The calldata for this manual transaction is easily obtained by finding the reverted\n        // transaction in the tx history for 0x000000000000000000000000000000000000006e on Arbiscan.\n        // https://developer.offchainlabs.com/docs/l1_l2_messages#retryable-transaction-lifecycle\n        _gatewayRouter.outboundTransfer{ value: totalBridgeCost }(\n            _balToken,\n            _recipient,\n            mintAmount,\n            gasLimit,\n            gasPrice,\n            abi.encode(maxSubmissionCost, \"\")\n        );\n    }\n\n    function getTotalBridgeCost() external view returns (uint256) {\n        (uint256 gasLimit, uint256 gasPrice, uint256 maxSubmissionCost) = _factory.getArbitrumFees();\n        return _getTotalBridgeCost(gasLimit, gasPrice, maxSubmissionCost);\n    }\n\n    function _getTotalBridgeCost(\n        uint256 gasLimit,\n        uint256 gasPrice,\n        uint256 maxSubmissionCost\n    ) internal pure returns (uint256) {\n        return gasLimit * gasPrice + maxSubmissionCost;\n    }\n}\n"
      },
      "@balancer-labs/v2-interfaces/contracts/liquidity-mining/IArbitrumFeeProvider.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.7.0;\n\ninterface IArbitrumFeeProvider {\n    function getArbitrumFees()\n        external\n        view\n        returns (\n            uint256 gasLimit,\n            uint256 gasPrice,\n            uint256 maxSubmissionCost\n        );\n\n    function setArbitrumFees(\n        uint64 gasLimit,\n        uint64 gasPrice,\n        uint64 maxSubmissionCost\n    ) external;\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 9999
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}