{"file_path":"src/integrations/farms/AaveV4Farm.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport {IFarm} from \"@interfaces/IFarm.sol\";\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {MultiAssetFarmV2} from \"@integrations/MultiAssetFarmV2.sol\";\nimport {SwapFarmV2WithMaturity} from \"@integrations/farms/SwapFarmV2WithMaturity.sol\";\nimport {IAaveV4Spoke, IAaveV4Hub} from \"@interfaces/aave/IAaveV4Spoke.sol\";\n\n/// @title Aave V4 Farm\n/// @notice Farm that receives the primary assetToken (e.g. USDC), uses SwapFarmV2\n/// functionality to swap it to aaveAssetToken (e.g. USDG), and supplies aaveAssetToken to an\n/// Aave V4 Spoke through keeper-triggered functions.\ncontract AaveV4Farm is SwapFarmV2WithMaturity {\n    using SafeERC20 for IERC20;\n\n    /// @notice Address of the Aave V4 Spoke this farm supplies to.\n    address public immutable spoke;\n\n    /// @notice Reserve id within the Aave V4 Spoke that corresponds to aaveAssetToken.\n    uint256 public immutable reserveId;\n\n    /// @notice Token supplied to Aave V4 (e.g. USDG). Can be distinct from the primary\n    /// assetToken (e.g. USDC) which represents the farm's accounting & liquidity unit.\n    address public immutable aaveAssetToken;\n\n    /// @notice Aave V4 Hub backing the reserve, used to read the asset-wide deficit and supply shares.\n    address public immutable hub;\n\n    /// @notice Hub-level asset id of aaveAssetToken (distinct from the spoke `reserveId`).\n    uint256 public immutable aaveAssetId;\n\n    constructor(\n        address _core,\n        address _assetToken,\n        address _accounting,\n        address _settlementContract,\n        address _vaultRelayer,\n        uint256 _duration,\n        address _spoke,\n        uint256 _reserveId\n    ) SwapFarmV2WithMaturity(_core, _assetToken, _accounting, _settlementContract, _vaultRelayer, _duration) {\n        spoke = _spoke;\n        reserveId = _reserveId;\n\n        // cache immutables to save gas when reading assets()\n        IAaveV4Spoke.Reserve memory reserve = IAaveV4Spoke(_spoke).getReserve(_reserveId);\n        aaveAssetToken = reserve.underlying;\n        hub = reserve.hub;\n        aaveAssetId = reserve.assetId;\n\n        // register aaveAssetToken as a supported secondary asset if different from assetToken\n        if (aaveAssetToken != _assetToken) {\n            _enableAsset(aaveAssetToken);\n        }\n    }\n\n    /// @notice Returns the total assets held by the farm, expressed in `assetToken`.\n    /// @dev Includes all balances of enabled assets + assets supplied to Aave V4 spoke.\n    function assets() public view override(MultiAssetFarmV2, IFarm) returns (uint256) {\n        uint256 totalAssets = super.assets();\n\n        IAaveV4Spoke.UserPosition memory userPosition = IAaveV4Spoke(spoke).getUserPosition(reserveId, address(this));\n        if (userPosition.suppliedShares == 0) return totalAssets;\n\n        uint256 suppliedAaveAssets = IAaveV4Spoke(spoke).getUserSuppliedAssets(reserveId, address(this));\n\n        // subtract our pro-rata slice of realized bad debt, in aaveAssetToken units\n        uint256 deficitRay = IAaveV4Hub(hub).getAssetDeficitRay(aaveAssetId);\n        if (deficitRay != 0) {\n            // ceil(deficitRay / 1e27) converts the RAY-scaled deficit to asset units, then we take\n            // our share = suppliedShares / (addedShares + virtualShares), matching Aave's SharesMath\n            // (VIRTUAL_SHARES = 1e6). Rounding up is conservative: it never over-states assets().\n            uint256 haircut = Math.mulDiv(\n                Math.ceilDiv(deficitRay, 1e27),\n                uint256(userPosition.suppliedShares),\n                IAaveV4Hub(hub).getAddedShares(aaveAssetId) + 1e6,\n                Math.Rounding.Ceil\n            );\n            suppliedAaveAssets = suppliedAaveAssets > haircut ? suppliedAaveAssets - haircut : 0;\n        }\n\n        if (aaveAssetToken == assetToken) return totalAssets + suppliedAaveAssets;\n        else return totalAssets + convert(aaveAssetToken, assetToken, suppliedAaveAssets);\n    }\n\n    /// @notice No-op deposit\n    function _deposit(uint256 _amount) internal view virtual override {}\n\n    /// @notice Withdraw is a simple transfer.\n    /// To increase liquidity call `withdrawFromAave` and eventually swap.\n    function _withdraw(uint256 _amount, address _to) internal override {\n        IERC20(assetToken).safeTransfer(_to, _amount);\n    }\n\n    /// @notice Supplies `_amount` of `aaveAssetToken` to the Aave V4 Spoke.\n    function depositToAave(uint256 _amount)\n        external\n        whenNotPaused\n        checkSlippage\n        onlyCoreRole(CoreRoles.FARM_SWAP_CALLER)\n        returns (uint256 suppliedShares, uint256 suppliedAmount)\n    {\n        IERC20(aaveAssetToken).forceApprove(spoke, _amount);\n        (suppliedShares, suppliedAmount) = IAaveV4Spoke(spoke).supply(reserveId, _amount, address(this));\n    }\n\n    /// @notice Withdraws `_amount` of `aaveAssetToken` from the Aave V4.\n    function withdrawFromAave(uint256 _amount)\n        external\n        whenNotPaused\n        checkSlippage\n        onlyCoreRole(CoreRoles.FARM_SWAP_CALLER)\n        returns (uint256 withdrawnShares, uint256 withdrawnAmount)\n    {\n        (withdrawnShares, withdrawnAmount) = IAaveV4Spoke(spoke).withdraw(reserveId, _amount, address(this));\n    }\n}\n","deployed_bytecode":"0x60806040526004361061030d575f3560e01c806368fd2d801161019c5780639624e83e116100e7578063e0ffcd2111610092578063e9607c011161006d578063e9607c011461094e578063ea42418b1461096f578063ea8d1f0a146109a2578063f2f4eb26146109d5575f5ffd5b8063e0ffcd21146108dd578063e190febc14610910578063e625ad341461092f575f5ffd5b8063c23544ad116100c2578063c23544ad14610842578063d0e30db014610870578063d7ed262314610884575f5ffd5b80639624e83e146107a95780639b552cc2146107dc578063aabed5e51461080f575f5ffd5b80637df3927e116101475780638456cb59116101225780638456cb59146107545780638c04166f146107685780639387e6731461077d575f5ffd5b80637df3927e146106f657806380009630146107165780638417abc414610735575f5ffd5b8063761a1ea311610177578063761a1ea3146106a35780637b96eef1146106b85780637d38f07c146106d7575f5ffd5b806368fd2d80146106515780636ea69d621461067057806371a973051461068f575f5ffd5b8063439950811161025c57806351508f0a116102075780636083e59a116101e25780636083e59a146105f45780636863775f14610608578063688f237b1461061d575f5ffd5b806351508f0a146105a057806353770b53146105bf5780635c975abb146105de575f5ffd5b8063464b415811610237578063464b41581461051f57806347786d371461054e57806347bfbcc61461056d575f5ffd5b806343995081146104c257806343f68a49146104e15780634615707714610500575f5ffd5b8063204f83f9116102bc578063365a86fc11610297578063365a86fc146104665780633f4ba83a146104995780633ffb788e146104ad575f5ffd5b8063204f83f91461041e578063248391ff14610432578063355274ea14610451575f5ffd5b80630fb5a6b4116102ec5780630fb5a6b4146103a45780631083f761146103d75780631a6865021461040a575f5ffd5b8062f714ce14610311578063044007321461033257806306952f1e14610382575b5f5ffd5b34801561031c575f5ffd5b5061033061032b366004614461565b6109f6565b005b34801561033d575f5ffd5b506103657f000000000000000000000000e343167631d89b6ffc58b88d6b7fb0228795491d81565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561038d575f5ffd5b50610396600181565b604051908152602001610379565b3480156103af575f5ffd5b506103967f0000000000000000000000000000000000000000000000000000000000093a8081565b3480156103e2575f5ffd5b506103657f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b348015610415575f5ffd5b50610396610b39565b348015610429575f5ffd5b50610396610bc6565b34801561043d575f5ffd5b5061039661044c36600461448b565b610bf1565b34801561045c575f5ffd5b5061039660015481565b348015610471575f5ffd5b506103657f000000000000000000000000cca852bc40e560adc3b1cc58ca5b55638ce826c981565b3480156104a4575f5ffd5b50610330610d44565b3480156104b8575f5ffd5b506103966104b081565b3480156104cd575f5ffd5b506103966104dc3660046144c5565b610e1f565b3480156104ec575f5ffd5b506103306104fb3660046144ed565b610e94565b34801561050b575f5ffd5b5061033061051a366004614504565b610f8e565b34801561052a575f5ffd5b5061053e61053936600461453d565b61114e565b6040519015158152602001610379565b348015610559575f5ffd5b506103306105683660046144ed565b6111a5565b348015610578575f5ffd5b506103657f00000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c48581565b3480156105ab575f5ffd5b506103306105ba36600461453d565b611297565b3480156105ca575f5ffd5b506103306105d936600461461e565b6113ed565b3480156105e9575f5ffd5b505f5460ff1661053e565b3480156105ff575f5ffd5b506103966116c4565b348015610613575f5ffd5b5061039661a8c081565b348015610628575f5ffd5b5061063c6106373660046144ed565b6116f4565b60408051928352602083019190915201610379565b34801561065c575f5ffd5b5061063c61066b3660046144ed565b6118db565b34801561067b575f5ffd5b50600354610365906001600160a01b031681565b34801561069a575f5ffd5b50610396611a7b565b3480156106ae575f5ffd5b5061039660065481565b3480156106c3575f5ffd5b506103306106d236600461469f565b611e86565b3480156106e2575f5ffd5b506103306106f136600461471c565b611fb2565b61070961070436600461471c565b61210f565b6040516103799190614789565b348015610721575f5ffd5b5061033061073036600461453d565b612391565b348015610740575f5ffd5b5061033061074f3660046147ec565b61246e565b34801561075f575f5ffd5b506103306126ed565b348015610773575f5ffd5b5061039660025481565b348015610788575f5ffd5b5061079c6107973660046147ec565b6127c5565b604051610379919061482b565b3480156107b4575f5ffd5b506103657f0000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b381565b3480156107e7575f5ffd5b506103657f000000000000000000000000c92e8bdf79f0507f65a392b0ab4667716bfe011081565b34801561081a575f5ffd5b506103967f000000000000000000000000000000000000000000000000000000000000000881565b34801561084d575f5ffd5b5061053e61085c36600461453d565b60076020525f908152604090205460ff1681565b34801561087b575f5ffd5b50610330612b26565b34801561088f575f5ffd5b506108a361089e3660046144c5565b612c78565b60408051825167ffffffffffffffff908116825260208085015190911690820152918101516001600160801b031690820152606001610379565b3480156108e8575f5ffd5b5061053e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561091b575f5ffd5b5061033061092a36600461483d565b612cf6565b34801561093a575f5ffd5b5061033061094936600461471c565b612eda565b348015610959575f5ffd5b50610962612ff6565b6040516103799190614877565b34801561097a575f5ffd5b506103657f0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4181565b3480156109ad575f5ffd5b506103967f000000000000000000000000000000000000000000000000000000000000000b81565b3480156109e0575f5ffd5b505f5461010090046001600160a01b0316610365565b5f54604051632474521560e21b81527f5f33620cda06d02d58df96005b92bc83bd059a566e48e016372f3fbdc974e371600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610a67573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8b91906148c2565b610acb5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b610ad3613002565b5f610adc611a7b565b9050610ae88484613027565b7f35a901c4413e585f9121eb5cf07e67760bd4ac498dd031249e5cd2cd225f74e44282610b1587826148f1565b6040805193845260208401929092529082015260600160405180910390a150505050565b6040516370a0823160e01b81523060048201525f907f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316906370a0823190602401602060405180830381865afa158015610b9d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bc19190614904565b905090565b5f610bc17f0000000000000000000000000000000000000000000000000000000000093a804261491b565b5f826001600160a01b0316846001600160a01b031603610c12575080610d3d565b6040516315d5220f60e31b81526001600160a01b0385811660048301525f917f0000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b39091169063aea9107890602401602060405180830381865afa158015610c7a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9e9190614904565b6040516315d5220f60e31b81526001600160a01b0386811660048301529192505f917f0000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b3169063aea9107890602401602060405180830381865afa158015610d07573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d2b9190614904565b9050610d3884838361305b565b925050505b9392505050565b5f54604051632474521560e21b81527fe7276a2a84d8de556657ec9cf93a55a7d66f096e529d0582ed08e9e2208b92b5600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610db5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dd991906148c2565b610e145760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b610e1c613076565b50565b5f5f5f836001600160a01b0316856001600160a01b031611610e42578385610e45565b84845b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b166034820152919350915060480160405160208183030381529060405280519060200120925050505b92915050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610ef2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1691906148c2565b610f515760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b60028290556040518281527f9c922f6d0c990b250e9dd0a427a5c8da7f44b960f697fecb31cbbd8ba79ec8c2906020015b60405180910390a15050565b5f54604051632474521560e21b81527f5f33620cda06d02d58df96005b92bc83bd059a566e48e016372f3fbdc974e371600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610fff573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102391906148c2565b61105e5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b611066613002565b61106f8461114e565b80156110ad57507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316846001600160a01b031614155b84906110d8576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b505f6110e2611a7b565b90506110f86001600160a01b03861684866130c7565b5f611101611a7b565b60408051428152602081018590529081018290529091507f35a901c4413e585f9121eb5cf07e67760bd4ac498dd031249e5cd2cd225f74e4906060015b60405180910390a1505050505050565b5f7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316826001600160a01b03161480610e8e5750611195600483613101565b8015610e8e5750610e8e82613122565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015611203573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122791906148c2565b6112625760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b60018290556040518281527f3c8eb7c49d332f4c1e4d92a27cda93c31cc9452f7a408e0c6109fcddbc9946ea90602001610f82565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa1580156112f5573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131991906148c2565b6113545760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b816001600160a01b03811661138857604051633202e20d60e21b81526001600160a01b039091166004820152602401610ac2565b506003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03841690811790915560405190815242907fb9e8010e984929bdc235316d2fb8ed6c6b467a403c55770ee0f63f22dba991bc9060200160405180910390a25050565b6113f5613002565b84845f6114028383610e1f565b5f8181526008602052604090208054919250906114329067ffffffffffffffff600160401b82048116911661492e565b67ffffffffffffffff16421161145b57604051635ab1f4a960e01b815260040160405180910390fd5b6002548154600160801b90046001600160801b031690808210156114a35760405163d9a6273f60e01b81526001600160801b0390921660048301526024820152604401610ac2565b50508888806001600160a01b0316826001600160a01b0316141581906114e85760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506114f28261114e565b829061151d5760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506115278161114e565b81906115525760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b505f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa1580156115b1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115d591906148c2565b6116105760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b61161b8c8b8b6131c0565b5f6116298d8d8d8d8d6132b5565b90506116378d8d8d84613460565b427ff4db84547d3060691bc81cbf8face8bc35e4508017813b02cd4082996e4b82d28e8d8f8560405161169294939291906001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b60405180910390a25050825467ffffffffffffffff19164267ffffffffffffffff161790925550505050505050505050565b5f5f6116ce611a7b565b905060015481106116e0575f91505090565b806001546116ee91906148f1565b91505090565b5f5f6116fe613002565b5f611707611a7b565b5f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529293506101009091046001600160a01b0316906391d1485490604401602060405180830381865afa158015611768573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061178c91906148c2565b6117c75760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b604051630ad58d2f60e01b81527f000000000000000000000000000000000000000000000000000000000000000b6004820152602481018690523060448201527f00000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c4856001600160a01b031690630ad58d2f906064015b60408051808303815f875af1158015611857573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061187b919061494e565b90945092505f905061188b611a7b565b90505f6118a36002548461349790919063ffffffff16565b90508082818110156118d157604051633b5d56ed60e11b815260048101929092526024820152604401610ac2565b5050505050915091565b5f5f6118e5613002565b5f6118ee611a7b565b5f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529293506101009091046001600160a01b0316906391d1485490604401602060405180830381865afa15801561194f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061197391906148c2565b6119ae5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b611a026001600160a01b037f000000000000000000000000e343167631d89b6ffc58b88d6b7fb0228795491d167f00000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c485876134ab565b60405163852a56a560e01b81527f000000000000000000000000000000000000000000000000000000000000000b6004820152602481018690523060448201527f00000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c4856001600160a01b03169063852a56a59060640161183c565b5f5f611a856134fd565b60405163869da9db60e01b81527f000000000000000000000000000000000000000000000000000000000000000b60048201523060248201529091505f906001600160a01b037f00000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c485169063869da9db9060440160a060405180830381865afa158015611b12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b36919061498e565b905080606001516effffffffffffffffffffffffffffff165f03611b5a5750919050565b60405163f1568a8960e01b81527f000000000000000000000000000000000000000000000000000000000000000b60048201523060248201525f907f00000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c4856001600160a01b03169063f1568a8990604401602060405180830381865afa158015611be4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c089190614904565b60405163d5d15a1160e01b81527f000000000000000000000000000000000000000000000000000000000000000860048201529091505f906001600160a01b037f000000000000000000000000cca852bc40e560adc3b1cc58ca5b55638ce826c9169063d5d15a1190602401602060405180830381865afa158015611c8f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cb39190614904565b90508015611dc5575f611da8611cd5836b033b2e3c9fd0803ce8000000613814565b606086015160405163b0745f2b60e01b81527f000000000000000000000000000000000000000000000000000000000000000860048201526effffffffffffffffffffffffffffff909116906001600160a01b037f000000000000000000000000cca852bc40e560adc3b1cc58ca5b55638ce826c9169063b0745f2b90602401602060405180830381865afa158015611d70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d949190614904565b611da190620f424061491b565b6001613848565b9050808311611db7575f611dc1565b611dc181846148f1565b9250505b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b03167f000000000000000000000000e343167631d89b6ffc58b88d6b7fb0228795491d6001600160a01b031603611e3157611e28828561491b565b94505050505090565b611e7c7f000000000000000000000000e343167631d89b6ffc58b88d6b7fb0228795491d7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4884610bf1565b611e28908561491b565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015611ee4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f0891906148c2565b611f435760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b6001600160a01b0383165f81815260076020908152604091829020805460ff1916861515908117909155825142815291820193909352908101919091527faf11e799c0dfe70b6ee7eeeb1e99889edf753033f557a3a5568838bdc770a08b9060600160405180910390a1505050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612010573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061203491906148c2565b61206f5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b8161208d5760405163251f56a160e21b815260040160405180910390fd5b5f5b82811015612109575f8484838181106120aa576120aa614a0f565b90506020020160208101906120bf919061453d565b90506120ca8161114e565b1581906120f6576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b5061210081613893565b5060010161208f565b50505050565b5f54604051632474521560e21b81527f1a6838efa4183e08fe3607359d1259272af9d4716f65e1a7b5921f78fd5a3c6a6004820181905233602483015260609290916101009091046001600160a01b0316906391d1485490604401602060405180830381865afa158015612185573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121a991906148c2565b6121e45760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b8267ffffffffffffffff8111156121fd576121fd614556565b60405190808252806020026020018201604052801561223057816020015b606081526020019060019003908161221b5790505b5091505f5b83811015612389575f85858381811061225057612250614a0f565b90506020028101906122629190614a23565b61227090602081019061453d565b90505f86868481811061228557612285614a0f565b90506020028101906122979190614a23565b602001359050365f8888868181106122b1576122b1614a0f565b90506020028101906122c39190614a23565b6122d1906040810190614a41565b915091505f5f856001600160a01b03168585856040516122f2929190614a84565b5f6040518083038185875af1925050503d805f811461232c576040519150601f19603f3d011682016040523d82523d5f602084013e612331565b606091505b509150915081819061235757604051634ad176bb60e01b8152600401610ac2919061482b565b508089888151811061236b5761236b614a0f565b60200260200101819052505050505050508080600101915050612235565b505092915050565b5f54604051632474521560e21b81527f1a6838efa4183e08fe3607359d1259272af9d4716f65e1a7b5921f78fd5a3c6a600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612402573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242691906148c2565b6124615760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b61246a82613915565b5050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa1580156124cc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124f091906148c2565b61252b5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b6125348561114e565b859061255f5760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506125698461114e565b84906125945760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506002548290808210156125c45760405163d9a6273f60e01b815260048101929092526024820152604401610ac2565b505061a8c083111583906125ee57604051636181a74160e11b8152600401610ac291815260200190565b505f6125fa8686610e1f565b905060405180606001604052806001864261261591906148f1565b61261f91906148f1565b67ffffffffffffffff90811682528681166020808401919091526001600160801b038781166040948501525f868152600883528490208551815487850151978701518416600160801b02978616600160401b026fffffffffffffffffffffffffffffffff199091169190951617939093171693909317905580514281526001600160a01b03898116938201939093529187169082015260608101859052608081018490527f71b3fdccb5911c1fc5f03ba3225fe0f1550be29e3b2fb7a661189fef40eed24a9060a00161113e565b5f54604051632474521560e21b81527ffcb9fcbfa83b897fb2d5cf4b58962164105c1e71489a37ef3ae0db3fdce576f6600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa15801561275e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061278291906148c2565b6127bd5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b610e1c61397a565b60606127cf613002565b84845f6127dc8383610e1f565b5f81815260086020526040902080549192509061280c9067ffffffffffffffff600160401b82048116911661492e565b67ffffffffffffffff16421161283557604051635ab1f4a960e01b815260040160405180910390fd5b6002548154600160801b90046001600160801b0316908082101561287d5760405163d9a6273f60e01b81526001600160801b0390921660048301526024820152604401610ac2565b50508888806001600160a01b0316826001600160a01b0316141581906128c25760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506128cc8261114e565b82906128f75760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506129018161114e565b819061292c5760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b505f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa15801561298b573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129af91906148c2565b6129ea5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b8980612a0c57604051636450874f60e11b8152600401610ac291815260200190565b506040516370a0823160e01b81523060048201526001600160a01b038d16906370a0823190602401602060405180830381865afa158015612a4f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a739190614904565b8a11158a90612a9857604051636450874f60e11b8152600401610ac291815260200190565b505f612aa48d8d612c78565b604001516001600160801b031690505f6040518060a001604052808f6001600160a01b031681526020018e6001600160a01b031681526020018d81526020018c8152602001838152509050612af8816139b6565b865467ffffffffffffffff19164267ffffffffffffffff161790965550939c9b505050505050505050505050565b5f54604051632474521560e21b81527f5f33620cda06d02d58df96005b92bc83bd059a566e48e016372f3fbdc974e371600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612b97573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bbb91906148c2565b612bf65760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b612bfe613002565b5f612c07611a7b565b9050600154811115612c3a5760015460405163f480e28560e01b8152610ac2918391600401918252602082015260400190565b60408051428152602081018390529081018290527f35a901c4413e585f9121eb5cf07e67760bd4ac498dd031249e5cd2cd225f74e490606001610f82565b604080516060810182525f8082526020820181905291810182905290612c9e8484610e1f565b5f908152600860209081526040918290208251606081018452905467ffffffffffffffff8082168352600160401b82041692820192909252600160801b9091046001600160801b031691810191909152949350505050565b612cfe613002565b5f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612d5c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d8091906148c2565b612dbb5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b6003546001600160a01b031680612de55760405163072e9ae360e31b815260040160405180910390fd5b5f612dee611a7b565b90505f826001600160a01b031685604051612e099190614a93565b5f604051808303815f865af19150503d805f8114612e42576040519150601f19603f3d011682016040523d82523d5f602084013e612e47565b606091505b5050905080612e69576040516377f92a5360e11b815260040160405180910390fd5b5f612e72611a7b565b905082811015612e9557604051633892029d60e11b815260040160405180910390fd5b427fc83b5086ce94ec8d5a88a9f5fea4b18a522bb238ed0d2d8abd959549a80c16b8612ec185846148f1565b60405190815260200160405180910390a2505050505050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612f38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f5c91906148c2565b612f975760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b81612fb55760405163251f56a160e21b815260040160405180910390fd5b5f5b8281101561210957612fee848483818110612fd457612fd4614a0f565b9050602002016020810190612fe9919061453d565b613a6a565b600101612fb7565b6060610bc16004613c6e565b5f5460ff16156130255760405163d93c066560e01b815260040160405180910390fd5b565b61246a6001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481682846130c7565b5f825f19048411830215820261306f575f5ffd5b5091020490565b61307e613c7a565b5f805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6130d48383836001613c9c565b6130fc57604051635274afe760e01b81526001600160a01b0384166004820152602401610ac2565b505050565b6001600160a01b0381165f9081526001830160205260408120541515610d3d565b6040516315d5220f60e31b81526001600160a01b0382811660048301525f917f0000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b39091169063aea9107890602401602060405180830381865afa9250505080156131a8575060408051601f3d908101601f191682019092526131a591810190614904565b60015b6131b357505f919050565b151592915050565b919050565b6001600160a01b0381165f90815260076020526040902054819060ff166132065760405163a58f313b60e01b81526001600160a01b039091166004820152602401610ac2565b50818061322957604051636450874f60e11b8152600401610ac291815260200190565b506040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa15801561326c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132909190614904565b821115829061210957604051636450874f60e11b8152600401610ac291815260200190565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038716906370a0823190602401602060405180830381865afa1580156132fb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061331f9190614904565b90506133356001600160a01b03881685876134ab565b5f5f856001600160a01b03168560405161334f9190614a93565b5f604051808303815f865af19150503d805f8114613388576040519150601f19603f3d011682016040523d82523d5f602084013e61338d565b606091505b50915091508181906133cc576040517fff9fa595000000000000000000000000000000000000000000000000000000008152600401610ac2919061482b565b506133e16001600160a01b038a16875f6134ab565b6040516370a0823160e01b815230600482015283906001600160a01b038a16906370a0823190602401602060405180830381865afa158015613425573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134499190614904565b61345391906148f1565b9998505050505050505050565b5f8180613489576040516378e9a2e760e01b815260048101929092526024820152604401610ac2565b505061210984848484613cfe565b5f610d3d8383670de0b6b3a764000061305b565b6134b78383835f613d66565b6130fc576134c883835f6001613d66565b6134f057604051635274afe760e01b81526001600160a01b0384166004820152602401610ac2565b6130d48383836001613d66565b6040516370a0823160e01b81523060048201525f9081906001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a0823190602401602060405180830381865afa158015613563573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135879190614904565b6040516315d5220f60e31b81526001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48811660048301529192505f917f0000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b3169063aea9107890602401602060405180830381865afa158015613610573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136349190614904565b90505f61363f612ff6565b90505f5b815181101561380b577f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031682828151811061368857613688614a0f565b60200260200101516001600160a01b03160315613803575f8282815181106136b2576136b2614a0f565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015613700573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137249190614904565b9050805f036137335750613803565b5f7f0000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b36001600160a01b031663aea9107885858151811061377557613775614a0f565b60200260200101516040518263ffffffff1660e01b81526004016137a891906001600160a01b0391909116815260200190565b602060405180830381865afa1580156137c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137e79190614904565b90506137f482828761305b565b6137fe908761491b565b955050505b600101613643565b50919392505050565b5f815f03613826576138266012613db0565b81600184038161383857613838614aa9565b046001018315155b029392505050565b5f61387561385583613dc1565b801561387057505f848061386b5761386b614aa9565b868809115b151590565b613880868686613ded565b61388a919061491b565b95945050505050565b61389c81613122565b81906138c757604051631f93601760e01b81526001600160a01b039091166004820152602401610ac2565b506138d3600482613e9d565b506040516001600160a01b038216815242907faa5546990a389e40b77b177c187d29e7a10fcba5151f6872026b18dd6acd57719060200160405180910390a250565b5f80546001600160a01b0383811661010081810274ffffffffffffffffffffffffffffffffffffffff0019851617855560405193049190911692909183917f9209b7c8c06dcfd261686a663e7c55989337b18d59da5433c6f2835fb697092091a35050565b613982613002565b5f805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586130aa3390565b60607f000000000000000000000000000000000000000000000000000000000000000015613a12576104b06006546139ee919061491b565b4211613a0d57604051635ab1f4a960e01b815260040160405180910390fd5b426006555b613a1b82613eb1565b60408201518251613a59916001600160a01b03909116907f000000000000000000000000c92e8bdf79f0507f65a392b0ab4667716bfe0110906134ab565b610e8e613a6583613f03565b614075565b7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b0316816001600160a01b031614158190613acb576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b50613ad58161114e565b8190613b00576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b506040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015613b45573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b699190614904565b90505f826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ba8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bcc9190614abd565b60ff169050613bdc81600a614bb8565b613be7906001614bc3565b82111583839091613c1c5760405163327f32bd60e11b81526001600160a01b0390921660048301526024820152604401610ac2565b50613c2a9050600484614230565b506040516001600160a01b038416815242907f36c12b9b4d20f73189838a9c40ee0af4582f9431846c881b42cfd809eeca78b39060200160405180910390a2505050565b60605f610d3d83614244565b5f5460ff1661302557604051638dfc202b60e01b815260040160405180910390fd5b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613cf2578383151615613ce6573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f613d098585612c78565b604001516001600160801b031690505f613d2e82613d28888888610bf1565b90613497565b9050808381811015613d5c57604051633b5d56ed60e11b815260048101929092526024820152604401610ac2565b5050505050505050565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613cf2578383151615613ce6573d5f823e3d81fd5b634e487b715f52806020526024601cfd5b5f6002826003811115613dd657613dd6614bda565b613de09190614bee565b60ff166001149050919050565b5f5f5f613dfa868661429d565b91509150815f03613e1e57838181613e1457613e14614aa9565b0492505050610d3d565b818411613e3557613e356003851502601118613db0565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f610d3d836001600160a01b0384166142b9565b5f613ed08260800151613d28845f015185602001518660400151610bf1565b6060830151909150819081811161210957604051633b5d56ed60e11b815260048101929092526024820152604401610ac2565b613f7e6040518061018001604052805f6001600160a01b031681526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f63ffffffff1681526020015f81526020015f81526020015f81526020015f151581526020015f81526020015f81525090565b604051806101800160405280835f01516001600160a01b0316815260200183602001516001600160a01b03168152602001306001600160a01b0316815260200183604001518152602001836060015181526020016104b042613fe0919061491b565b63ffffffff1681527f3cac71ef99d0dfbf5b937334b5b7ab672b679ba2bbd4d6fe8e0c54a2dab3110960208201525f604082018190527ff3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee346775606083015260808201527f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc960a0820181905260c09091015292915050565b60605f7f0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4190505f61415184836001600160a01b031663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156140dc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141009190614904565b601f1990910180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a08220915260405161190160f01b8152600281019290925260228201526042902090565b604080516038808252606082019092529192505f91906020820181803683370190505090506141868183308860a00151614305565b60405163ec6cb13f60e01b81526001600160a01b0384169063ec6cb13f906141b5908490600190600401614c1b565b5f604051808303815f87803b1580156141cc575f5ffd5b505af11580156141de573d5f5f3e3d5ffd5b50505050427f63521d767ee2dda07d9815cec18770071f08ed7902feacb2cb193196bb8e9aad82878860a0015189608001516040516142209493929190614c3e565b60405180910390a2949350505050565b5f610d3d836001600160a01b038416614368565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561429157602002820191905f5260205f20905b81548152602001906001019080831161427d575b50505050509050919050565b5f805f1983850993909202808410938190039390930393915050565b5f8181526001830160205260408120546142fe57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610e8e565b505f610e8e565b60388451146143565760405162461bcd60e51b815260206004820152601960248201527f475076323a2075696420627566666572206f766572666c6f77000000000000006044820152606401610ac2565b60388401526034830152602090910152565b5f8181526001830160205260408120548015614442575f61438a6001836148f1565b85549091505f9061439d906001906148f1565b90508082146143fc575f865f0182815481106143bb576143bb614a0f565b905f5260205f200154905080875f0184815481106143db576143db614a0f565b5f918252602080832090910192909255918252600188019052604090208390555b855486908061440d5761440d614d2c565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610e8e565b5f915050610e8e565b80356001600160a01b03811681146131bb575f5ffd5b5f5f60408385031215614472575f5ffd5b823591506144826020840161444b565b90509250929050565b5f5f5f6060848603121561449d575f5ffd5b6144a68461444b565b92506144b46020850161444b565b929592945050506040919091013590565b5f5f604083850312156144d6575f5ffd5b6144df8361444b565b91506144826020840161444b565b5f602082840312156144fd575f5ffd5b5035919050565b5f5f5f60608486031215614516575f5ffd5b61451f8461444b565b9250602084013591506145346040850161444b565b90509250925092565b5f6020828403121561454d575f5ffd5b610d3d8261444b565b634e487b7160e01b5f52604160045260245ffd5b60405160a0810167ffffffffffffffff8111828210171561458d5761458d614556565b60405290565b5f82601f8301126145a2575f5ffd5b813567ffffffffffffffff8111156145bc576145bc614556565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156145eb576145eb614556565b604052818152838201602001851015614602575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f60a08688031215614632575f5ffd5b61463b8661444b565b94506146496020870161444b565b93506040860135925061465e6060870161444b565b9150608086013567ffffffffffffffff811115614679575f5ffd5b61468588828901614593565b9150509295509295909350565b8015158114610e1c575f5ffd5b5f5f604083850312156146b0575f5ffd5b6146b98361444b565b915060208301356146c981614692565b809150509250929050565b5f5f83601f8401126146e4575f5ffd5b50813567ffffffffffffffff8111156146fb575f5ffd5b6020830191508360208260051b8501011115614715575f5ffd5b9250929050565b5f5f6020838503121561472d575f5ffd5b823567ffffffffffffffff811115614743575f5ffd5b61474f858286016146d4565b90969095509350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156147e057603f198786030184526147cb85835161475b565b945060209384019391909101906001016147af565b50929695505050505050565b5f5f5f5f608085870312156147ff575f5ffd5b6148088561444b565b93506148166020860161444b565b93969395505050506040820135916060013590565b602081525f610d3d602083018461475b565b5f6020828403121561484d575f5ffd5b813567ffffffffffffffff811115614863575f5ffd5b61486f84828501614593565b949350505050565b602080825282518282018190525f918401906040840190835b818110156148b75783516001600160a01b0316835260209384019390920191600101614890565b509095945050505050565b5f602082840312156148d2575f5ffd5b8151610d3d81614692565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610e8e57610e8e6148dd565b5f60208284031215614914575f5ffd5b5051919050565b80820180821115610e8e57610e8e6148dd565b67ffffffffffffffff8181168382160190811115610e8e57610e8e6148dd565b5f5f6040838503121561495f575f5ffd5b505080516020909101519092909150565b80516effffffffffffffffffffffffffffff811681146131bb575f5ffd5b5f60a082840312801561499f575f5ffd5b506149a861456a565b6149b183614970565b81526149bf60208401614970565b602082015260408301518060180b81146149d7575f5ffd5b60408201526149e860608401614970565b6060820152608083015163ffffffff81168114614a03575f5ffd5b60808201529392505050565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614a37575f5ffd5b9190910192915050565b5f5f8335601e19843603018112614a56575f5ffd5b83018035915067ffffffffffffffff821115614a70575f5ffd5b602001915036819003821315614715575f5ffd5b818382375f9101908152919050565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52601260045260245ffd5b5f60208284031215614acd575f5ffd5b815160ff81168114610d3d575f5ffd5b6001815b6001841115614b1857808504811115614afc57614afc6148dd565b6001841615614b0a57908102905b60019390931c928002614ae1565b935093915050565b5f82614b2e57506001610e8e565b81614b3a57505f610e8e565b8160018114614b505760028114614b5a57614b76565b6001915050610e8e565b60ff841115614b6b57614b6b6148dd565b50506001821b610e8e565b5060208310610133831016604e8410600b8410161715614b99575081810a610e8e565b614ba55f198484614add565b805f1904821115613840576138406148dd565b5f610d3d8383614b20565b8082028115828204841417610e8e57610e8e6148dd565b634e487b7160e01b5f52602160045260245ffd5b5f60ff831680614c0c57634e487b7160e01b5f52601260045260245ffd5b8060ff84160691505092915050565b604081525f614c2d604083018561475b565b905082151560208301529392505050565b6101e081525f614c526101e083018761475b565b85516001600160a01b03166020840152905060208501516001600160a01b03811660408401525060408501516001600160a01b03811660608401525060608501516080830152608085015160a083015260a0850151614cb960c084018263ffffffff169052565b5060c085015160e083015260e0850151610100830152610100850151610120830152610120850151614cf061014084018215159052565b50610140850151610160830152610160850151610180830152614d1c6101a083018563ffffffff169052565b826101c083015295945050505050565b634e487b7160e01b5f52603160045260245ffdfe456cfaf8d1ec98ae5bbe595a448911a58cb2e264d4686992e15dec9d0f363e033947e2f542c6c46c543fa4f79cbd1e27fea37ed249bc3caf992570d19123642ea26469706673582212202f27f2d47a7f717a132515e634abfdc6bdbdf6d27ce68cbdd472d62af5b6dfc964736f6c634300081c0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"enabled":true,"runs":400},"remappings":["@openzeppelin/=lib/openzeppelin-contracts/","@forge-std/=lib/forge-std/src/","@solmate/=lib/solmate/","@cowprotocol/=lib/cowprotocol/src/","@core/=src/core/","@tokens/=src/tokens/","@locking/=src/locking/","@funding/=src/funding/","@gateway/=src/gateway/","@finance/=src/finance/","@periphery/=src/periphery/","@libraries/=src/libraries/","@interfaces/=src/interfaces/","@governance/=src/governance/","@integrations/=src/integrations/","@test/=test/","@deployment/=deployment/","@pendle/=lib/pendle-core-v2-public/contracts/","@chainlink/=lib/chainlink-ccip/chains/evm/","@chainlink/local/=lib/chainlink-local/","@layerzerolabs/lz-evm-protocol-v2/=lib/LayerZero-v2/packages/layerzero-v2/evm/protocol/","@layerzerolabs/lz-evm-oapp-v2/=lib/LayerZero-v2/packages/layerzero-v2/evm/oapp/","@layerzerolabs/lz-evm-messagelib-v2/=lib/LayerZero-v2/packages/layerzero-v2/evm/messagelib/","solidity-bytes-utils/=lib/solidity-bytes-utils/","LayerZero-devtools/=lib/LayerZero-devtools/","LayerZero-v2/=lib/LayerZero-v2/","chainlink-ccip/=lib/chainlink-ccip/chains/evm/contracts/vendor/optimism/interop-lib/v0/src/","cowprotocol/=lib/cowprotocol/src/","ds-test/=lib/solmate/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/","pendle-core-v2-public/=lib/pendle-core-v2-public/contracts/","solmate/=lib/solmate/src/"],"viaIR":false},"optimization_runs":400,"sourcify_repo_url":null,"decoded_constructor_args":[["0xF6d48735EcCf12bDC1DF2674b1ce3fcb3bD25490",{"internalType":"address","name":"_core","type":"address"}],["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",{"internalType":"address","name":"_assetToken","type":"address"}],["0x7A5C5dbA4fbD0e1e1A2eCDBe752fAe55f6E842B3",{"internalType":"address","name":"_accounting","type":"address"}],["0x9008D19f58AAbD9eD0D60971565AA8510560ab41",{"internalType":"address","name":"_settlementContract","type":"address"}],["0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",{"internalType":"address","name":"_vaultRelayer","type":"address"}],["604800",{"internalType":"uint256","name":"_duration","type":"uint256"}],["0x94e7A5dCbE816e498b89aB752661904E2F56c485",{"internalType":"address","name":"_spoke","type":"address"}],["11",{"internalType":"uint256","name":"_reserveId","type":"uint256"}]],"compiler_version":"0.8.28+commit.7893614a","is_verified_via_verifier_alliance":true,"verified_at":"2026-06-11T15:12:35.428726Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x6101e06040526001600655348015610015575f5ffd5b5060405161538b38038061538b833981016040819052610034916102c8565b5f8054610100600160a81b0319166101006001600160a01b038b811682029290921783558982166080525f1960015588821660a05287821660e052868216905260c0829052670dcef33a6f83800060025561012085905283166101408190526101608390526040516377778db360e01b8152600481018490526377778db39060240160e060405180830381865afa1580156100d1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100f59190610395565b80516001600160a01b03908116610180819052602083015182166101a052604083015161ffff166101c052919250891614610137576101805161013790610145565b505050505050505050610467565b61014e816101cb565b819061017d57604051631f93601760e01b81526001600160a01b03909116600482015260240160405180910390fd5b50610189600482610249565b506040516001600160a01b038216815242907faa5546990a389e40b77b177c187d29e7a10fcba5151f6872026b18dd6acd57719060200160405180910390a250565b60a0516040516315d5220f60e31b81526001600160a01b0383811660048301525f92169063aea9107890602401602060405180830381865afa925050508015610231575060408051601f3d908101601f1916820190925261022e91810190610450565b60015b61023c57505f919050565b151592915050565b919050565b5f61025d836001600160a01b038416610266565b90505b92915050565b5f8181526001830160205260408120546102ab57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610260565b505f610260565b80516001600160a01b0381168114610244575f5ffd5b5f5f5f5f5f5f5f5f610100898b0312156102e0575f5ffd5b6102e9896102b2565b97506102f760208a016102b2565b965061030560408a016102b2565b955061031360608a016102b2565b945061032160808a016102b2565b60a08a0151909450925061033760c08a016102b2565b60e09990990151979a96995094979396929591945050565b805161ffff81168114610244575f5ffd5b805160ff81168114610244575f5ffd5b805162ffffff81168114610244575f5ffd5b805163ffffffff81168114610244575f5ffd5b5f60e08284031280156103a6575f5ffd5b5060405160e081016001600160401b03811182821017156103d557634e487b7160e01b5f52604160045260245ffd5b6040526103e1836102b2565b81526103ef602084016102b2565b60208201526104006040840161034f565b604082015261041160608401610360565b606082015261042260808401610370565b608082015261043360a08401610360565b60a082015261044460c08401610382565b60c08201529392505050565b5f60208284031215610460575f5ffd5b5051919050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c051614db66105d55f395f818161082001528181611c170152611ce901525f818161047701528181611c4a0152611d2b01525f8181610343015281816119bb01528181611df10152611e3601525f81816109b3015281816117d601528181611a1101528181611a940152611b6901525f818161057e01528181611809015281816119dd01528181611a4401528181611acd0152611b9701525f81816103b50152610bcc01525f81816107ed0152613a3401525f8181610980015261407a01525f81816108ee01526139ba01525f81816107ba01528181610c3301528181610cc201528181613143015281816135cb015261373601525f81816103e801528181610b50015281816110780152818161115101528181611dc701528181611e57015281816130340152818161351e0152818161359e0152818161364e0152613a6c0152614db65ff3fe60806040526004361061030d575f3560e01c806368fd2d801161019c5780639624e83e116100e7578063e0ffcd2111610092578063e9607c011161006d578063e9607c011461094e578063ea42418b1461096f578063ea8d1f0a146109a2578063f2f4eb26146109d5575f5ffd5b8063e0ffcd21146108dd578063e190febc14610910578063e625ad341461092f575f5ffd5b8063c23544ad116100c2578063c23544ad14610842578063d0e30db014610870578063d7ed262314610884575f5ffd5b80639624e83e146107a95780639b552cc2146107dc578063aabed5e51461080f575f5ffd5b80637df3927e116101475780638456cb59116101225780638456cb59146107545780638c04166f146107685780639387e6731461077d575f5ffd5b80637df3927e146106f657806380009630146107165780638417abc414610735575f5ffd5b8063761a1ea311610177578063761a1ea3146106a35780637b96eef1146106b85780637d38f07c146106d7575f5ffd5b806368fd2d80146106515780636ea69d621461067057806371a973051461068f575f5ffd5b8063439950811161025c57806351508f0a116102075780636083e59a116101e25780636083e59a146105f45780636863775f14610608578063688f237b1461061d575f5ffd5b806351508f0a146105a057806353770b53146105bf5780635c975abb146105de575f5ffd5b8063464b415811610237578063464b41581461051f57806347786d371461054e57806347bfbcc61461056d575f5ffd5b806343995081146104c257806343f68a49146104e15780634615707714610500575f5ffd5b8063204f83f9116102bc578063365a86fc11610297578063365a86fc146104665780633f4ba83a146104995780633ffb788e146104ad575f5ffd5b8063204f83f91461041e578063248391ff14610432578063355274ea14610451575f5ffd5b80630fb5a6b4116102ec5780630fb5a6b4146103a45780631083f761146103d75780631a6865021461040a575f5ffd5b8062f714ce14610311578063044007321461033257806306952f1e14610382575b5f5ffd5b34801561031c575f5ffd5b5061033061032b366004614461565b6109f6565b005b34801561033d575f5ffd5b506103657f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561038d575f5ffd5b50610396600181565b604051908152602001610379565b3480156103af575f5ffd5b506103967f000000000000000000000000000000000000000000000000000000000000000081565b3480156103e2575f5ffd5b506103657f000000000000000000000000000000000000000000000000000000000000000081565b348015610415575f5ffd5b50610396610b39565b348015610429575f5ffd5b50610396610bc6565b34801561043d575f5ffd5b5061039661044c36600461448b565b610bf1565b34801561045c575f5ffd5b5061039660015481565b348015610471575f5ffd5b506103657f000000000000000000000000000000000000000000000000000000000000000081565b3480156104a4575f5ffd5b50610330610d44565b3480156104b8575f5ffd5b506103966104b081565b3480156104cd575f5ffd5b506103966104dc3660046144c5565b610e1f565b3480156104ec575f5ffd5b506103306104fb3660046144ed565b610e94565b34801561050b575f5ffd5b5061033061051a366004614504565b610f8e565b34801561052a575f5ffd5b5061053e61053936600461453d565b61114e565b6040519015158152602001610379565b348015610559575f5ffd5b506103306105683660046144ed565b6111a5565b348015610578575f5ffd5b506103657f000000000000000000000000000000000000000000000000000000000000000081565b3480156105ab575f5ffd5b506103306105ba36600461453d565b611297565b3480156105ca575f5ffd5b506103306105d936600461461e565b6113ed565b3480156105e9575f5ffd5b505f5460ff1661053e565b3480156105ff575f5ffd5b506103966116c4565b348015610613575f5ffd5b5061039661a8c081565b348015610628575f5ffd5b5061063c6106373660046144ed565b6116f4565b60408051928352602083019190915201610379565b34801561065c575f5ffd5b5061063c61066b3660046144ed565b6118db565b34801561067b575f5ffd5b50600354610365906001600160a01b031681565b34801561069a575f5ffd5b50610396611a7b565b3480156106ae575f5ffd5b5061039660065481565b3480156106c3575f5ffd5b506103306106d236600461469f565b611e86565b3480156106e2575f5ffd5b506103306106f136600461471c565b611fb2565b61070961070436600461471c565b61210f565b6040516103799190614789565b348015610721575f5ffd5b5061033061073036600461453d565b612391565b348015610740575f5ffd5b5061033061074f3660046147ec565b61246e565b34801561075f575f5ffd5b506103306126ed565b348015610773575f5ffd5b5061039660025481565b348015610788575f5ffd5b5061079c6107973660046147ec565b6127c5565b604051610379919061482b565b3480156107b4575f5ffd5b506103657f000000000000000000000000000000000000000000000000000000000000000081565b3480156107e7575f5ffd5b506103657f000000000000000000000000000000000000000000000000000000000000000081565b34801561081a575f5ffd5b506103967f000000000000000000000000000000000000000000000000000000000000000081565b34801561084d575f5ffd5b5061053e61085c36600461453d565b60076020525f908152604090205460ff1681565b34801561087b575f5ffd5b50610330612b26565b34801561088f575f5ffd5b506108a361089e3660046144c5565b612c78565b60408051825167ffffffffffffffff908116825260208085015190911690820152918101516001600160801b031690820152606001610379565b3480156108e8575f5ffd5b5061053e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561091b575f5ffd5b5061033061092a36600461483d565b612cf6565b34801561093a575f5ffd5b5061033061094936600461471c565b612eda565b348015610959575f5ffd5b50610962612ff6565b6040516103799190614877565b34801561097a575f5ffd5b506103657f000000000000000000000000000000000000000000000000000000000000000081565b3480156109ad575f5ffd5b506103967f000000000000000000000000000000000000000000000000000000000000000081565b3480156109e0575f5ffd5b505f5461010090046001600160a01b0316610365565b5f54604051632474521560e21b81527f5f33620cda06d02d58df96005b92bc83bd059a566e48e016372f3fbdc974e371600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610a67573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a8b91906148c2565b610acb5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b610ad3613002565b5f610adc611a7b565b9050610ae88484613027565b7f35a901c4413e585f9121eb5cf07e67760bd4ac498dd031249e5cd2cd225f74e44282610b1587826148f1565b6040805193845260208401929092529082015260600160405180910390a150505050565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b9d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bc19190614904565b905090565b5f610bc17f00000000000000000000000000000000000000000000000000000000000000004261491b565b5f826001600160a01b0316846001600160a01b031603610c12575080610d3d565b6040516315d5220f60e31b81526001600160a01b0385811660048301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063aea9107890602401602060405180830381865afa158015610c7a573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9e9190614904565b6040516315d5220f60e31b81526001600160a01b0386811660048301529192505f917f0000000000000000000000000000000000000000000000000000000000000000169063aea9107890602401602060405180830381865afa158015610d07573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d2b9190614904565b9050610d3884838361305b565b925050505b9392505050565b5f54604051632474521560e21b81527fe7276a2a84d8de556657ec9cf93a55a7d66f096e529d0582ed08e9e2208b92b5600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610db5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dd991906148c2565b610e145760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b610e1c613076565b50565b5f5f5f836001600160a01b0316856001600160a01b031611610e42578385610e45565b84845b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b166034820152919350915060480160405160208183030381529060405280519060200120925050505b92915050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610ef2573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1691906148c2565b610f515760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b60028290556040518281527f9c922f6d0c990b250e9dd0a427a5c8da7f44b960f697fecb31cbbd8ba79ec8c2906020015b60405180910390a15050565b5f54604051632474521560e21b81527f5f33620cda06d02d58df96005b92bc83bd059a566e48e016372f3fbdc974e371600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015610fff573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102391906148c2565b61105e5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b611066613002565b61106f8461114e565b80156110ad57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614155b84906110d8576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b505f6110e2611a7b565b90506110f86001600160a01b03861684866130c7565b5f611101611a7b565b60408051428152602081018590529081018290529091507f35a901c4413e585f9121eb5cf07e67760bd4ac498dd031249e5cd2cd225f74e4906060015b60405180910390a1505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480610e8e5750611195600483613101565b8015610e8e5750610e8e82613122565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015611203573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122791906148c2565b6112625760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b60018290556040518281527f3c8eb7c49d332f4c1e4d92a27cda93c31cc9452f7a408e0c6109fcddbc9946ea90602001610f82565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa1580156112f5573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131991906148c2565b6113545760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b816001600160a01b03811661138857604051633202e20d60e21b81526001600160a01b039091166004820152602401610ac2565b506003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03841690811790915560405190815242907fb9e8010e984929bdc235316d2fb8ed6c6b467a403c55770ee0f63f22dba991bc9060200160405180910390a25050565b6113f5613002565b84845f6114028383610e1f565b5f8181526008602052604090208054919250906114329067ffffffffffffffff600160401b82048116911661492e565b67ffffffffffffffff16421161145b57604051635ab1f4a960e01b815260040160405180910390fd5b6002548154600160801b90046001600160801b031690808210156114a35760405163d9a6273f60e01b81526001600160801b0390921660048301526024820152604401610ac2565b50508888806001600160a01b0316826001600160a01b0316141581906114e85760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506114f28261114e565b829061151d5760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506115278161114e565b81906115525760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b505f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa1580156115b1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115d591906148c2565b6116105760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b61161b8c8b8b6131c0565b5f6116298d8d8d8d8d6132b5565b90506116378d8d8d84613460565b427ff4db84547d3060691bc81cbf8face8bc35e4508017813b02cd4082996e4b82d28e8d8f8560405161169294939291906001600160a01b039485168152602081019390935292166040820152606081019190915260800190565b60405180910390a25050825467ffffffffffffffff19164267ffffffffffffffff161790925550505050505050505050565b5f5f6116ce611a7b565b905060015481106116e0575f91505090565b806001546116ee91906148f1565b91505090565b5f5f6116fe613002565b5f611707611a7b565b5f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529293506101009091046001600160a01b0316906391d1485490604401602060405180830381865afa158015611768573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061178c91906148c2565b6117c75760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b604051630ad58d2f60e01b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018690523060448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630ad58d2f906064015b60408051808303815f875af1158015611857573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061187b919061494e565b90945092505f905061188b611a7b565b90505f6118a36002548461349790919063ffffffff16565b90508082818110156118d157604051633b5d56ed60e11b815260048101929092526024820152604401610ac2565b5050505050915091565b5f5f6118e5613002565b5f6118ee611a7b565b5f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529293506101009091046001600160a01b0316906391d1485490604401602060405180830381865afa15801561194f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061197391906148c2565b6119ae5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b611a026001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000876134ab565b60405163852a56a560e01b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018690523060448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063852a56a59060640161183c565b5f5f611a856134fd565b60405163869da9db60e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201523060248201529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063869da9db9060440160a060405180830381865afa158015611b12573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b36919061498e565b905080606001516effffffffffffffffffffffffffffff165f03611b5a5750919050565b60405163f1568a8960e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201523060248201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f1568a8990604401602060405180830381865afa158015611be4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c089190614904565b60405163d5d15a1160e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d5d15a1190602401602060405180830381865afa158015611c8f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cb39190614904565b90508015611dc5575f611da8611cd5836b033b2e3c9fd0803ce8000000613814565b606086015160405163b0745f2b60e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201526effffffffffffffffffffffffffffff909116906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b0745f2b90602401602060405180830381865afa158015611d70573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d949190614904565b611da190620f424061491b565b6001613848565b9050808311611db7575f611dc1565b611dc181846148f1565b9250505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603611e3157611e28828561491b565b94505050505090565b611e7c7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084610bf1565b611e28908561491b565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015611ee4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f0891906148c2565b611f435760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b6001600160a01b0383165f81815260076020908152604091829020805460ff1916861515908117909155825142815291820193909352908101919091527faf11e799c0dfe70b6ee7eeeb1e99889edf753033f557a3a5568838bdc770a08b9060600160405180910390a1505050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612010573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061203491906148c2565b61206f5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b8161208d5760405163251f56a160e21b815260040160405180910390fd5b5f5b82811015612109575f8484838181106120aa576120aa614a0f565b90506020020160208101906120bf919061453d565b90506120ca8161114e565b1581906120f6576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b5061210081613893565b5060010161208f565b50505050565b5f54604051632474521560e21b81527f1a6838efa4183e08fe3607359d1259272af9d4716f65e1a7b5921f78fd5a3c6a6004820181905233602483015260609290916101009091046001600160a01b0316906391d1485490604401602060405180830381865afa158015612185573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121a991906148c2565b6121e45760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b8267ffffffffffffffff8111156121fd576121fd614556565b60405190808252806020026020018201604052801561223057816020015b606081526020019060019003908161221b5790505b5091505f5b83811015612389575f85858381811061225057612250614a0f565b90506020028101906122629190614a23565b61227090602081019061453d565b90505f86868481811061228557612285614a0f565b90506020028101906122979190614a23565b602001359050365f8888868181106122b1576122b1614a0f565b90506020028101906122c39190614a23565b6122d1906040810190614a41565b915091505f5f856001600160a01b03168585856040516122f2929190614a84565b5f6040518083038185875af1925050503d805f811461232c576040519150601f19603f3d011682016040523d82523d5f602084013e612331565b606091505b509150915081819061235757604051634ad176bb60e01b8152600401610ac2919061482b565b508089888151811061236b5761236b614a0f565b60200260200101819052505050505050508080600101915050612235565b505092915050565b5f54604051632474521560e21b81527f1a6838efa4183e08fe3607359d1259272af9d4716f65e1a7b5921f78fd5a3c6a600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612402573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061242691906148c2565b6124615760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b61246a82613915565b5050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa1580156124cc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124f091906148c2565b61252b5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b6125348561114e565b859061255f5760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506125698461114e565b84906125945760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506002548290808210156125c45760405163d9a6273f60e01b815260048101929092526024820152604401610ac2565b505061a8c083111583906125ee57604051636181a74160e11b8152600401610ac291815260200190565b505f6125fa8686610e1f565b905060405180606001604052806001864261261591906148f1565b61261f91906148f1565b67ffffffffffffffff90811682528681166020808401919091526001600160801b038781166040948501525f868152600883528490208551815487850151978701518416600160801b02978616600160401b026fffffffffffffffffffffffffffffffff199091169190951617939093171693909317905580514281526001600160a01b03898116938201939093529187169082015260608101859052608081018490527f71b3fdccb5911c1fc5f03ba3225fe0f1550be29e3b2fb7a661189fef40eed24a9060a00161113e565b5f54604051632474521560e21b81527ffcb9fcbfa83b897fb2d5cf4b58962164105c1e71489a37ef3ae0db3fdce576f6600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa15801561275e573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061278291906148c2565b6127bd5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b610e1c61397a565b60606127cf613002565b84845f6127dc8383610e1f565b5f81815260086020526040902080549192509061280c9067ffffffffffffffff600160401b82048116911661492e565b67ffffffffffffffff16421161283557604051635ab1f4a960e01b815260040160405180910390fd5b6002548154600160801b90046001600160801b0316908082101561287d5760405163d9a6273f60e01b81526001600160801b0390921660048301526024820152604401610ac2565b50508888806001600160a01b0316826001600160a01b0316141581906128c25760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506128cc8261114e565b82906128f75760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b506129018161114e565b819061292c5760405163961c9a4f60e01b81526001600160a01b039091166004820152602401610ac2565b505f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa15801561298b573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129af91906148c2565b6129ea5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b8980612a0c57604051636450874f60e11b8152600401610ac291815260200190565b506040516370a0823160e01b81523060048201526001600160a01b038d16906370a0823190602401602060405180830381865afa158015612a4f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a739190614904565b8a11158a90612a9857604051636450874f60e11b8152600401610ac291815260200190565b505f612aa48d8d612c78565b604001516001600160801b031690505f6040518060a001604052808f6001600160a01b031681526020018e6001600160a01b031681526020018d81526020018c8152602001838152509050612af8816139b6565b865467ffffffffffffffff19164267ffffffffffffffff161790965550939c9b505050505050505050505050565b5f54604051632474521560e21b81527f5f33620cda06d02d58df96005b92bc83bd059a566e48e016372f3fbdc974e371600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612b97573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bbb91906148c2565b612bf65760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b612bfe613002565b5f612c07611a7b565b9050600154811115612c3a5760015460405163f480e28560e01b8152610ac2918391600401918252602082015260400190565b60408051428152602081018390529081018290527f35a901c4413e585f9121eb5cf07e67760bd4ac498dd031249e5cd2cd225f74e490606001610f82565b604080516060810182525f8082526020820181905291810182905290612c9e8484610e1f565b5f908152600860209081526040918290208251606081018452905467ffffffffffffffff8082168352600160401b82041692820192909252600160801b9091046001600160801b031691810191909152949350505050565b612cfe613002565b5f54604051632474521560e21b81525f516020614d415f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612d5c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d8091906148c2565b612dbb5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b6003546001600160a01b031680612de55760405163072e9ae360e31b815260040160405180910390fd5b5f612dee611a7b565b90505f826001600160a01b031685604051612e099190614a93565b5f604051808303815f865af19150503d805f8114612e42576040519150601f19603f3d011682016040523d82523d5f602084013e612e47565b606091505b5050905080612e69576040516377f92a5360e11b815260040160405180910390fd5b5f612e72611a7b565b905082811015612e9557604051633892029d60e11b815260040160405180910390fd5b427fc83b5086ce94ec8d5a88a9f5fea4b18a522bb238ed0d2d8abd959549a80c16b8612ec185846148f1565b60405190815260200160405180910390a2505050505050565b5f54604051632474521560e21b81525f516020614d615f395f51905f52600482018190523360248301529161010090046001600160a01b0316906391d1485490604401602060405180830381865afa158015612f38573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f5c91906148c2565b612f975760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401610ac2565b81612fb55760405163251f56a160e21b815260040160405180910390fd5b5f5b8281101561210957612fee848483818110612fd457612fd4614a0f565b9050602002016020810190612fe9919061453d565b613a6a565b600101612fb7565b6060610bc16004613c6e565b5f5460ff16156130255760405163d93c066560e01b815260040160405180910390fd5b565b61246a6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001682846130c7565b5f825f19048411830215820261306f575f5ffd5b5091020490565b61307e613c7a565b5f805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6130d48383836001613c9c565b6130fc57604051635274afe760e01b81526001600160a01b0384166004820152602401610ac2565b505050565b6001600160a01b0381165f9081526001830160205260408120541515610d3d565b6040516315d5220f60e31b81526001600160a01b0382811660048301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063aea9107890602401602060405180830381865afa9250505080156131a8575060408051601f3d908101601f191682019092526131a591810190614904565b60015b6131b357505f919050565b151592915050565b919050565b6001600160a01b0381165f90815260076020526040902054819060ff166132065760405163a58f313b60e01b81526001600160a01b039091166004820152602401610ac2565b50818061322957604051636450874f60e11b8152600401610ac291815260200190565b506040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa15801561326c573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132909190614904565b821115829061210957604051636450874f60e11b8152600401610ac291815260200190565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038716906370a0823190602401602060405180830381865afa1580156132fb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061331f9190614904565b90506133356001600160a01b03881685876134ab565b5f5f856001600160a01b03168560405161334f9190614a93565b5f604051808303815f865af19150503d805f8114613388576040519150601f19603f3d011682016040523d82523d5f602084013e61338d565b606091505b50915091508181906133cc576040517fff9fa595000000000000000000000000000000000000000000000000000000008152600401610ac2919061482b565b506133e16001600160a01b038a16875f6134ab565b6040516370a0823160e01b815230600482015283906001600160a01b038a16906370a0823190602401602060405180830381865afa158015613425573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134499190614904565b61345391906148f1565b9998505050505050505050565b5f8180613489576040516378e9a2e760e01b815260048101929092526024820152604401610ac2565b505061210984848484613cfe565b5f610d3d8383670de0b6b3a764000061305b565b6134b78383835f613d66565b6130fc576134c883835f6001613d66565b6134f057604051635274afe760e01b81526001600160a01b0384166004820152602401610ac2565b6130d48383836001613d66565b6040516370a0823160e01b81523060048201525f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015613563573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906135879190614904565b6040516315d5220f60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529192505f917f0000000000000000000000000000000000000000000000000000000000000000169063aea9107890602401602060405180830381865afa158015613610573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136349190614904565b90505f61363f612ff6565b90505f5b815181101561380b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031682828151811061368857613688614a0f565b60200260200101516001600160a01b03160315613803575f8282815181106136b2576136b2614a0f565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015613700573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137249190614904565b9050805f036137335750613803565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663aea9107885858151811061377557613775614a0f565b60200260200101516040518263ffffffff1660e01b81526004016137a891906001600160a01b0391909116815260200190565b602060405180830381865afa1580156137c3573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137e79190614904565b90506137f482828761305b565b6137fe908761491b565b955050505b600101613643565b50919392505050565b5f815f03613826576138266012613db0565b81600184038161383857613838614aa9565b046001018315155b029392505050565b5f61387561385583613dc1565b801561387057505f848061386b5761386b614aa9565b868809115b151590565b613880868686613ded565b61388a919061491b565b95945050505050565b61389c81613122565b81906138c757604051631f93601760e01b81526001600160a01b039091166004820152602401610ac2565b506138d3600482613e9d565b506040516001600160a01b038216815242907faa5546990a389e40b77b177c187d29e7a10fcba5151f6872026b18dd6acd57719060200160405180910390a250565b5f80546001600160a01b0383811661010081810274ffffffffffffffffffffffffffffffffffffffff0019851617855560405193049190911692909183917f9209b7c8c06dcfd261686a663e7c55989337b18d59da5433c6f2835fb697092091a35050565b613982613002565b5f805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586130aa3390565b60607f000000000000000000000000000000000000000000000000000000000000000015613a12576104b06006546139ee919061491b565b4211613a0d57604051635ab1f4a960e01b815260040160405180910390fd5b426006555b613a1b82613eb1565b60408201518251613a59916001600160a01b03909116907f0000000000000000000000000000000000000000000000000000000000000000906134ab565b610e8e613a6583613f03565b614075565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614158190613acb576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b50613ad58161114e565b8190613b00576040516337bce3c560e11b81526001600160a01b039091166004820152602401610ac2565b506040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015613b45573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b699190614904565b90505f826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ba8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bcc9190614abd565b60ff169050613bdc81600a614bb8565b613be7906001614bc3565b82111583839091613c1c5760405163327f32bd60e11b81526001600160a01b0390921660048301526024820152604401610ac2565b50613c2a9050600484614230565b506040516001600160a01b038416815242907f36c12b9b4d20f73189838a9c40ee0af4582f9431846c881b42cfd809eeca78b39060200160405180910390a2505050565b60605f610d3d83614244565b5f5460ff1661302557604051638dfc202b60e01b815260040160405180910390fd5b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613cf2578383151615613ce6573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b5f613d098585612c78565b604001516001600160801b031690505f613d2e82613d28888888610bf1565b90613497565b9050808381811015613d5c57604051633b5d56ed60e11b815260048101929092526024820152604401610ac2565b5050505050505050565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316613cf2578383151615613ce6573d5f823e3d81fd5b634e487b715f52806020526024601cfd5b5f6002826003811115613dd657613dd6614bda565b613de09190614bee565b60ff166001149050919050565b5f5f5f613dfa868661429d565b91509150815f03613e1e57838181613e1457613e14614aa9565b0492505050610d3d565b818411613e3557613e356003851502601118613db0565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f610d3d836001600160a01b0384166142b9565b5f613ed08260800151613d28845f015185602001518660400151610bf1565b6060830151909150819081811161210957604051633b5d56ed60e11b815260048101929092526024820152604401610ac2565b613f7e6040518061018001604052805f6001600160a01b031681526020015f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f63ffffffff1681526020015f81526020015f81526020015f81526020015f151581526020015f81526020015f81525090565b604051806101800160405280835f01516001600160a01b0316815260200183602001516001600160a01b03168152602001306001600160a01b0316815260200183604001518152602001836060015181526020016104b042613fe0919061491b565b63ffffffff1681527f3cac71ef99d0dfbf5b937334b5b7ab672b679ba2bbd4d6fe8e0c54a2dab3110960208201525f604082018190527ff3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee346775606083015260808201527f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc960a0820181905260c09091015292915050565b60605f7f000000000000000000000000000000000000000000000000000000000000000090505f61415184836001600160a01b031663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156140dc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141009190614904565b601f1990910180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a08220915260405161190160f01b8152600281019290925260228201526042902090565b604080516038808252606082019092529192505f91906020820181803683370190505090506141868183308860a00151614305565b60405163ec6cb13f60e01b81526001600160a01b0384169063ec6cb13f906141b5908490600190600401614c1b565b5f604051808303815f87803b1580156141cc575f5ffd5b505af11580156141de573d5f5f3e3d5ffd5b50505050427f63521d767ee2dda07d9815cec18770071f08ed7902feacb2cb193196bb8e9aad82878860a0015189608001516040516142209493929190614c3e565b60405180910390a2949350505050565b5f610d3d836001600160a01b038416614368565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561429157602002820191905f5260205f20905b81548152602001906001019080831161427d575b50505050509050919050565b5f805f1983850993909202808410938190039390930393915050565b5f8181526001830160205260408120546142fe57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610e8e565b505f610e8e565b60388451146143565760405162461bcd60e51b815260206004820152601960248201527f475076323a2075696420627566666572206f766572666c6f77000000000000006044820152606401610ac2565b60388401526034830152602090910152565b5f8181526001830160205260408120548015614442575f61438a6001836148f1565b85549091505f9061439d906001906148f1565b90508082146143fc575f865f0182815481106143bb576143bb614a0f565b905f5260205f200154905080875f0184815481106143db576143db614a0f565b5f918252602080832090910192909255918252600188019052604090208390555b855486908061440d5761440d614d2c565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610e8e565b5f915050610e8e565b80356001600160a01b03811681146131bb575f5ffd5b5f5f60408385031215614472575f5ffd5b823591506144826020840161444b565b90509250929050565b5f5f5f6060848603121561449d575f5ffd5b6144a68461444b565b92506144b46020850161444b565b929592945050506040919091013590565b5f5f604083850312156144d6575f5ffd5b6144df8361444b565b91506144826020840161444b565b5f602082840312156144fd575f5ffd5b5035919050565b5f5f5f60608486031215614516575f5ffd5b61451f8461444b565b9250602084013591506145346040850161444b565b90509250925092565b5f6020828403121561454d575f5ffd5b610d3d8261444b565b634e487b7160e01b5f52604160045260245ffd5b60405160a0810167ffffffffffffffff8111828210171561458d5761458d614556565b60405290565b5f82601f8301126145a2575f5ffd5b813567ffffffffffffffff8111156145bc576145bc614556565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156145eb576145eb614556565b604052818152838201602001851015614602575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f60a08688031215614632575f5ffd5b61463b8661444b565b94506146496020870161444b565b93506040860135925061465e6060870161444b565b9150608086013567ffffffffffffffff811115614679575f5ffd5b61468588828901614593565b9150509295509295909350565b8015158114610e1c575f5ffd5b5f5f604083850312156146b0575f5ffd5b6146b98361444b565b915060208301356146c981614692565b809150509250929050565b5f5f83601f8401126146e4575f5ffd5b50813567ffffffffffffffff8111156146fb575f5ffd5b6020830191508360208260051b8501011115614715575f5ffd5b9250929050565b5f5f6020838503121561472d575f5ffd5b823567ffffffffffffffff811115614743575f5ffd5b61474f858286016146d4565b90969095509350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156147e057603f198786030184526147cb85835161475b565b945060209384019391909101906001016147af565b50929695505050505050565b5f5f5f5f608085870312156147ff575f5ffd5b6148088561444b565b93506148166020860161444b565b93969395505050506040820135916060013590565b602081525f610d3d602083018461475b565b5f6020828403121561484d575f5ffd5b813567ffffffffffffffff811115614863575f5ffd5b61486f84828501614593565b949350505050565b602080825282518282018190525f918401906040840190835b818110156148b75783516001600160a01b0316835260209384019390920191600101614890565b509095945050505050565b5f602082840312156148d2575f5ffd5b8151610d3d81614692565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610e8e57610e8e6148dd565b5f60208284031215614914575f5ffd5b5051919050565b80820180821115610e8e57610e8e6148dd565b67ffffffffffffffff8181168382160190811115610e8e57610e8e6148dd565b5f5f6040838503121561495f575f5ffd5b505080516020909101519092909150565b80516effffffffffffffffffffffffffffff811681146131bb575f5ffd5b5f60a082840312801561499f575f5ffd5b506149a861456a565b6149b183614970565b81526149bf60208401614970565b602082015260408301518060180b81146149d7575f5ffd5b60408201526149e860608401614970565b6060820152608083015163ffffffff81168114614a03575f5ffd5b60808201529392505050565b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614a37575f5ffd5b9190910192915050565b5f5f8335601e19843603018112614a56575f5ffd5b83018035915067ffffffffffffffff821115614a70575f5ffd5b602001915036819003821315614715575f5ffd5b818382375f9101908152919050565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52601260045260245ffd5b5f60208284031215614acd575f5ffd5b815160ff81168114610d3d575f5ffd5b6001815b6001841115614b1857808504811115614afc57614afc6148dd565b6001841615614b0a57908102905b60019390931c928002614ae1565b935093915050565b5f82614b2e57506001610e8e565b81614b3a57505f610e8e565b8160018114614b505760028114614b5a57614b76565b6001915050610e8e565b60ff841115614b6b57614b6b6148dd565b50506001821b610e8e565b5060208310610133831016604e8410600b8410161715614b99575081810a610e8e565b614ba55f198484614add565b805f1904821115613840576138406148dd565b5f610d3d8383614b20565b8082028115828204841417610e8e57610e8e6148dd565b634e487b7160e01b5f52602160045260245ffd5b5f60ff831680614c0c57634e487b7160e01b5f52601260045260245ffd5b8060ff84160691505092915050565b604081525f614c2d604083018561475b565b905082151560208301529392505050565b6101e081525f614c526101e083018761475b565b85516001600160a01b03166020840152905060208501516001600160a01b03811660408401525060408501516001600160a01b03811660608401525060608501516080830152608085015160a083015260a0850151614cb960c084018263ffffffff169052565b5060c085015160e083015260e0850151610100830152610100850151610120830152610120850151614cf061014084018215159052565b50610140850151610160830152610160850151610180830152614d1c6101a083018563ffffffff169052565b826101c083015295945050505050565b634e487b7160e01b5f52603160045260245ffdfe456cfaf8d1ec98ae5bbe595a448911a58cb2e264d4686992e15dec9d0f363e033947e2f542c6c46c543fa4f79cbd1e27fea37ed249bc3caf992570d19123642ea26469706673582212202f27f2d47a7f717a132515e634abfdc6bdbdf6d27ce68cbdd472d62af5b6dfc964736f6c634300081c0033000000000000000000000000f6d48735eccf12bdc1df2674b1ce3fcb3bd25490000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b30000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41000000000000000000000000c92e8bdf79f0507f65a392b0ab4667716bfe01100000000000000000000000000000000000000000000000000000000000093a8000000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c485000000000000000000000000000000000000000000000000000000000000000b","name":"AaveV4Farm","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.24;\n\nimport {Arrays} from \"../Arrays.sol\";\nimport {Math} from \"../math/Math.sol\";\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n * - Set can be cleared (all elements removed) in O(n).\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * The following types are supported:\n *\n * - `bytes32` (`Bytes32Set`) since v3.3.0\n * - `address` (`AddressSet`) since v3.3.0\n * - `uint256` (`UintSet`) since v3.3.0\n * - `string` (`StringSet`) since v5.4.0\n * - `bytes` (`BytesSet`) since v5.4.0\n * - `bytes4` (`Bytes4Set`) since v5.6.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes32 value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: This function has an unbounded cost that scales with set size. Developers should keep in mind that\n     * using it may render the function uncallable if the set grows to the point where clearing it consumes too much\n     * gas to fit in a block.\n     */\n    function _clear(Set storage set) private {\n        uint256 len = _length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set, uint256 start, uint256 end) private view returns (bytes32[] memory) {\n        unchecked {\n            end = Math.min(end, _length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            bytes32[] memory result = new bytes32[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32Set storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set, uint256 start, uint256 end) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes4Set\n\n    struct Bytes4Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes4Set storage set, bytes4 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes4Set storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes4Set storage set, bytes4 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes4Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes4Set storage set, uint256 index) internal view returns (bytes4) {\n        return bytes4(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes4Set storage set) internal view returns (bytes4[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes4[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes4Set storage set, uint256 start, uint256 end) internal view returns (bytes4[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        bytes4[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set, uint256 start, uint256 end) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set, uint256 start, uint256 end) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner, start, end);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    struct StringSet {\n        // Storage of set values\n        string[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(string value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(StringSet storage set, string memory value) internal returns (bool) {\n        if (!contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(StringSet storage set, string memory value) internal returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                string memory lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(StringSet storage set) internal {\n        uint256 len = length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(StringSet storage set, string memory value) internal view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(StringSet storage set) internal view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(StringSet storage set, uint256 index) internal view returns (string memory) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(StringSet storage set) internal view returns (string[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(StringSet storage set, uint256 start, uint256 end) internal view returns (string[] memory) {\n        unchecked {\n            end = Math.min(end, length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            string[] memory result = new string[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n\n    struct BytesSet {\n        // Storage of set values\n        bytes[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(BytesSet storage set, bytes memory value) internal returns (bool) {\n        if (!contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(BytesSet storage set, bytes memory value) internal returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes memory lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(BytesSet storage set) internal {\n        uint256 len = length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(BytesSet storage set, bytes memory value) internal view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(BytesSet storage set) internal view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(BytesSet storage set, uint256 index) internal view returns (bytes memory) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(BytesSet storage set) internal view returns (bytes[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Return a slice of the set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(BytesSet storage set, uint256 start, uint256 end) internal view returns (bytes[] memory) {\n        unchecked {\n            end = Math.min(end, length(set));\n            start = Math.min(start, end);\n\n            uint256 len = end - start;\n            bytes[] memory result = new bytes[](len);\n            for (uint256 i = 0; i < len; ++i) {\n                result[i] = Arrays.unsafeAccess(set._values, start + i).value;\n            }\n            return result;\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/interfaces/GPv2Authentication.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\n\n/// @title Gnosis Protocol v2 Authentication Interface\n/// @author Gnosis Developers\ninterface GPv2Authentication {\n    /// @dev determines whether the provided address is an authenticated solver.\n    /// @param prospectiveSolver the address of prospective solver.\n    /// @return true when prospectiveSolver is an authenticated solver, otherwise false.\n    function isSolver(address prospectiveSolver) external view returns (bool);\n}\n"},{"file_path":"src/integrations/farms/SwapFarmV2.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {FixedPointMathLib} from \"@solmate/src/utils/FixedPointMathLib.sol\";\n\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {CoWSwapBase} from \"@integrations/CoWSwapBase.sol\";\nimport {MultiAssetFarmV2} from \"@integrations/MultiAssetFarmV2.sol\";\n\n/// @title SwapFarmV2\n/// @notice Farm contract that supports token swapping through CoW Protocol and other aggregators\n/// @dev This contract extends MultiAssetFarmV2 and CoWSwapFarmBaseV2 to provide swap functionality\n/// @dev It supports both CoW Protocol orders and direct aggregator swaps with configurable pairs\ncontract SwapFarmV2 is MultiAssetFarmV2, CoWSwapBase {\n    using SafeERC20 for IERC20;\n    using FixedPointMathLib for uint256;\n\n    event TokensSwapped(\n        uint256 indexed timestamp, address _tokenIn, uint256 _amountIn, address _tokenOut, uint256 _amountOut\n    );\n\n    /// @notice Configuration for token pair swap settings\n    struct PairConfig {\n        uint64 lastSwap;\n        /// @dev Timestamp of the last swap for this pair\n        uint64 cooldown;\n        /// @dev Cooldown period between swaps for this pair\n        uint128 maxSlippage;\n    }\n\n    /// @notice Emitted when a router is enabled or disabled\n    /// @param timestamp The block timestamp when the router status was changed\n    /// @param router The address of the router that was enabled/disabled\n    /// @param enabled True if the router was enabled, false if disabled\n    event SetEnabledRouter(uint256 timestamp, address router, bool enabled);\n\n    /// @notice Emitted when a pair configuration is set\n    event SetPairConfig(uint256 timestamp, address token1, address token2, uint256 cooldown, uint256 maxSlippage);\n\n    /// @notice Thrown when a swap operation fails\n    /// @param _reason The reason for the swap failure\n    error SwapFailed(bytes _reason);\n\n    /// @notice Thrown when trying to use a disabled router\n    /// @param _router The address of the disabled router\n    error RouterNotEnabled(address _router);\n\n    /// @notice Thrown when an invalid cooldown period is provided\n    /// @param _cooldown The invalid cooldown value\n    error InvalidCooldown(uint256 _cooldown);\n\n    /// @notice Thrown when slippage configuration is invalid\n    /// @param _configuredSlipage The configured slippage value\n    /// @param _maxSlippage The maximum allowed slippage value\n    error InvalidSlippage(uint256 _configuredSlipage, uint256 _maxSlippage);\n\n    /// @notice Maximum allowed cooldown period for swap pairs (12 hours)\n    uint256 public constant _MAX_COOLDOWN = 12 hours;\n\n    /// @notice Mapping of routers that can be used to swap tokens\n    mapping(address => bool) public enabledRouters;\n\n    /// @notice Mapping of token pairs to their swap configuration\n    mapping(bytes32 _key => PairConfig _value) pairConfig;\n\n    /// @notice Constructor for SwapFarmV2\n    /// @param _core The address of the core contract\n    /// @param _assetToken The primary asset token for this farm\n    /// @param _accounting The address of the accounting contract\n    /// @param _settlementContract The address of the GPv2Settlement contract\n    /// @param _vaultRelayer The address of the GPv2VaultRelayer contract\n    constructor(\n        address _core,\n        address _assetToken,\n        address _accounting,\n        address _settlementContract,\n        address _vaultRelayer\n    ) CoWSwapBase(_settlementContract, _vaultRelayer, false) MultiAssetFarmV2(_core, _assetToken, _accounting) {\n        // set default slippage tolerance to 99.5%\n        maxSlippage = 0.995e18;\n    }\n\n    /// @dev Modifier to validate that both tokens in a swap pair are valid and supported\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    modifier validTokenPair(address _tokenIn, address _tokenOut) {\n        require(_tokenIn != _tokenOut, InvalidToken(_tokenOut));\n        require(isAssetSupported(_tokenIn), InvalidToken(_tokenIn));\n        require(isAssetSupported(_tokenOut), InvalidToken(_tokenOut));\n        _;\n    }\n\n    /// @dev Modifier to validate swap configuration and enforce cooldown periods\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    modifier withValidConfig(address _tokenIn, address _tokenOut) {\n        bytes32 key = getSwapPairKey(_tokenIn, _tokenOut);\n        PairConfig storage config = pairConfig[key];\n        // do not allow swap pairs to exchange too often\n        require(block.timestamp > config.lastSwap + config.cooldown, SwapCooldown());\n        // enforce pair slippage to respect general level slippage\n        // @dev note that if maxSlippage is set to 0, this check will pass even if\n        // the swap pair has not been configured.\n        require(config.maxSlippage >= maxSlippage, InvalidSlippage(config.maxSlippage, maxSlippage));\n        _;\n        config.lastSwap = uint64(block.timestamp);\n    }\n\n    /// @notice Allows governance to manage the whitelist of routers to be used by the\n    /// keeper with FARM_SWAP_CALLER role\n    /// @param _router The address of the router to enable/disable\n    /// @param _enabled True to enable the router, false to disable\n    function setEnabledRouter(address _router, bool _enabled) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        enabledRouters[_router] = _enabled;\n        emit SetEnabledRouter(block.timestamp, _router, _enabled);\n    }\n\n    /// @notice Sets the configuration of the selected swap pair\n    /// @dev !!! Direction is not important for _tokenIn and _tokenOut\n    /// @dev note that this can be used to reset the cooldown but it is behind 1 day timelock\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    /// @param _cooldown The cooldown period between swaps for this pair\n    /// @param _slippage The maximum slippage tolerance for this pair (in WAD format)\n    function setPairConfig(address _tokenIn, address _tokenOut, uint256 _cooldown, uint256 _slippage)\n        external\n        onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS)\n    {\n        require(isAssetSupported(_tokenIn), InvalidToken(_tokenIn));\n        require(isAssetSupported(_tokenOut), InvalidToken(_tokenOut));\n        require(_slippage >= maxSlippage, InvalidSlippage(_slippage, maxSlippage));\n        require(_cooldown <= _MAX_COOLDOWN, InvalidCooldown(_cooldown));\n\n        bytes32 _key = getSwapPairKey(_tokenIn, _tokenOut);\n        // castings are safe because they are timestamps far in the future and config values\n        // forge-lint: disable-next-item(unsafe-typecast)\n        pairConfig[_key] = PairConfig({\n            lastSwap: uint64(block.timestamp - _cooldown - 1),\n            cooldown: uint64(_cooldown),\n            maxSlippage: uint128(_slippage)\n        });\n\n        emit SetPairConfig(block.timestamp, _tokenIn, _tokenOut, _cooldown, _slippage);\n    }\n\n    /// @notice Generates a unique key for a token pair (direction-independent)\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    /// @return A unique bytes32 key for the token pair\n    function getSwapPairKey(address _tokenIn, address _tokenOut) public pure returns (bytes32) {\n        (address a, address b) = _tokenIn > _tokenOut ? (_tokenIn, _tokenOut) : (_tokenOut, _tokenIn);\n        return keccak256(abi.encodePacked(a, b));\n    }\n\n    /// @notice Returns the configuration for a specific token pair\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    /// @return The PairConfig for the specified token pair\n    function getSwapPairConfig(address _tokenIn, address _tokenOut) public view returns (PairConfig memory) {\n        bytes32 key = getSwapPairKey(_tokenIn, _tokenOut);\n        return pairConfig[key];\n    }\n\n    /// @notice Performs a CoW Protocol order signature\n    /// @dev The caller is trusted to not be sandwiching the swap to steal yield\n    /// @dev There is a prevention measure which sets a cooldown between swap pairs\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    /// @param _amountIn The amount of input tokens to swap\n    /// @param _minAmountOut The minimum amount of output tokens expected\n    /// @return The signed order UID\n    function signSwapOrder(address _tokenIn, address _tokenOut, uint256 _amountIn, uint256 _minAmountOut)\n        external\n        whenNotPaused\n        withValidConfig(_tokenIn, _tokenOut)\n        validTokenPair(_tokenIn, _tokenOut)\n        onlyCoreRole(CoreRoles.FARM_SWAP_CALLER)\n        returns (bytes memory)\n    {\n        require(_amountIn > 0, InvalidAmountIn(_amountIn));\n        require(_amountIn <= IERC20(_tokenIn).balanceOf(address(this)), InvalidAmountIn(_amountIn));\n\n        uint256 slippage = getSwapPairConfig(_tokenIn, _tokenOut).maxSlippage;\n\n        CoWSwapBase.CoWSwapData memory _data =\n            CoWSwapBase.CoWSwapData(_tokenIn, _tokenOut, _amountIn, _minAmountOut, slippage);\n\n        return _checkSwapApproveAndSignOrder(_data);\n    }\n\n    /// @notice Swaps one supported token to another using an enabled aggregator router\n    /// @dev The transaction may be submitted privately to avoid sandwiching, and the function\n    /// can be called multiple times with partial amounts to help reduce slippage\n    /// @dev The caller is trusted to not be sandwiching the swap to steal yield\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    /// @param _amountIn The amount of input tokens to swap\n    /// @param _router The address of the aggregator router to use\n    /// @param _calldata The calldata to send to the router\n    function swapWithAggregator(\n        address _tokenIn,\n        address _tokenOut,\n        uint256 _amountIn,\n        address _router,\n        bytes memory _calldata\n    )\n        external\n        whenNotPaused\n        withValidConfig(_tokenIn, _tokenOut)\n        validTokenPair(_tokenIn, _tokenOut)\n        onlyCoreRole(CoreRoles.FARM_SWAP_CALLER)\n    {\n        _preChecks(_tokenIn, _amountIn, _router);\n\n        uint256 tokensReceived = _doSwap(_tokenIn, _tokenOut, _amountIn, _router, _calldata);\n\n        _postChecks(_tokenIn, _tokenOut, _amountIn, tokensReceived);\n\n        emit TokensSwapped(block.timestamp, _tokenIn, _amountIn, _tokenOut, tokensReceived);\n    }\n\n    /// @notice pre-check for aggregator swaps\n    function _preChecks(address _tokenIn, uint256 _amountIn, address _router) internal view {\n        require(enabledRouters[_router], RouterNotEnabled(_router));\n        require(_amountIn > 0, InvalidAmountIn(_amountIn));\n        require(_amountIn <= IERC20(_tokenIn).balanceOf(address(this)), InvalidAmountIn(_amountIn));\n    }\n\n    function _doSwap(address _tokenIn, address _tokenOut, uint256 _amountIn, address _router, bytes memory _calldata)\n        internal\n        returns (uint256 tokensReceived)\n    {\n        uint256 tokenOutBalanceBefore = IERC20(_tokenOut).balanceOf(address(this));\n\n        IERC20(_tokenIn).forceApprove(_router, _amountIn);\n        (bool success, bytes memory returnData) = _router.call(_calldata);\n        require(success, SwapFailed(returnData));\n        IERC20(_tokenIn).forceApprove(_router, 0); // reset approval\n\n        tokensReceived = IERC20(_tokenOut).balanceOf(address(this)) - tokenOutBalanceBefore;\n    }\n\n    function _postChecks(address _tokenIn, address _tokenOut, uint256 _amountIn, uint256 tokensReceived) internal view {\n        require(tokensReceived > 0, InvalidAmountOut(0, tokensReceived));\n        _checkSlippage(_tokenIn, _tokenOut, _amountIn, tokensReceived);\n    }\n\n    /// @dev Internal function to check if the swap output meets slippage requirements\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    /// @param _amountIn The amount of input tokens\n    /// @param _amountOut The actual amount of output tokens received\n    function _checkSlippage(address _tokenIn, address _tokenOut, uint256 _amountIn, uint256 _amountOut)\n        internal\n        view\n        virtual\n    {\n        uint256 slippage = getSwapPairConfig(_tokenIn, _tokenOut).maxSlippage;\n        uint256 minAmountOut = convert(_tokenIn, _tokenOut, _amountIn).mulWadDown(slippage);\n        require(_amountOut >= minAmountOut, SlippageTooHigh(minAmountOut, _amountOut));\n    }\n\n    /// @dev Internal function to validate CoW Protocol swap data\n    /// @param _data The swap data to validate\n    function _validateSwap(CoWSwapData memory _data) internal view virtual override {\n        // check slippage\n        uint256 minOutSlippage = convert(_data.tokenIn, _data.tokenOut, _data.amountIn).mulWadDown(_data.maxSlippage);\n        require(_data.minAmountOut > minOutSlippage, SlippageTooHigh(minOutSlippage, _data.minAmountOut));\n    }\n}\n"},{"file_path":"src/interfaces/IOracle.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IOracle {\n    /// @notice price of a token expressed in a reference token.\n    /// @dev be mindful of the decimals here, because if quote token\n    /// doesn't have 18 decimals, value is used to scale the decimals.\n    /// For example, for USDC quote (6 decimals) expressed in\n    /// DAI reference (18 decimals), value should be around ~1e30,\n    /// so that price is:\n    /// 1e6 * 1e30 / WAD (1e18)\n    /// ~= WAD (1e18)\n    /// ~= 1:1\n    function price() external view returns (uint256);\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `condition ? a : b`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `condition ? a : b`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // (a + b) / 2 can overflow.\n            return (a & b) + (a ^ b) / 2;\n        }\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory buffer) private pure returns (bool) {\n        uint256 chunk;\n        for (uint256 i = 0; i < buffer.length; i += 0x20) {\n            // See _unsafeReadBytesOffset from utils/Bytes.sol\n            assembly (\"memory-safe\") {\n                chunk := mload(add(add(buffer, 0x20), i))\n            }\n            if (chunk >> (8 * saturatingSub(i + 0x20, buffer.length)) != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the first 16 bytes (most significant half).\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n\n    /**\n     * @dev Counts the number of leading zero bits in a uint256.\n     */\n    function clz(uint256 x) internal pure returns (uint256) {\n        return ternary(x == 0, 256, 255 - log2(x));\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},{"file_path":"lib/cowprotocol/src/contracts/GPv2Settlement.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\npragma abicoder v2;\n\nimport \"./GPv2VaultRelayer.sol\";\nimport \"./interfaces/GPv2Authentication.sol\";\nimport \"./interfaces/IERC20.sol\";\nimport \"./interfaces/IVault.sol\";\nimport \"./libraries/GPv2Interaction.sol\";\nimport \"./libraries/GPv2Order.sol\";\nimport \"./libraries/GPv2Trade.sol\";\nimport \"./libraries/GPv2Transfer.sol\";\nimport \"./libraries/SafeCast.sol\";\nimport \"./libraries/SafeMath.sol\";\nimport \"./mixins/GPv2Signing.sol\";\nimport \"./mixins/ReentrancyGuard.sol\";\nimport \"./mixins/StorageAccessible.sol\";\n\n/// @title Gnosis Protocol v2 Settlement Contract\n/// @author Gnosis Developers\ncontract GPv2Settlement is GPv2Signing, ReentrancyGuard, StorageAccessible {\n    using GPv2Order for bytes;\n    using GPv2Transfer for IVault;\n    using SafeCast for int256;\n    using SafeCast for uint256;\n    using SafeMath for uint256;\n\n    /// @dev The authenticator is used to determine who can call the settle function.\n    /// That is, only authorized solvers have the ability to invoke settlements.\n    /// Any valid authenticator implements an isSolver method called by the onlySolver\n    /// modifier below.\n    GPv2Authentication public immutable authenticator;\n\n    /// @dev The Balancer Vault the protocol used for managing user funds.\n    IVault public immutable vault;\n\n    /// @dev The Balancer Vault relayer which can interact on behalf of users.\n    /// This contract is created during deployment\n    GPv2VaultRelayer public immutable vaultRelayer;\n\n    /// @dev Map each user order by UID to the amount that has been filled so\n    /// far. If this amount is larger than or equal to the amount traded in the\n    /// order (amount sold for sell orders, amount bought for buy orders) then\n    /// the order cannot be traded anymore. If the order is fill or kill, then\n    /// this value is only used to determine whether the order has already been\n    /// executed.\n    mapping(bytes => uint256) public filledAmount;\n\n    /// @dev Event emitted for each executed trade.\n    event Trade(\n        address indexed owner,\n        IERC20 sellToken,\n        IERC20 buyToken,\n        uint256 sellAmount,\n        uint256 buyAmount,\n        uint256 feeAmount,\n        bytes orderUid\n    );\n\n    /// @dev Event emitted for each executed interaction.\n    ///\n    /// For gas efficiency, only the interaction calldata selector (first 4\n    /// bytes) is included in the event. For interactions without calldata or\n    /// whose calldata is shorter than 4 bytes, the selector will be `0`.\n    event Interaction(address indexed target, uint256 value, bytes4 selector);\n\n    /// @dev Event emitted when a settlement completes\n    event Settlement(address indexed solver);\n\n    /// @dev Event emitted when an order is invalidated.\n    event OrderInvalidated(address indexed owner, bytes orderUid);\n\n    constructor(GPv2Authentication authenticator_, IVault vault_) {\n        authenticator = authenticator_;\n        vault = vault_;\n        vaultRelayer = new GPv2VaultRelayer(vault_);\n    }\n\n    // solhint-disable-next-line no-empty-blocks\n    receive() external payable {\n        // NOTE: Include an empty receive function so that the settlement\n        // contract can receive Ether from contract interactions.\n    }\n\n    /// @dev This modifier is called by settle function to block any non-listed\n    /// senders from settling batches.\n    modifier onlySolver() {\n        require(authenticator.isSolver(msg.sender), \"GPv2: not a solver\");\n        _;\n    }\n\n    /// @dev Modifier to ensure that an external function is only callable as a\n    /// settlement interaction.\n    modifier onlyInteraction() {\n        require(address(this) == msg.sender, \"GPv2: not an interaction\");\n        _;\n    }\n\n    /// @dev Settle the specified orders at a clearing price. Note that it is\n    /// the responsibility of the caller to ensure that all GPv2 invariants are\n    /// upheld for the input settlement, otherwise this call will revert.\n    /// Namely:\n    /// - All orders are valid and signed\n    /// - Accounts have sufficient balance and approval.\n    /// - Settlement contract has sufficient balance to execute trades. Note\n    ///   this implies that the accumulated fees held in the contract can also\n    ///   be used for settlement. This is OK since:\n    ///   - Solvers need to be authorized\n    ///   - Misbehaving solvers will be slashed for abusing accumulated fees for\n    ///     settlement\n    ///   - Critically, user orders are entirely protected\n    ///\n    /// @param tokens An array of ERC20 tokens to be traded in the settlement.\n    /// Trades encode tokens as indices into this array.\n    /// @param clearingPrices An array of clearing prices where the `i`-th price\n    /// is for the `i`-th token in the [`tokens`] array.\n    /// @param trades Trades for signed orders.\n    /// @param interactions Smart contract interactions split into three\n    /// separate lists to be run before the settlement, during the settlement\n    /// and after the settlement respectively.\n    function settle(\n        IERC20[] calldata tokens,\n        uint256[] calldata clearingPrices,\n        GPv2Trade.Data[] calldata trades,\n        GPv2Interaction.Data[][3] calldata interactions\n    ) external nonReentrant onlySolver {\n        executeInteractions(interactions[0]);\n\n        (\n            GPv2Transfer.Data[] memory inTransfers,\n            GPv2Transfer.Data[] memory outTransfers\n        ) = computeTradeExecutions(tokens, clearingPrices, trades);\n\n        vaultRelayer.transferFromAccounts(inTransfers);\n\n        executeInteractions(interactions[1]);\n\n        vault.transferToAccounts(outTransfers);\n\n        executeInteractions(interactions[2]);\n\n        emit Settlement(msg.sender);\n    }\n\n    /// @dev Settle an order directly against Balancer V2 pools.\n    ///\n    /// @param swaps The Balancer V2 swap steps to use for trading.\n    /// @param tokens An array of ERC20 tokens to be traded in the settlement.\n    /// Swaps and the trade encode tokens as indices into this array.\n    /// @param trade The trade to match directly against Balancer liquidity. The\n    /// order will always be fully executed, so the trade's `executedAmount`\n    /// field is used to represent a swap limit amount.\n    function swap(\n        IVault.BatchSwapStep[] calldata swaps,\n        IERC20[] calldata tokens,\n        GPv2Trade.Data calldata trade\n    ) external nonReentrant onlySolver {\n        RecoveredOrder memory recoveredOrder = allocateRecoveredOrder();\n        GPv2Order.Data memory order = recoveredOrder.data;\n        recoverOrderFromTrade(recoveredOrder, tokens, trade);\n\n        IVault.SwapKind kind = order.kind == GPv2Order.KIND_SELL\n            ? IVault.SwapKind.GIVEN_IN\n            : IVault.SwapKind.GIVEN_OUT;\n\n        IVault.FundManagement memory funds;\n        funds.sender = recoveredOrder.owner;\n        funds.fromInternalBalance =\n            order.sellTokenBalance == GPv2Order.BALANCE_INTERNAL;\n        funds.recipient = payable(recoveredOrder.receiver);\n        funds.toInternalBalance =\n            order.buyTokenBalance == GPv2Order.BALANCE_INTERNAL;\n\n        int256[] memory limits = new int256[](tokens.length);\n        uint256 limitAmount = trade.executedAmount;\n        // NOTE: Array allocation initializes elements to 0, so we only need to\n        // set the limits we care about. This ensures that the swap will respect\n        // the order's limit price.\n        if (order.kind == GPv2Order.KIND_SELL) {\n            require(limitAmount >= order.buyAmount, \"GPv2: limit too low\");\n            limits[trade.sellTokenIndex] = order.sellAmount.toInt256();\n            limits[trade.buyTokenIndex] = -limitAmount.toInt256();\n        } else {\n            require(limitAmount <= order.sellAmount, \"GPv2: limit too high\");\n            limits[trade.sellTokenIndex] = limitAmount.toInt256();\n            limits[trade.buyTokenIndex] = -order.buyAmount.toInt256();\n        }\n\n        GPv2Transfer.Data memory feeTransfer;\n        feeTransfer.account = recoveredOrder.owner;\n        feeTransfer.token = order.sellToken;\n        feeTransfer.amount = order.feeAmount;\n        feeTransfer.balance = order.sellTokenBalance;\n\n        int256[] memory tokenDeltas = vaultRelayer.batchSwapWithFee(\n            kind,\n            swaps,\n            tokens,\n            funds,\n            limits,\n            // NOTE: Specify a deadline to ensure that an expire order\n            // cannot be used to trade.\n            order.validTo,\n            feeTransfer\n        );\n\n        bytes memory orderUid = recoveredOrder.uid;\n        uint256 executedSellAmount = tokenDeltas[trade.sellTokenIndex]\n            .toUint256();\n        uint256 executedBuyAmount = (-tokenDeltas[trade.buyTokenIndex])\n            .toUint256();\n\n        // NOTE: Check that the orders were completely filled and update their\n        // filled amounts to avoid replaying them. The limit price and order\n        // validity has already been verified when executing the swap through\n        // the `limit` and `deadline` parameters.\n        require(filledAmount[orderUid] == 0, \"GPv2: order filled\");\n        if (order.kind == GPv2Order.KIND_SELL) {\n            require(\n                executedSellAmount == order.sellAmount,\n                \"GPv2: sell amount not respected\"\n            );\n            filledAmount[orderUid] = order.sellAmount;\n        } else {\n            require(\n                executedBuyAmount == order.buyAmount,\n                \"GPv2: buy amount not respected\"\n            );\n            filledAmount[orderUid] = order.buyAmount;\n        }\n\n        emit Trade(\n            recoveredOrder.owner,\n            order.sellToken,\n            order.buyToken,\n            executedSellAmount,\n            executedBuyAmount,\n            order.feeAmount,\n            orderUid\n        );\n        emit Settlement(msg.sender);\n    }\n\n    /// @dev Invalidate onchain an order that has been signed offline.\n    ///\n    /// @param orderUid The unique identifier of the order that is to be made\n    /// invalid after calling this function. The user that created the order\n    /// must be the sender of this message. See [`extractOrderUidParams`]\n    /// for details on orderUid.\n    function invalidateOrder(bytes calldata orderUid) external {\n        (, address owner, ) = orderUid.extractOrderUidParams();\n        require(owner == msg.sender, \"GPv2: caller does not own order\");\n        filledAmount[orderUid] = type(uint256).max;\n        emit OrderInvalidated(owner, orderUid);\n    }\n\n    /// @dev Free storage from the filled amounts of **expired** orders to claim\n    /// a gas refund. This method can only be called as an interaction.\n    ///\n    /// @param orderUids The unique identifiers of the expired order to free\n    /// storage for.\n    function freeFilledAmountStorage(\n        bytes[] calldata orderUids\n    ) external onlyInteraction {\n        freeOrderStorage(filledAmount, orderUids);\n    }\n\n    /// @dev Free storage from the pre signatures of **expired** orders to claim\n    /// a gas refund. This method can only be called as an interaction.\n    ///\n    /// @param orderUids The unique identifiers of the expired order to free\n    /// storage for.\n    function freePreSignatureStorage(\n        bytes[] calldata orderUids\n    ) external onlyInteraction {\n        freeOrderStorage(preSignature, orderUids);\n    }\n\n    /// @dev Process all trades one at a time returning the computed net in and\n    /// out transfers for the trades.\n    ///\n    /// This method reverts if processing of any single trade fails. See\n    /// [`computeTradeExecution`] for more details.\n    ///\n    /// @param tokens An array of ERC20 tokens to be traded in the settlement.\n    /// @param clearingPrices An array of token clearing prices.\n    /// @param trades Trades for signed orders.\n    /// @return inTransfers Array of in transfers of executed sell amounts.\n    /// @return outTransfers Array of out transfers of executed buy amounts.\n    function computeTradeExecutions(\n        IERC20[] calldata tokens,\n        uint256[] calldata clearingPrices,\n        GPv2Trade.Data[] calldata trades\n    )\n        internal\n        returns (\n            GPv2Transfer.Data[] memory inTransfers,\n            GPv2Transfer.Data[] memory outTransfers\n        )\n    {\n        RecoveredOrder memory recoveredOrder = allocateRecoveredOrder();\n\n        inTransfers = new GPv2Transfer.Data[](trades.length);\n        outTransfers = new GPv2Transfer.Data[](trades.length);\n\n        for (uint256 i; i < trades.length; ++i) {\n            GPv2Trade.Data calldata trade = trades[i];\n\n            recoverOrderFromTrade(recoveredOrder, tokens, trade);\n            computeTradeExecution(\n                recoveredOrder,\n                clearingPrices[trade.sellTokenIndex],\n                clearingPrices[trade.buyTokenIndex],\n                trade.executedAmount,\n                inTransfers[i],\n                outTransfers[i]\n            );\n        }\n    }\n\n    /// @dev Compute the in and out transfer amounts for a single trade.\n    /// This function reverts if:\n    /// - The order has expired\n    /// - The order's limit price is not respected\n    /// - The order gets over-filled\n    /// - The fee discount is larger than the executed fee\n    ///\n    /// @param recoveredOrder The recovered order to process.\n    /// @param sellPrice The price of the order's sell token.\n    /// @param buyPrice The price of the order's buy token.\n    /// @param executedAmount The portion of the order to execute. This will be\n    /// ignored for fill-or-kill orders.\n    /// @param inTransfer Memory location for computed executed sell amount\n    /// transfer.\n    /// @param outTransfer Memory location for computed executed buy amount\n    /// transfer.\n    function computeTradeExecution(\n        RecoveredOrder memory recoveredOrder,\n        uint256 sellPrice,\n        uint256 buyPrice,\n        uint256 executedAmount,\n        GPv2Transfer.Data memory inTransfer,\n        GPv2Transfer.Data memory outTransfer\n    ) internal {\n        GPv2Order.Data memory order = recoveredOrder.data;\n        bytes memory orderUid = recoveredOrder.uid;\n\n        // solhint-disable-next-line not-rely-on-time\n        require(order.validTo >= block.timestamp, \"GPv2: order expired\");\n\n        // NOTE: The following computation is derived from the equation:\n        // ```\n        // amount_x * price_x = amount_y * price_y\n        // ```\n        // Intuitively, if a chocolate bar is 0,50€ and a beer is 4€, 1 beer\n        // is roughly worth 8 chocolate bars (`1 * 4 = 8 * 0.5`). From this\n        // equation, we can derive:\n        // - The limit price for selling `x` and buying `y` is respected iff\n        // ```\n        // limit_x * price_x >= limit_y * price_y\n        // ```\n        // - The executed amount of token `y` given some amount of `x` and\n        //   clearing prices is:\n        // ```\n        // amount_y = amount_x * price_x / price_y\n        // ```\n\n        require(\n            order.sellAmount.mul(sellPrice) >= order.buyAmount.mul(buyPrice),\n            \"GPv2: limit price not respected\"\n        );\n\n        uint256 executedSellAmount;\n        uint256 executedBuyAmount;\n        uint256 executedFeeAmount;\n        uint256 currentFilledAmount;\n\n        if (order.kind == GPv2Order.KIND_SELL) {\n            if (order.partiallyFillable) {\n                executedSellAmount = executedAmount;\n                executedFeeAmount = order.feeAmount.mul(executedSellAmount).div(\n                    order.sellAmount\n                );\n            } else {\n                executedSellAmount = order.sellAmount;\n                executedFeeAmount = order.feeAmount;\n            }\n\n            executedBuyAmount = executedSellAmount.mul(sellPrice).ceilDiv(\n                buyPrice\n            );\n\n            currentFilledAmount = filledAmount[orderUid].add(\n                executedSellAmount\n            );\n            require(\n                currentFilledAmount <= order.sellAmount,\n                \"GPv2: order filled\"\n            );\n        } else {\n            if (order.partiallyFillable) {\n                executedBuyAmount = executedAmount;\n                executedFeeAmount = order.feeAmount.mul(executedBuyAmount).div(\n                    order.buyAmount\n                );\n            } else {\n                executedBuyAmount = order.buyAmount;\n                executedFeeAmount = order.feeAmount;\n            }\n\n            executedSellAmount = executedBuyAmount.mul(buyPrice).div(sellPrice);\n\n            currentFilledAmount = filledAmount[orderUid].add(executedBuyAmount);\n            require(\n                currentFilledAmount <= order.buyAmount,\n                \"GPv2: order filled\"\n            );\n        }\n\n        executedSellAmount = executedSellAmount.add(executedFeeAmount);\n        filledAmount[orderUid] = currentFilledAmount;\n\n        emit Trade(\n            recoveredOrder.owner,\n            order.sellToken,\n            order.buyToken,\n            executedSellAmount,\n            executedBuyAmount,\n            executedFeeAmount,\n            orderUid\n        );\n\n        inTransfer.account = recoveredOrder.owner;\n        inTransfer.token = order.sellToken;\n        inTransfer.amount = executedSellAmount;\n        inTransfer.balance = order.sellTokenBalance;\n\n        outTransfer.account = recoveredOrder.receiver;\n        outTransfer.token = order.buyToken;\n        outTransfer.amount = executedBuyAmount;\n        outTransfer.balance = order.buyTokenBalance;\n    }\n\n    /// @dev Execute a list of arbitrary contract calls from this contract.\n    /// @param interactions The list of interactions to execute.\n    function executeInteractions(\n        GPv2Interaction.Data[] calldata interactions\n    ) internal {\n        for (uint256 i; i < interactions.length; ++i) {\n            GPv2Interaction.Data calldata interaction = interactions[i];\n\n            // To prevent possible attack on user funds, we explicitly disable\n            // any interactions with the vault relayer contract.\n            require(\n                interaction.target != address(vaultRelayer),\n                \"GPv2: forbidden interaction\"\n            );\n            GPv2Interaction.execute(interaction);\n\n            emit Interaction(\n                interaction.target,\n                interaction.value,\n                GPv2Interaction.selector(interaction)\n            );\n        }\n    }\n\n    /// @dev Claims refund for the specified storage and order UIDs.\n    ///\n    /// This method reverts if any of the orders are still valid.\n    ///\n    /// @param orderUids Order refund data for freeing storage.\n    /// @param orderStorage Order storage mapped on a UID.\n    function freeOrderStorage(\n        mapping(bytes => uint256) storage orderStorage,\n        bytes[] calldata orderUids\n    ) internal {\n        for (uint256 i; i < orderUids.length; ++i) {\n            bytes calldata orderUid = orderUids[i];\n\n            (, , uint32 validTo) = orderUid.extractOrderUidParams();\n            // solhint-disable-next-line not-rely-on-time\n            require(validTo < block.timestamp, \"GPv2: order still valid\");\n\n            orderStorage[orderUid] = 0;\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Arrays.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/Arrays.sol)\n// This file was procedurally generated from scripts/generate/templates/Arrays.js.\n\npragma solidity ^0.8.24;\n\nimport {Comparators} from \"./Comparators.sol\";\nimport {SlotDerivation} from \"./SlotDerivation.sol\";\nimport {StorageSlot} from \"./StorageSlot.sol\";\nimport {Math} from \"./math/Math.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary Arrays {\n    using SlotDerivation for bytes32;\n    using StorageSlot for bytes32;\n\n    /**\n     * @dev Sort an array of uint256 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        uint256[] memory array,\n        function(uint256, uint256) pure returns (bool) comp\n    ) internal pure returns (uint256[] memory) {\n        _quickSort(_begin(array), _end(array), comp);\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of uint256 in increasing order.\n     */\n    function sort(uint256[] memory array) internal pure returns (uint256[] memory) {\n        sort(array, Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of address (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        address[] memory array,\n        function(address, address) pure returns (bool) comp\n    ) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of address in increasing order.\n     */\n    function sort(address[] memory array) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of bytes32 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        bytes32[] memory array,\n        function(bytes32, bytes32) pure returns (bool) comp\n    ) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.\n     */\n    function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops\n     * at end (exclusive). Sorting follows the `comp` comparator.\n     *\n     * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.\n     *\n     * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should\n     * be used only if the limits are within a memory array.\n     */\n    function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {\n        unchecked {\n            if (end - begin < 0x40) return;\n\n            // Use first element as pivot\n            uint256 pivot = _mload(begin);\n            // Position where the pivot should be at the end of the loop\n            uint256 pos = begin;\n\n            for (uint256 it = begin + 0x20; it < end; it += 0x20) {\n                if (comp(_mload(it), pivot)) {\n                    // If the value stored at the iterator's position comes before the pivot, we increment the\n                    // position of the pivot and move the value there.\n                    pos += 0x20;\n                    _swap(pos, it);\n                }\n            }\n\n            _swap(begin, pos); // Swap pivot into place\n            _quickSort(begin, pos, comp); // Sort the left side of the pivot\n            _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first element of `array`.\n     */\n    function _begin(uint256[] memory array) private pure returns (uint256 ptr) {\n        assembly (\"memory-safe\") {\n            ptr := add(array, 0x20)\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word\n     * that comes just after the last element of the array.\n     */\n    function _end(uint256[] memory array) private pure returns (uint256 ptr) {\n        unchecked {\n            return _begin(array) + array.length * 0x20;\n        }\n    }\n\n    /**\n     * @dev Load memory word (as a uint256) at location `ptr`.\n     */\n    function _mload(uint256 ptr) private pure returns (uint256 value) {\n        assembly {\n            value := mload(ptr)\n        }\n    }\n\n    /**\n     * @dev Swaps the elements memory location `ptr1` and `ptr2`.\n     */\n    function _swap(uint256 ptr1, uint256 ptr2) private pure {\n        assembly {\n            let value1 := mload(ptr1)\n            let value2 := mload(ptr2)\n            mstore(ptr1, value2)\n            mstore(ptr2, value1)\n        }\n    }\n\n    /// @dev Helper: low level cast address memory array to uint256 memory array\n    function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 memory array to uint256 memory array\n    function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast address comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(address, address) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(bytes32, bytes32) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /**\n     * @dev Searches a sorted `array` and returns the first index that contains\n     * a value greater or equal to `element`. If no such index exists (i.e. all\n     * values in the array are strictly less than `element`), the array length is\n     * returned. Time complexity O(log n).\n     *\n     * NOTE: The `array` is expected to be sorted in ascending order, and to\n     * contain no repeated elements.\n     *\n     * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks\n     * support for repeated elements in the array. The {lowerBound} function should\n     * be used instead.\n     */\n    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n        if (low > 0 && unsafeAccess(array, low - 1).value == element) {\n            return low - 1;\n        } else {\n            return low;\n        }\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value greater or equal than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].\n     */\n    function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value strictly greater than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].\n     */\n    function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {lowerBound}, but with an array in memory.\n     */\n    function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {upperBound}, but with an array in memory.\n     */\n    function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to the end of `array` into a new address array in\n     * memory.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(address[] memory array, uint256 start) internal pure returns (address[] memory) {\n        return slice(array, start, array.length);\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to `end` (excluded) into a new address array in\n     * memory. The `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(address[] memory array, uint256 start, uint256 end) internal pure returns (address[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        address[] memory result = new address[](end - start);\n        assembly (\"memory-safe\") {\n            mcopy(add(result, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to the end of `array` into a new bytes32 array in\n     * memory.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(bytes32[] memory array, uint256 start) internal pure returns (bytes32[] memory) {\n        return slice(array, start, array.length);\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to `end` (excluded) into a new bytes32 array in\n     * memory. The `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(bytes32[] memory array, uint256 start, uint256 end) internal pure returns (bytes32[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        bytes32[] memory result = new bytes32[](end - start);\n        assembly (\"memory-safe\") {\n            mcopy(add(result, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to the end of `array` into a new uint256 array in\n     * memory.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(uint256[] memory array, uint256 start) internal pure returns (uint256[] memory) {\n        return slice(array, start, array.length);\n    }\n\n    /**\n     * @dev Copies the content of `array`, from `start` (included) to `end` (excluded) into a new uint256 array in\n     * memory. The `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's `Array.slice`]\n     */\n    function slice(uint256[] memory array, uint256 start, uint256 end) internal pure returns (uint256[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // allocate and copy\n        uint256[] memory result = new uint256[](end - start);\n        assembly (\"memory-safe\") {\n            mcopy(add(result, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n        }\n\n        return result;\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to the end of `array` to the start of that array.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(address[] memory array, uint256 start) internal pure returns (address[] memory) {\n        return splice(array, start, array.length);\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to `end` (excluded) to the start of that array. The\n     * `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(address[] memory array, uint256 start, uint256 end) internal pure returns (address[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // move and resize\n        assembly (\"memory-safe\") {\n            mcopy(add(array, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n            mstore(array, sub(end, start))\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with all elements from `replacement`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`).\n     * If `pos >= array.length`, no replacement occurs and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        address[] memory array,\n        uint256 pos,\n        address[] memory replacement\n    ) internal pure returns (address[] memory) {\n        return replace(array, pos, replacement, 0, replacement.length);\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with elements from `replacement` starting at `offset`.\n     * Copies at most `length` elements from `replacement` to `array`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`, `offset` is\n     * clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,\n     * array.length - pos)`). If `pos >= array.length` or `offset >= replacement.length`, no replacement occurs\n     * and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        address[] memory array,\n        uint256 pos,\n        address[] memory replacement,\n        uint256 offset,\n        uint256 length\n    ) internal pure returns (address[] memory) {\n        // sanitize\n        pos = Math.min(pos, array.length);\n        offset = Math.min(offset, replacement.length);\n        length = Math.min(length, Math.min(replacement.length - offset, array.length - pos));\n\n        // allocate and copy\n        assembly (\"memory-safe\") {\n            mcopy(\n                add(add(array, 0x20), mul(pos, 0x20)),\n                add(add(replacement, 0x20), mul(offset, 0x20)),\n                mul(length, 0x20)\n            )\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to the end of `array` to the start of that array.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(bytes32[] memory array, uint256 start) internal pure returns (bytes32[] memory) {\n        return splice(array, start, array.length);\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to `end` (excluded) to the start of that array. The\n     * `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(bytes32[] memory array, uint256 start, uint256 end) internal pure returns (bytes32[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // move and resize\n        assembly (\"memory-safe\") {\n            mcopy(add(array, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n            mstore(array, sub(end, start))\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with all elements from `replacement`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`).\n     * If `pos >= array.length`, no replacement occurs and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        bytes32[] memory array,\n        uint256 pos,\n        bytes32[] memory replacement\n    ) internal pure returns (bytes32[] memory) {\n        return replace(array, pos, replacement, 0, replacement.length);\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with elements from `replacement` starting at `offset`.\n     * Copies at most `length` elements from `replacement` to `array`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`, `offset` is\n     * clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,\n     * array.length - pos)`). If `pos >= array.length` or `offset >= replacement.length`, no replacement occurs\n     * and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        bytes32[] memory array,\n        uint256 pos,\n        bytes32[] memory replacement,\n        uint256 offset,\n        uint256 length\n    ) internal pure returns (bytes32[] memory) {\n        // sanitize\n        pos = Math.min(pos, array.length);\n        offset = Math.min(offset, replacement.length);\n        length = Math.min(length, Math.min(replacement.length - offset, array.length - pos));\n\n        // allocate and copy\n        assembly (\"memory-safe\") {\n            mcopy(\n                add(add(array, 0x20), mul(pos, 0x20)),\n                add(add(replacement, 0x20), mul(offset, 0x20)),\n                mul(length, 0x20)\n            )\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to the end of `array` to the start of that array.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(uint256[] memory array, uint256 start) internal pure returns (uint256[] memory) {\n        return splice(array, start, array.length);\n    }\n\n    /**\n     * @dev Moves the content of `array`, from `start` (included) to `end` (excluded) to the start of that array. The\n     * `end` argument is truncated to the length of the `array`.\n     *\n     * NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.\n     * NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]\n     */\n    function splice(uint256[] memory array, uint256 start, uint256 end) internal pure returns (uint256[] memory) {\n        // sanitize\n        end = Math.min(end, array.length);\n        start = Math.min(start, end);\n\n        // move and resize\n        assembly (\"memory-safe\") {\n            mcopy(add(array, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))\n            mstore(array, sub(end, start))\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with all elements from `replacement`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`).\n     * If `pos >= array.length`, no replacement occurs and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        uint256[] memory array,\n        uint256 pos,\n        uint256[] memory replacement\n    ) internal pure returns (uint256[] memory) {\n        return replace(array, pos, replacement, 0, replacement.length);\n    }\n\n    /**\n     * @dev Replaces elements in `array` starting at `pos` with elements from `replacement` starting at `offset`.\n     * Copies at most `length` elements from `replacement` to `array`.\n     *\n     * Parameters are clamped to valid ranges (i.e. `pos` is clamped to `[0, array.length]`, `offset` is\n     * clamped to `[0, replacement.length]`, and `length` is clamped to `min(length, replacement.length - offset,\n     * array.length - pos)`). If `pos >= array.length` or `offset >= replacement.length`, no replacement occurs\n     * and the array is returned unchanged.\n     *\n     * NOTE: This function modifies the provided array in place.\n     */\n    function replace(\n        uint256[] memory array,\n        uint256 pos,\n        uint256[] memory replacement,\n        uint256 offset,\n        uint256 length\n    ) internal pure returns (uint256[] memory) {\n        // sanitize\n        pos = Math.min(pos, array.length);\n        offset = Math.min(offset, replacement.length);\n        length = Math.min(length, Math.min(replacement.length - offset, array.length - pos));\n\n        // allocate and copy\n        assembly (\"memory-safe\") {\n            mcopy(\n                add(add(array, 0x20), mul(pos, 0x20)),\n                add(add(replacement, 0x20), mul(offset, 0x20)),\n                mul(length, 0x20)\n            )\n        }\n\n        return array;\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getAddressSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytes32Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getUint256Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes[] storage arr, uint256 pos) internal pure returns (StorageSlot.BytesSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytesSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(string[] storage arr, uint256 pos) internal pure returns (StorageSlot.StringSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getStringSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes[] memory arr, uint256 pos) internal pure returns (bytes memory res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(string[] memory arr, uint256 pos) internal pure returns (string memory res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(address[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes32[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(uint256[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, or initialize elements if length is increased.\n     */\n    function unsafeSetLength(string[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n}\n"},{"file_path":"src/core/CoreControlled.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Pausable} from \"@openzeppelin/contracts/utils/Pausable.sol\";\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {InfiniFiCore} from \"@core/InfiniFiCore.sol\";\n\n/// @notice Defines some modifiers and utilities around interacting with Core\nabstract contract CoreControlled is Pausable {\n    error UnderlyingCallReverted(bytes returnData);\n\n    /// @notice emitted when the reference to core is updated\n    event CoreUpdate(address indexed oldCore, address indexed newCore);\n\n    /// @notice reference to Core\n    InfiniFiCore private _core;\n\n    constructor(address coreAddress) {\n        _core = InfiniFiCore(coreAddress);\n    }\n\n    /// @notice named onlyCoreRole to prevent collision with OZ onlyRole modifier\n    modifier onlyCoreRole(bytes32 role) {\n        require(_core.hasRole(role, msg.sender), \"UNAUTHORIZED\");\n        _;\n    }\n\n    /// @notice address of the Core contract referenced\n    function core() public view returns (InfiniFiCore) {\n        return _core;\n    }\n\n    /// @notice WARNING CALLING THIS FUNCTION CAN POTENTIALLY\n    /// BRICK A CONTRACT IF CORE IS SET INCORRECTLY\n    /// @notice set new reference to core\n    /// only callable by governor\n    /// @param newCore to reference\n    function setCore(address newCore) external onlyCoreRole(CoreRoles.GOVERNOR) {\n        _setCore(newCore);\n    }\n\n    /// @notice WARNING CALLING THIS FUNCTION CAN POTENTIALLY\n    /// BRICK A CONTRACT IF CORE IS SET INCORRECTLY\n    /// @notice set new reference to core\n    /// @param newCore to reference\n    function _setCore(address newCore) internal {\n        address oldCore = address(_core);\n        _core = InfiniFiCore(newCore);\n\n        emit CoreUpdate(oldCore, newCore);\n    }\n\n    /// @notice set pausable methods to paused\n    function pause() public onlyCoreRole(CoreRoles.PAUSE) {\n        _pause();\n    }\n\n    /// @notice set pausable methods to unpaused\n    function unpause() public onlyCoreRole(CoreRoles.UNPAUSE) {\n        _unpause();\n    }\n\n    /// ------------------------------------------\n    /// ------------ Emergency Action ------------\n    /// ------------------------------------------\n\n    /// inspired by MakerDAO Multicall:\n    /// https://github.com/makerdao/multicall/blob/master/src/Multicall.sol\n\n    /// @notice struct to pack calldata and targets for an emergency action\n    struct Call {\n        /// @notice target address to call\n        address target;\n        /// @notice amount of eth to send with the call\n        uint256 value;\n        /// @notice payload to send to target\n        bytes callData;\n    }\n\n    /// @notice due to inflexibility of current smart contracts,\n    /// add this ability to be able to execute arbitrary calldata\n    /// against arbitrary addresses.\n    /// callable only by governor\n    function emergencyAction(Call[] calldata calls)\n        external\n        payable\n        virtual\n        onlyCoreRole(CoreRoles.GOVERNOR)\n        returns (bytes[] memory returnData)\n    {\n        returnData = new bytes[](calls.length);\n        for (uint256 i = 0; i < calls.length; i++) {\n            address payable target = payable(calls[i].target);\n            uint256 value = calls[i].value;\n            bytes calldata callData = calls[i].callData;\n\n            (bool success, bytes memory returned) = target.call{value: value}(callData);\n            require(success, UnderlyingCallReverted(returned));\n            returnData[i] = returned;\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/libraries/GPv2Transfer.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\npragma abicoder v2;\n\nimport \"../interfaces/IERC20.sol\";\nimport \"../interfaces/IVault.sol\";\nimport \"./GPv2Order.sol\";\nimport \"./GPv2SafeERC20.sol\";\n\n/// @title Gnosis Protocol v2 Transfers\n/// @author Gnosis Developers\nlibrary GPv2Transfer {\n    using GPv2SafeERC20 for IERC20;\n\n    /// @dev Transfer data.\n    struct Data {\n        address account;\n        IERC20 token;\n        uint256 amount;\n        bytes32 balance;\n    }\n\n    /// @dev Ether marker address used to indicate an Ether transfer.\n    address internal constant BUY_ETH_ADDRESS =\n        0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n    /// @dev Execute the specified transfer from the specified account to a\n    /// recipient. The recipient will either receive internal Vault balances or\n    /// ERC20 token balances depending on whether the account is using internal\n    /// balances or not.\n    ///\n    /// This method is used for transferring fees to the settlement contract\n    /// when settling a single order directly with Balancer.\n    ///\n    /// Note that this method is subtly different from `transferFromAccounts`\n    /// with a single transfer with respect to how it deals with internal\n    /// balances. Specifically, this method will perform an **internal balance\n    /// transfer to the settlement contract instead of a withdrawal to the\n    /// external balance of the settlement contract** for trades that specify\n    /// trading with internal balances. This is done as a gas optimization in\n    /// the single order \"fast-path\".\n    ///\n    /// @param vault The Balancer vault to use.\n    /// @param transfer The transfer to perform specifying the sender account.\n    /// @param recipient The recipient for the transfer.\n    function fastTransferFromAccount(\n        IVault vault,\n        Data calldata transfer,\n        address recipient\n    ) internal {\n        require(\n            address(transfer.token) != BUY_ETH_ADDRESS,\n            \"GPv2: cannot transfer native ETH\"\n        );\n\n        if (transfer.balance == GPv2Order.BALANCE_ERC20) {\n            transfer.token.safeTransferFrom(\n                transfer.account,\n                recipient,\n                transfer.amount\n            );\n        } else {\n            IVault.UserBalanceOp[]\n                memory balanceOps = new IVault.UserBalanceOp[](1);\n\n            IVault.UserBalanceOp memory balanceOp = balanceOps[0];\n            balanceOp.kind = transfer.balance == GPv2Order.BALANCE_EXTERNAL\n                ? IVault.UserBalanceOpKind.TRANSFER_EXTERNAL\n                : IVault.UserBalanceOpKind.TRANSFER_INTERNAL;\n            balanceOp.asset = transfer.token;\n            balanceOp.amount = transfer.amount;\n            balanceOp.sender = transfer.account;\n            balanceOp.recipient = payable(recipient);\n\n            vault.manageUserBalance(balanceOps);\n        }\n    }\n\n    /// @dev Execute the specified transfers from the specified accounts to a\n    /// single recipient. The recipient will receive all transfers as ERC20\n    /// token balances, regardless of whether or not the accounts are using\n    /// internal Vault balances.\n    ///\n    /// This method is used for accumulating user balances into the settlement\n    /// contract.\n    ///\n    /// @param vault The Balancer vault to use.\n    /// @param transfers The batched transfers to perform specifying the\n    /// sender accounts.\n    /// @param recipient The single recipient for all the transfers.\n    function transferFromAccounts(\n        IVault vault,\n        Data[] calldata transfers,\n        address recipient\n    ) internal {\n        // NOTE: Allocate buffer of Vault balance operations large enough to\n        // hold all GP transfers. This is done to avoid re-allocations (which\n        // are gas inefficient) while still allowing all transfers to be batched\n        // into a single Vault call.\n        IVault.UserBalanceOp[] memory balanceOps = new IVault.UserBalanceOp[](\n            transfers.length\n        );\n        uint256 balanceOpCount = 0;\n\n        for (uint256 i = 0; i < transfers.length; i++) {\n            Data calldata transfer = transfers[i];\n            require(\n                address(transfer.token) != BUY_ETH_ADDRESS,\n                \"GPv2: cannot transfer native ETH\"\n            );\n\n            if (transfer.balance == GPv2Order.BALANCE_ERC20) {\n                transfer.token.safeTransferFrom(\n                    transfer.account,\n                    recipient,\n                    transfer.amount\n                );\n            } else {\n                IVault.UserBalanceOp memory balanceOp = balanceOps[\n                    balanceOpCount++\n                ];\n                balanceOp.kind = transfer.balance == GPv2Order.BALANCE_EXTERNAL\n                    ? IVault.UserBalanceOpKind.TRANSFER_EXTERNAL\n                    : IVault.UserBalanceOpKind.WITHDRAW_INTERNAL;\n                balanceOp.asset = transfer.token;\n                balanceOp.amount = transfer.amount;\n                balanceOp.sender = transfer.account;\n                balanceOp.recipient = payable(recipient);\n            }\n        }\n\n        if (balanceOpCount > 0) {\n            truncateBalanceOpsArray(balanceOps, balanceOpCount);\n            vault.manageUserBalance(balanceOps);\n        }\n    }\n\n    /// @dev Execute the specified transfers to their respective accounts.\n    ///\n    /// This method is used for paying out trade proceeds from the settlement\n    /// contract.\n    ///\n    /// @param vault The Balancer vault to use.\n    /// @param transfers The batched transfers to perform.\n    function transferToAccounts(\n        IVault vault,\n        Data[] memory transfers\n    ) internal {\n        IVault.UserBalanceOp[] memory balanceOps = new IVault.UserBalanceOp[](\n            transfers.length\n        );\n        uint256 balanceOpCount = 0;\n\n        for (uint256 i = 0; i < transfers.length; i++) {\n            Data memory transfer = transfers[i];\n\n            if (address(transfer.token) == BUY_ETH_ADDRESS) {\n                require(\n                    transfer.balance != GPv2Order.BALANCE_INTERNAL,\n                    \"GPv2: unsupported internal ETH\"\n                );\n                payable(transfer.account).transfer(transfer.amount);\n            } else if (transfer.balance == GPv2Order.BALANCE_ERC20) {\n                transfer.token.safeTransfer(transfer.account, transfer.amount);\n            } else {\n                IVault.UserBalanceOp memory balanceOp = balanceOps[\n                    balanceOpCount++\n                ];\n                balanceOp.kind = IVault.UserBalanceOpKind.DEPOSIT_INTERNAL;\n                balanceOp.asset = transfer.token;\n                balanceOp.amount = transfer.amount;\n                balanceOp.sender = address(this);\n                balanceOp.recipient = payable(transfer.account);\n            }\n        }\n\n        if (balanceOpCount > 0) {\n            truncateBalanceOpsArray(balanceOps, balanceOpCount);\n            vault.manageUserBalance(balanceOps);\n        }\n    }\n\n    /// @dev Truncate a Vault balance operation array to its actual size.\n    ///\n    /// This method **does not** check whether or not the new length is valid,\n    /// and specifying a size that is larger than the array's actual length is\n    /// undefined behaviour.\n    ///\n    /// @param balanceOps The memory array of balance operations to truncate.\n    /// @param newLength The new length to set.\n    function truncateBalanceOpsArray(\n        IVault.UserBalanceOp[] memory balanceOps,\n        uint256 newLength\n    ) private pure {\n        // NOTE: Truncate the vault transfers array to the specified length.\n        // This is done by setting the array's length which occupies the first\n        // word in memory pointed to by the `balanceOps` memory variable.\n        // <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html>\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            mstore(balanceOps, newLength)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (access/extensions/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.24;\n\nimport {IAccessControlEnumerable} from \"./IAccessControlEnumerable.sol\";\nimport {AccessControl} from \"../AccessControl.sol\";\nimport {EnumerableSet} from \"../../utils/structs/EnumerableSet.sol\";\nimport {IERC165} from \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    mapping(bytes32 role => EnumerableSet.AddressSet) private _roleMembers;\n\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) {\n        return _roleMembers[role].at(index);\n    }\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) {\n        return _roleMembers[role].length();\n    }\n\n    /**\n     * @dev Return all accounts that have `role`\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {\n        return _roleMembers[role].values();\n    }\n\n    /**\n     * @dev Overload {AccessControl-_grantRole} to track enumerable memberships\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        bool granted = super._grantRole(role, account);\n        if (granted) {\n            _roleMembers[role].add(account);\n        }\n        return granted;\n    }\n\n    /**\n     * @dev Overload {AccessControl-_revokeRole} to track enumerable memberships\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        bool revoked = super._revokeRole(role, account);\n        if (revoked) {\n            _roleMembers[role].remove(account);\n        }\n        return revoked;\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n\n// Vendored from OpenZeppelin contracts with minor modifications:\n// - Modified Solidity version\n// - Formatted code\n// - Added `name`, `symbol` and `decimals` function declarations\n// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC20/IERC20.sol>\n\npragma solidity >=0.7.6 <0.9.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the number of decimals the token uses.\n     */\n    function decimals() external view returns (uint8);\n\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(\n        address recipient,\n        uint256 amount\n    ) 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(\n        address owner,\n        address spender\n    ) 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(\n        address indexed owner,\n        address indexed spender,\n        uint256 value\n    );\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/access/IAccessControl.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted to signal this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Panic.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/extensions/IAccessControlEnumerable.sol)\n\npragma solidity >=0.8.4;\n\nimport {IAccessControl} from \"../IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC-165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n"},{"file_path":"src/interfaces/IFarm.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @notice Interface for an InfiniFi Farm contract\ninterface IFarm {\n    /// @notice emitted when there is a deposit of withdrawal from the farm\n    event AssetsUpdated(uint256 timestamp, uint256 assetsBefore, uint256 assetsAfter);\n\n    // --------------------------------------------------------------------\n    // Accounting\n    // --------------------------------------------------------------------\n\n    /// @notice the cap of the farm\n    function cap() external view returns (uint256);\n\n    /// @notice the asset used by deposits and withdrawals in the farm\n    function assetToken() external view returns (address);\n\n    /// @notice the total assets in the farm, reported as a balance of asset()\n    function assets() external view returns (uint256);\n\n    // --------------------------------------------------------------------\n    // Adapter logic\n    // --------------------------------------------------------------------\n    /// @notice deposit all asset() held by the contract into the farm\n    function deposit() external;\n\n    /// @notice Returns the max deposit amount for the underlying protocol\n    function maxDeposit() external view returns (uint256);\n\n    /// @notice withdraw an amount of the asset() from the farm\n    /// @param amount Amount of assets to withdraw\n    /// @param to Address to receive the withdrawn assets\n    function withdraw(uint256 amount, address to) external;\n\n    /// @notice available number of assetToken() withdrawable instantly from the farm\n    function liquidity() external view returns (uint256);\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/mixins/GPv2Signing.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\n\nimport \"../interfaces/GPv2EIP1271.sol\";\nimport \"../libraries/GPv2Order.sol\";\nimport \"../libraries/GPv2Trade.sol\";\n\n/// @title Gnosis Protocol v2 Signing Library.\n/// @author Gnosis Developers\nabstract contract GPv2Signing {\n    using GPv2Order for GPv2Order.Data;\n    using GPv2Order for bytes;\n\n    /// @dev Recovered trade data containing the extracted order and the\n    /// recovered owner address.\n    struct RecoveredOrder {\n        GPv2Order.Data data;\n        bytes uid;\n        address owner;\n        address receiver;\n    }\n\n    /// @dev Signing scheme used for recovery.\n    enum Scheme {\n        Eip712,\n        EthSign,\n        Eip1271,\n        PreSign\n    }\n\n    /// @dev The EIP-712 domain type hash used for computing the domain\n    /// separator.\n    bytes32 private constant DOMAIN_TYPE_HASH =\n        keccak256(\n            \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n        );\n\n    /// @dev The EIP-712 domain name used for computing the domain separator.\n    bytes32 private constant DOMAIN_NAME = keccak256(\"Gnosis Protocol\");\n\n    /// @dev The EIP-712 domain version used for computing the domain separator.\n    bytes32 private constant DOMAIN_VERSION = keccak256(\"v2\");\n\n    /// @dev Marker value indicating an order is pre-signed.\n    uint256 private constant PRE_SIGNED =\n        uint256(keccak256(\"GPv2Signing.Scheme.PreSign\"));\n\n    /// @dev The domain separator used for signing orders that gets mixed in\n    /// making signatures for different domains incompatible. This domain\n    /// separator is computed following the EIP-712 standard and has replay\n    /// protection mixed in so that signed orders are only valid for specific\n    /// GPv2 contracts.\n    bytes32 public immutable domainSeparator;\n\n    /// @dev Storage indicating whether or not an order has been signed by a\n    /// particular address.\n    mapping(bytes => uint256) public preSignature;\n\n    /// @dev Event that is emitted when an account either pre-signs an order or\n    /// revokes an existing pre-signature.\n    event PreSignature(address indexed owner, bytes orderUid, bool signed);\n\n    constructor() {\n        // NOTE: Currently, the only way to get the chain ID in solidity is\n        // using assembly.\n        uint256 chainId;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            chainId := chainid()\n        }\n\n        domainSeparator = keccak256(\n            abi.encode(\n                DOMAIN_TYPE_HASH,\n                DOMAIN_NAME,\n                DOMAIN_VERSION,\n                chainId,\n                address(this)\n            )\n        );\n    }\n\n    /// @dev Sets a presignature for the specified order UID.\n    ///\n    /// @param orderUid The unique identifier of the order to pre-sign.\n    /// @param signed True to set the order as tradable with pre-sign, false to\n    /// false to unset it.\n    function setPreSignature(bytes calldata orderUid, bool signed) external {\n        (, address owner, ) = orderUid.extractOrderUidParams();\n        require(owner == msg.sender, \"GPv2: cannot presign order\");\n        if (signed) {\n            preSignature[orderUid] = PRE_SIGNED;\n        } else {\n            preSignature[orderUid] = 0;\n        }\n        emit PreSignature(owner, orderUid, signed);\n    }\n\n    /// @dev Returns an empty recovered order with a pre-allocated buffer for\n    /// packing the unique identifier.\n    ///\n    /// @return recoveredOrder The empty recovered order data.\n    function allocateRecoveredOrder()\n        internal\n        pure\n        returns (RecoveredOrder memory recoveredOrder)\n    {\n        recoveredOrder.uid = new bytes(GPv2Order.UID_LENGTH);\n    }\n\n    /// @dev Extracts order data and recovers the signer from the specified\n    /// trade.\n    ///\n    /// @param recoveredOrder Memory location used for writing the recovered order data.\n    /// @param tokens The list of tokens included in the settlement. The token\n    /// indices in the trade parameters map to tokens in this array.\n    /// @param trade The trade data to recover the order data from.\n    function recoverOrderFromTrade(\n        RecoveredOrder memory recoveredOrder,\n        IERC20[] calldata tokens,\n        GPv2Trade.Data calldata trade\n    ) internal view {\n        GPv2Order.Data memory order = recoveredOrder.data;\n\n        Scheme signingScheme = GPv2Trade.extractOrder(trade, tokens, order);\n        (bytes32 orderDigest, address owner) = recoverOrderSigner(\n            order,\n            signingScheme,\n            trade.signature\n        );\n\n        recoveredOrder.uid.packOrderUidParams(\n            orderDigest,\n            owner,\n            order.validTo\n        );\n        recoveredOrder.owner = owner;\n        recoveredOrder.receiver = order.actualReceiver(owner);\n    }\n\n    /// @dev The length of any signature from an externally owned account.\n    uint256 private constant ECDSA_SIGNATURE_LENGTH = 65;\n\n    /// @dev Recovers an order's signer from the specified order and signature.\n    ///\n    /// @param order The order to recover a signature for.\n    /// @param signingScheme The signing scheme.\n    /// @param signature The signature bytes.\n    /// @return orderDigest The computed order hash.\n    /// @return owner The recovered address from the specified signature.\n    function recoverOrderSigner(\n        GPv2Order.Data memory order,\n        Scheme signingScheme,\n        bytes calldata signature\n    ) internal view returns (bytes32 orderDigest, address owner) {\n        orderDigest = order.hash(domainSeparator);\n        if (signingScheme == Scheme.Eip712) {\n            owner = recoverEip712Signer(orderDigest, signature);\n        } else if (signingScheme == Scheme.EthSign) {\n            owner = recoverEthsignSigner(orderDigest, signature);\n        } else if (signingScheme == Scheme.Eip1271) {\n            owner = recoverEip1271Signer(orderDigest, signature);\n        } else {\n            // signingScheme == Scheme.PreSign\n            owner = recoverPreSigner(orderDigest, signature, order.validTo);\n        }\n    }\n\n    /// @dev Perform an ECDSA recover for the specified message and calldata\n    /// signature.\n    ///\n    /// The signature is encoded by tighyly packing the following struct:\n    /// ```\n    /// struct EncodedSignature {\n    ///     bytes32 r;\n    ///     bytes32 s;\n    ///     uint8 v;\n    /// }\n    /// ```\n    ///\n    /// @param message The signed message.\n    /// @param encodedSignature The encoded signature.\n    function ecdsaRecover(\n        bytes32 message,\n        bytes calldata encodedSignature\n    ) internal pure returns (address signer) {\n        require(\n            encodedSignature.length == ECDSA_SIGNATURE_LENGTH,\n            \"GPv2: malformed ecdsa signature\"\n        );\n\n        bytes32 r;\n        bytes32 s;\n        uint8 v;\n\n        // NOTE: Use assembly to efficiently decode signature data.\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // r = uint256(encodedSignature[0:32])\n            r := calldataload(encodedSignature.offset)\n            // s = uint256(encodedSignature[32:64])\n            s := calldataload(add(encodedSignature.offset, 32))\n            // v = uint8(encodedSignature[64])\n            v := shr(248, calldataload(add(encodedSignature.offset, 64)))\n        }\n\n        signer = ecrecover(message, v, r, s);\n        require(signer != address(0), \"GPv2: invalid ecdsa signature\");\n    }\n\n    /// @dev Decodes signature bytes originating from an EIP-712-encoded\n    /// signature.\n    ///\n    /// EIP-712 signs typed data. The specifications are described in the\n    /// related EIP (<https://eips.ethereum.org/EIPS/eip-712>).\n    ///\n    /// EIP-712 signatures are encoded as standard ECDSA signatures as described\n    /// in the corresponding decoding function [`ecdsaRecover`].\n    ///\n    /// @param orderDigest The EIP-712 signing digest derived from the order\n    /// parameters.\n    /// @param encodedSignature Calldata pointing to tightly packed signature\n    /// bytes.\n    /// @return owner The address of the signer.\n    function recoverEip712Signer(\n        bytes32 orderDigest,\n        bytes calldata encodedSignature\n    ) internal pure returns (address owner) {\n        owner = ecdsaRecover(orderDigest, encodedSignature);\n    }\n\n    /// @dev Decodes signature bytes originating from the output of the eth_sign\n    /// RPC call.\n    ///\n    /// The specifications are described in the Ethereum documentation\n    /// (<https://eth.wiki/json-rpc/API#eth_sign>).\n    ///\n    /// eth_sign signatures are encoded as standard ECDSA signatures as\n    /// described in the corresponding decoding function\n    /// [`ecdsaRecover`].\n    ///\n    /// @param orderDigest The EIP-712 signing digest derived from the order\n    /// parameters.\n    /// @param encodedSignature Calldata pointing to tightly packed signature\n    /// bytes.\n    /// @return owner The address of the signer.\n    function recoverEthsignSigner(\n        bytes32 orderDigest,\n        bytes calldata encodedSignature\n    ) internal pure returns (address owner) {\n        // The signed message is encoded as:\n        // `\"\\x19Ethereum Signed Message:\\n\" || length || data`, where\n        // the length is a constant (32 bytes) and the data is defined as:\n        // `orderDigest`.\n        bytes32 ethsignDigest = keccak256(\n            abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", orderDigest)\n        );\n\n        owner = ecdsaRecover(ethsignDigest, encodedSignature);\n    }\n\n    /// @dev Verifies the input calldata as an EIP-1271 contract signature and\n    /// returns the address of the signer.\n    ///\n    /// The encoded signature tightly packs the following struct:\n    ///\n    /// ```\n    /// struct EncodedEip1271Signature {\n    ///     address owner;\n    ///     bytes signature;\n    /// }\n    /// ```\n    ///\n    /// This function enforces that the encoded data stores enough bytes to\n    /// cover the full length of the decoded signature.\n    ///\n    /// @param encodedSignature The encoded EIP-1271 signature.\n    /// @param orderDigest The EIP-712 signing digest derived from the order\n    /// parameters.\n    /// @return owner The address of the signer.\n    function recoverEip1271Signer(\n        bytes32 orderDigest,\n        bytes calldata encodedSignature\n    ) internal view returns (address owner) {\n        // NOTE: Use assembly to read the verifier address from the encoded\n        // signature bytes.\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // owner = address(encodedSignature[0:20])\n            owner := shr(96, calldataload(encodedSignature.offset))\n        }\n\n        // NOTE: Configure prettier to ignore the following line as it causes\n        // a panic in the Solidity plugin.\n        // prettier-ignore\n        bytes calldata signature = encodedSignature[20:];\n\n        require(\n            EIP1271Verifier(owner).isValidSignature(orderDigest, signature) ==\n                GPv2EIP1271.MAGICVALUE,\n            \"GPv2: invalid eip1271 signature\"\n        );\n    }\n\n    /// @dev Verifies the order has been pre-signed. The signature is the\n    /// address of the signer of the order.\n    ///\n    /// @param orderDigest The EIP-712 signing digest derived from the order\n    /// parameters.\n    /// @param encodedSignature The pre-sign signature reprenting the order UID.\n    /// @param validTo The order expiry timestamp.\n    /// @return owner The address of the signer.\n    function recoverPreSigner(\n        bytes32 orderDigest,\n        bytes calldata encodedSignature,\n        uint32 validTo\n    ) internal view returns (address owner) {\n        require(encodedSignature.length == 20, \"GPv2: malformed presignature\");\n        // NOTE: Use assembly to read the owner address from the encoded\n        // signature bytes.\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // owner = address(encodedSignature[0:20])\n            owner := shr(96, calldataload(encodedSignature.offset))\n        }\n\n        bytes memory orderUid = new bytes(GPv2Order.UID_LENGTH);\n        orderUid.packOrderUidParams(orderDigest, owner, validTo);\n\n        require(\n            preSignature[orderUid] == PRE_SIGNED,\n            \"GPv2: order not presigned\"\n        );\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) 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 a `value` amount of tokens as the allowance of `spender` over the\n     * 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 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Pausable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n    bool private _paused;\n\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    /**\n     * @dev The operation failed because the contract is paused.\n     */\n    error EnforcedPause();\n\n    /**\n     * @dev The operation failed because the contract is not paused.\n     */\n    error ExpectedPause();\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        if (paused()) {\n            revert EnforcedPause();\n        }\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        if (!paused()) {\n            revert ExpectedPause();\n        }\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/libraries/SafeMath.sol","source_code":"// SPDX-License-Identifier: MIT\n\n// Vendored from OpenZeppelin contracts with minor modifications:\n// - Modified Solidity version\n// - Formatted code\n// - Shortened some revert messages\n// - Removed unused methods\n// - Added `ceilDiv` method\n// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/math/SafeMath.sol>\n\npragma solidity >=0.7.6 <0.9.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b <= a, \"SafeMath: subtraction overflow\");\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) return 0;\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: mul overflow\");\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0, \"SafeMath: division by 0\");\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the ceiling integer division of two unsigned integers,\n     * reverting on division by zero. The result is rounded towards up the\n     * nearest integer, instead of truncating the fractional part.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     * - The sum of the dividend and divisor cannot overflow.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0, \"SafeMath: ceiling division by 0\");\n        return a / b + (a % b == 0 ? 0 : 1);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"src/integrations/farms/SwapFarmV2WithMaturity.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {SwapFarmV2} from \"@integrations/farms/SwapFarmV2.sol\";\nimport {IMaturityFarm} from \"@interfaces/IMaturityFarm.sol\";\n\n/// @title SwapFarmV2WithMaturity\n/// @notice SwapFarmV2 with a duration\ncontract SwapFarmV2WithMaturity is SwapFarmV2, IMaturityFarm {\n    /// @notice Duration of the farm (maturity() returns block.timestamp + duration)\n    uint256 public immutable duration;\n\n    constructor(\n        address _core,\n        address _assetToken,\n        address _accounting,\n        address _settlementContract,\n        address _vaultRelayer,\n        uint256 _duration\n    ) SwapFarmV2(_core, _assetToken, _accounting, _settlementContract, _vaultRelayer) {\n        duration = _duration;\n    }\n\n    function maturity() public view virtual override returns (uint256) {\n        return block.timestamp + duration;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},{"file_path":"src/interfaces/IMaturityFarm.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IFarm} from \"@interfaces/IFarm.sol\";\n\n/// @notice Interface for an InfiniFi Farm contract that has a maturity date\n/// @dev These farms represent illiquid farm/asset class\ninterface IMaturityFarm is IFarm {\n    /// @notice timestamp at which more funds can be made available for withdrawal\n    function maturity() external view returns (uint256);\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/interfaces/GPv2EIP1271.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\n\nlibrary GPv2EIP1271 {\n    /// @dev Value returned by a call to `isValidSignature` if the signature\n    /// was verified successfully. The value is defined in EIP-1271 as:\n    /// bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))\n    bytes4 internal constant MAGICVALUE = 0x1626ba7e;\n}\n\n/// @title EIP1271 Interface\n/// @dev Standardized interface for an implementation of smart contract\n/// signatures as described in EIP-1271. The code that follows is identical to\n/// the code in the standard with the exception of formatting and syntax\n/// changes to adapt the code to our Solidity version.\ninterface EIP1271Verifier {\n    /// @dev Should return whether the signature provided is valid for the\n    /// provided data\n    /// @param _hash      Hash of the data to be signed\n    /// @param _signature Signature byte array associated with _data\n    ///\n    /// MUST return the bytes4 magic value 0x1626ba7e when function passes.\n    /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for\n    /// solc > 0.5)\n    /// MUST allow external calls\n    ///\n    function isValidSignature(\n        bytes32 _hash,\n        bytes memory _signature\n    ) external view returns (bytes4 magicValue);\n}\n"},{"file_path":"src/integrations/CoWSwapBase.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {GPv2Settlement} from \"@cowprotocol/contracts/GPv2Settlement.sol\";\nimport {GPv2Order, IERC20 as ICoWERC20} from \"@cowprotocol/contracts/libraries/GPv2Order.sol\";\n\n/// @title Raw CoWSwap Base\n/// Allows implementations to submit sell orders to cowswap\nabstract contract CoWSwapBase {\n    using SafeERC20 for IERC20;\n\n    struct CoWSwapData {\n        address tokenIn;\n        address tokenOut;\n        uint256 amountIn;\n        uint256 minAmountOut;\n        uint256 maxSlippage;\n    }\n\n    event OrderSigned(\n        uint256 indexed timestamp, bytes orderUid, GPv2Order.Data order, uint32 validTo, uint256 buyAmount\n    );\n\n    error SwapCooldown();\n    error InvalidToken(address token);\n    error InvalidAmountIn(uint256 amountIn);\n    error InvalidAmountOut(uint256 minOut, uint256 provided);\n\n    /// @notice cooldown period between order signings\n    uint256 public constant _SIGN_COOLDOWN = 20 minutes;\n\n    /// @notice timestamp of last order\n    uint256 public lastOrderSignTimestamp = 1;\n\n    /// @notice if orders can not be submitted inside _SIGN_COOLDOWN window\n    bool public immutable enforceCooldown;\n\n    /// @notice address of the GPv2Settlement contract\n    address public immutable settlementContract;\n\n    /// @notice address of the GPv2VaultRelayer contract\n    address public immutable vaultRelayer;\n\n    constructor(address _settlementContract, address _vaultRelayer, bool _enforceCooldown) {\n        settlementContract = _settlementContract;\n        vaultRelayer = _vaultRelayer;\n        enforceCooldown = _enforceCooldown;\n    }\n\n    function _validateSwap(CoWSwapData memory _data) internal virtual;\n\n    function _checkSwapApproveAndSignOrder(CoWSwapData memory _data) internal returns (bytes memory) {\n        if (enforceCooldown) {\n            require(block.timestamp > lastOrderSignTimestamp + _SIGN_COOLDOWN, SwapCooldown());\n            lastOrderSignTimestamp = block.timestamp;\n        }\n\n        _validateSwap(_data);\n        IERC20(_data.tokenIn).forceApprove(vaultRelayer, _data.amountIn);\n        return _signOrder(_order(_data));\n    }\n\n    function _order(CoWSwapData memory _data) private view returns (GPv2Order.Data memory) {\n        return GPv2Order.Data({\n            sellToken: ICoWERC20(_data.tokenIn),\n            buyToken: ICoWERC20(_data.tokenOut),\n            receiver: address(this),\n            sellAmount: _data.amountIn,\n            buyAmount: _data.minAmountOut,\n            // casting to 'uint32' is safe because type(uint32).max timestamp is 2106-02-07\n            // forge-lint: disable-next-line(unsafe-typecast)\n            validTo: uint32(block.timestamp + _SIGN_COOLDOWN),\n            // keccak256 {\"appCode\":\"infiniFi\",\"version\":\"1.0.0\",\"metadata\":{}}\n            appData: 0x3cac71ef99d0dfbf5b937334b5b7ab672b679ba2bbd4d6fe8e0c54a2dab31109,\n            feeAmount: 0,\n            kind: GPv2Order.KIND_SELL,\n            partiallyFillable: false,\n            sellTokenBalance: GPv2Order.BALANCE_ERC20,\n            buyTokenBalance: GPv2Order.BALANCE_ERC20\n        });\n    }\n\n    function _signOrder(GPv2Order.Data memory order) private returns (bytes memory) {\n        GPv2Settlement settlement = GPv2Settlement(payable(settlementContract));\n        bytes32 orderDigest = GPv2Order.hash(order, settlement.domainSeparator());\n        bytes memory orderUid = new bytes(GPv2Order.UID_LENGTH);\n        GPv2Order.packOrderUidParams(orderUid, orderDigest, address(this), order.validTo);\n        settlement.setPreSignature(orderUid, true);\n\n        emit OrderSigned(block.timestamp, orderUid, order, order.validTo, order.buyAmount);\n        return orderUid;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * Both values are immutable: they can only be set once during construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /// @inheritdoc IERC20\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /// @inheritdoc IERC20\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation sets the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the `transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance < type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"},{"file_path":"src/libraries/CoreRoles.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @notice Holds a complete list of all roles which can be held by contracts inside the InfiniFi protocol.\nlibrary CoreRoles {\n    /// ----------- Core roles for access control --------------\n    /// @notice the all-powerful role. Controls all other roles and protocol functionality.\n    bytes32 internal constant GOVERNOR = keccak256(\"GOVERNOR\");\n\n    /// @notice Can pause contracts in an emergency.\n    bytes32 internal constant PAUSE = keccak256(\"PAUSE\");\n\n    /// @notice Can unpause contracts after an emergency.\n    bytes32 internal constant UNPAUSE = keccak256(\"UNPAUSE\");\n\n    /// @notice can tweak protocol parameters\n    bytes32 internal constant PROTOCOL_PARAMETERS = keccak256(\"PROTOCOL_PARAMETERS\");\n\n    /// @notice can manage minor roles\n    bytes32 internal constant MINOR_ROLES_MANAGER = keccak256(\"MINOR_ROLES_MANAGER\");\n\n    /// ----------- User Flow Management -----------------------\n\n    /// @notice Granted to the user entry point of the system\n    bytes32 internal constant ENTRY_POINT = keccak256(\"ENTRY_POINT\");\n\n    /// ----------- Token Management ---------------------------\n\n    /// @notice can mint ReceiptToken arbitrarily\n    bytes32 internal constant RECEIPT_TOKEN_MINTER = keccak256(\"RECEIPT_TOKEN_MINTER\");\n\n    /// @notice can burn ReceiptToken tokens\n    bytes32 internal constant RECEIPT_TOKEN_BURNER = keccak256(\"RECEIPT_TOKEN_BURNER\");\n\n    /// @notice can mint GovernanceToken arbitrarily\n    bytes32 internal constant GOVERNANCE_TOKEN_MINTER = keccak256(\"GOVERNANCE_TOKEN_MINTER\");\n\n    /// @notice can burn GovernanceToken tokens\n    bytes32 internal constant GOVERNANCE_TOKEN_BURNER = keccak256(\"GOVERNANCE_TOKEN_BURNER\");\n\n    /// @notice can mint arbitrarily & burn held LockedPositionToken\n    bytes32 internal constant LOCKED_TOKEN_MANAGER = keccak256(\"LOCKED_TOKEN_MANAGER\");\n\n    /// @notice can prevent transfers of LockedPositionToken\n    bytes32 internal constant TRANSFER_RESTRICTOR = keccak256(\"TRANSFER_RESTRICTOR\");\n\n    /// ----------- Funds Management & Accounting --------------\n\n    /// @notice contract that can allocate funds between farms\n    bytes32 internal constant FARM_MANAGER = keccak256(\"FARM_MANAGER\");\n\n    /// @notice addresses who can use the manual rebalancer\n    bytes32 internal constant MANUAL_REBALANCER = keccak256(\"MANUAL_REBALANCER\");\n\n    /// @notice addresses who can use the periodic rebalancer\n    bytes32 internal constant PERIODIC_REBALANCER = keccak256(\"PERIODIC_REBALANCER\");\n\n    /// @notice addresses who can move funds from farms to a safe address\n    bytes32 internal constant EMERGENCY_WITHDRAWAL = keccak256(\"EMERGENCY_WITHDRAWAL\");\n\n    /// @notice addresses who can trigger swaps in Farms\n    bytes32 internal constant FARM_SWAP_CALLER = keccak256(\"FARM_SWAP_CALLER\");\n\n    /// @notice can set oracles references within the system\n    bytes32 internal constant ORACLE_MANAGER = keccak256(\"ORACLE_MANAGER\");\n\n    /// @notice trusted to report profit and losses in the system.\n    /// This role can be used to slash depositors in case of losses, and\n    /// can also deposit profits for distribution to end users.\n    bytes32 internal constant FINANCE_MANAGER = keccak256(\"FINANCE_MANAGER\");\n\n    /// @notice can accrue pending yield in the system\n    bytes32 internal constant ACCRUE_YIELD = keccak256(\"ACCRUE_YIELD\");\n\n    /// ----------- Timelock management ------------------------\n    /// The hashes are the same as OpenZeppelins's roles in TimelockController\n\n    /// @notice can propose new actions in timelocks\n    bytes32 internal constant PROPOSER_ROLE = keccak256(\"PROPOSER_ROLE\");\n\n    /// @notice can execute actions in timelocks after their delay\n    bytes32 internal constant EXECUTOR_ROLE = keccak256(\"EXECUTOR_ROLE\");\n\n    /// @notice can cancel actions in timelocks\n    bytes32 internal constant CANCELLER_ROLE = keccak256(\"CANCELLER_ROLE\");\n\n    /// ----------- Crosschain ------------------------\n\n    /// @notice controls bridging and messaging process\n    bytes32 internal constant OUTLAND_PORTAL = keccak256(\"OUTLAND_PORTAL\");\n\n    /// @notice can execute operations required by offchain keeper\n    /// example is submitting burn proofs to circle gateway\n    /// portal should have keeper role as well\n    bytes32 internal constant OUTLAND_KEEPER = keccak256(\"OUTLAND_KEEPER\");\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/access/AccessControl.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 role => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /// @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        return _roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (!hasRole(role, account)) {\n            _roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (hasRole(role, account)) {\n            _roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/libraries/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n\n// Vendored from OpenZeppelin contracts with minor modifications:\n// - Modified Solidity version\n// - Formatted code\n// - Shortened revert messages\n// - Removed unused methods\n// - Convert to `type(*).*` notation\n// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/utils/SafeCast.sol>\n\npragma solidity >=0.7.6 <0.9.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: not positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        require(\n            value <= uint256(type(int256).max),\n            \"SafeCast: int256 overflow\"\n        );\n        return int256(value);\n    }\n}\n"},{"file_path":"lib/solmate/src/utils/FixedPointMathLib.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\n/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)\nlibrary FixedPointMathLib {\n    /*//////////////////////////////////////////////////////////////\n                    SIMPLIFIED FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal constant MAX_UINT256 = 2**256 - 1;\n\n    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n    }\n\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n    }\n\n    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n    }\n\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                    LOW LEVEL FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function mulDivDown(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // Divide x * y by the denominator.\n            z := div(mul(x, y), denominator)\n        }\n    }\n\n    function mulDivUp(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // If x * y modulo the denominator is strictly greater than 0,\n            // 1 is added to round up the division of x * y by the denominator.\n            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))\n        }\n    }\n\n    function rpow(\n        uint256 x,\n        uint256 n,\n        uint256 scalar\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            switch x\n            case 0 {\n                switch n\n                case 0 {\n                    // 0 ** 0 = 1\n                    z := scalar\n                }\n                default {\n                    // 0 ** n = 0\n                    z := 0\n                }\n            }\n            default {\n                switch mod(n, 2)\n                case 0 {\n                    // If n is even, store scalar in z for now.\n                    z := scalar\n                }\n                default {\n                    // If n is odd, store x in z for now.\n                    z := x\n                }\n\n                // Shifting right by 1 is like dividing by 2.\n                let half := shr(1, scalar)\n\n                for {\n                    // Shift n right by 1 before looping to halve it.\n                    n := shr(1, n)\n                } n {\n                    // Shift n right by 1 each iteration to halve it.\n                    n := shr(1, n)\n                } {\n                    // Revert immediately if x ** 2 would overflow.\n                    // Equivalent to iszero(eq(div(xx, x), x)) here.\n                    if shr(128, x) {\n                        revert(0, 0)\n                    }\n\n                    // Store x squared.\n                    let xx := mul(x, x)\n\n                    // Round to the nearest number.\n                    let xxRound := add(xx, half)\n\n                    // Revert if xx + half overflowed.\n                    if lt(xxRound, xx) {\n                        revert(0, 0)\n                    }\n\n                    // Set x to scaled xxRound.\n                    x := div(xxRound, scalar)\n\n                    // If n is even:\n                    if mod(n, 2) {\n                        // Compute z * x.\n                        let zx := mul(z, x)\n\n                        // If z * x overflowed:\n                        if iszero(eq(div(zx, x), z)) {\n                            // Revert if x is non-zero.\n                            if iszero(iszero(x)) {\n                                revert(0, 0)\n                            }\n                        }\n\n                        // Round to the nearest number.\n                        let zxRound := add(zx, half)\n\n                        // Revert if zx + half overflowed.\n                        if lt(zxRound, zx) {\n                            revert(0, 0)\n                        }\n\n                        // Return properly scaled zxRound.\n                        z := div(zxRound, scalar)\n                    }\n                }\n            }\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        GENERAL NUMBER UTILITIES\n    //////////////////////////////////////////////////////////////*/\n\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let y := x // We start y at x, which will help us make our initial estimate.\n\n            z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n            // We check y >= 2^(k + 8) but shift right by k bits\n            // each branch to ensure that if x >= 256, then y >= 256.\n            if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n                y := shr(128, y)\n                z := shl(64, z)\n            }\n            if iszero(lt(y, 0x1000000000000000000)) {\n                y := shr(64, y)\n                z := shl(32, z)\n            }\n            if iszero(lt(y, 0x10000000000)) {\n                y := shr(32, y)\n                z := shl(16, z)\n            }\n            if iszero(lt(y, 0x1000000)) {\n                y := shr(16, y)\n                z := shl(8, z)\n            }\n\n            // Goal was to get z*z*y within a small factor of x. More iterations could\n            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n            // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n            // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n            // There is no overflow risk here since y < 2^136 after the first branch above.\n            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            // If x+1 is a perfect square, the Babylonian method cycles between\n            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Mod x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            z := mod(x, y)\n        }\n    }\n\n    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Divide x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            r := div(x, y)\n        }\n    }\n\n    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Add 1 to x * y if x % y > 0. Note this will\n            // return 0 instead of reverting if y is zero.\n            z := add(gt(mod(x, y), 0), div(x, y))\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/mixins/ReentrancyGuard.sol","source_code":"// SPDX-License-Identifier: MIT\n\n// Vendored from OpenZeppelin contracts with minor modifications:\n// - Modified Solidity version\n// - Formatted code\n// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/utils/ReentrancyGuard.sol>\n\npragma solidity >=0.7.6 <0.9.0;\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        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\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"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Context.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"src/core/InfiniFiCore.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {AccessControlEnumerable} from \"@openzeppelin/contracts/access/extensions/AccessControlEnumerable.sol\";\n\n/// @notice Maintains roles and access control\ncontract InfiniFiCore is AccessControlEnumerable {\n    error RoleAlreadyExists(bytes32 role);\n    error RoleDoesNotExist(bytes32 role);\n    error LengthMismatch(uint256 expected, uint256 actual);\n\n    /// @notice construct Core\n    constructor() {\n        // For initial setup before going live, deployer can then call\n        // renounceRole(bytes32 role, address account)\n        _grantRole(CoreRoles.GOVERNOR, msg.sender);\n\n        // Initial roles setup: direct hierarchy, everything under governor\n        _setRoleAdmin(CoreRoles.GOVERNOR, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.PAUSE, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.UNPAUSE, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.PROTOCOL_PARAMETERS, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.MINOR_ROLES_MANAGER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.ENTRY_POINT, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.RECEIPT_TOKEN_MINTER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.RECEIPT_TOKEN_BURNER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.GOVERNANCE_TOKEN_MINTER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.GOVERNANCE_TOKEN_BURNER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.LOCKED_TOKEN_MANAGER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.TRANSFER_RESTRICTOR, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.FARM_MANAGER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.MANUAL_REBALANCER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.PERIODIC_REBALANCER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.EMERGENCY_WITHDRAWAL, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.FARM_SWAP_CALLER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.ORACLE_MANAGER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.FINANCE_MANAGER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.PROPOSER_ROLE, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.EXECUTOR_ROLE, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.CANCELLER_ROLE, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.OUTLAND_PORTAL, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.OUTLAND_KEEPER, CoreRoles.GOVERNOR);\n        _setRoleAdmin(CoreRoles.ACCRUE_YIELD, CoreRoles.GOVERNOR);\n    }\n\n    /// @notice creates a new role to be maintained\n    /// @param role the new role id\n    /// @param adminRole the admin role id for `role`\n    function createRole(bytes32 role, bytes32 adminRole) external onlyRole(CoreRoles.GOVERNOR) {\n        require(getRoleAdmin(role) == bytes32(0), RoleAlreadyExists(role));\n        _setRoleAdmin(role, adminRole);\n    }\n\n    /// @notice override admin role of an existing role\n    /// @param role the role id\n    /// @param adminRole the admin role id\n    function setRoleAdmin(bytes32 role, bytes32 adminRole) external onlyRole(CoreRoles.GOVERNOR) {\n        require(getRoleAdmin(role) != bytes32(0), RoleDoesNotExist(role));\n        _setRoleAdmin(role, adminRole);\n    }\n\n    /// @notice batch granting of roles to various addresses\n    /// @dev if msg.sender does not have admin role needed to grant any of the\n    /// granted roles, the whole transaction reverts.\n    function grantRoles(bytes32[] calldata roles, address[] calldata accounts) external {\n        require(roles.length == accounts.length, LengthMismatch(roles.length, accounts.length));\n        for (uint256 i = 0; i < roles.length; i++) {\n            _checkRole(getRoleAdmin(roles[i]));\n            _grantRole(roles[i], accounts[i]);\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/interfaces/IVault.sol","source_code":"// 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.6 <0.9.0;\npragma abicoder v2;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Minimal interface for the Vault core contract only containing methods\n * used by Gnosis Protocol V2. Original source:\n * <https://github.com/balancer-labs/balancer-core-v2/blob/v1.0.0/contracts/vault/interfaces/IVault.sol>\n */\ninterface IVault {\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 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        IERC20 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 {\n        DEPOSIT_INTERNAL,\n        WITHDRAW_INTERNAL,\n        TRANSFER_INTERNAL,\n        TRANSFER_EXTERNAL\n    }\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 {\n        GIVEN_IN,\n        GIVEN_OUT\n    }\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        IERC20 assetIn;\n        IERC20 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        IERC20[] 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 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"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in a uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev A uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},{"file_path":"src/finance/Accounting.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {FixedPointMathLib} from \"@solmate/src/utils/FixedPointMathLib.sol\";\n\nimport {IFarm} from \"@interfaces/IFarm.sol\";\nimport {IOracle} from \"@interfaces/IOracle.sol\";\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {FarmRegistry} from \"@integrations/FarmRegistry.sol\";\nimport {CoreControlled} from \"@core/CoreControlled.sol\";\n\n/// @notice InfiniFi Accounting contract\ncontract Accounting is CoreControlled {\n    using FixedPointMathLib for uint256;\n\n    event PriceSet(uint256 indexed timestamp, address indexed asset, uint256 price);\n    event OracleSet(uint256 indexed timestamp, address indexed asset, address oracle);\n\n    /// @notice reference to the farm registry\n    address public immutable farmRegistry;\n\n    constructor(address _core, address _farmRegistry) CoreControlled(_core) {\n        farmRegistry = _farmRegistry;\n    }\n\n    /// @notice mapping from asset to oracle\n    mapping(address => address) public oracle;\n\n    /// @notice returns the price of an asset\n    function price(address _asset) external view returns (uint256) {\n        return IOracle(oracle[_asset]).price();\n    }\n\n    /// @notice set the oracle for an asset\n    function setOracle(address _asset, address _oracle) external onlyCoreRole(CoreRoles.ORACLE_MANAGER) {\n        oracle[_asset] = _oracle;\n        emit OracleSet(block.timestamp, _asset, _oracle);\n    }\n\n    /// -------------------------------------------------------------------------------------------\n    /// Reference token getters (e.g. USD for iUSD, ETH for iETH, ...)\n    /// @dev note that the \"USD\" token does not exist, it is just an abstract unit of account\n    /// used in the protocol to represent stablecoins pegged to USD, that allows to uniformly\n    /// account for a diverse reserve composed of USDC, DAI, FRAX, etc.\n    /// -------------------------------------------------------------------------------------------\n\n    /// @notice returns the sum of the value of all assets held on protocol contracts listed in the farm registry.\n    function totalAssetsValue() external view returns (uint256 _totalValue) {\n        address[] memory assets = FarmRegistry(farmRegistry).getEnabledAssets();\n        for (uint256 i = 0; i < assets.length; i++) {\n            uint256 assetPrice = IOracle(oracle[assets[i]]).price();\n            uint256 _assets = _calculateTotalAssets(FarmRegistry(farmRegistry).getAssetFarms(assets[i]));\n            _totalValue += _assets.mulWadDown(assetPrice);\n        }\n    }\n\n    /// @notice returns the sum of the value of all liquid assets held on protocol contracts listed in the farm registry.\n    /// @dev see totalAssetsValue()\n    function totalAssetsValueOf(uint256 _type) external view returns (uint256 _totalValue) {\n        address[] memory assets = FarmRegistry(farmRegistry).getEnabledAssets();\n        for (uint256 i = 0; i < assets.length; i++) {\n            uint256 assetPrice = IOracle(oracle[assets[i]]).price();\n            address[] memory assetFarms = FarmRegistry(farmRegistry).getAssetTypeFarms(assets[i], uint256(_type));\n            uint256 _assets = _calculateTotalAssets(assetFarms);\n            _totalValue += _assets.mulWadDown(assetPrice);\n        }\n    }\n\n    /// -------------------------------------------------------------------------------------------\n    /// Specific asset getters (e.g. USDC, DAI, ...)\n    /// -------------------------------------------------------------------------------------------\n\n    /// @notice returns the sum of the balance of all farms of a given asset.\n    function totalAssets(address _asset) external view returns (uint256) {\n        return _calculateTotalAssets(FarmRegistry(farmRegistry).getAssetFarms(_asset));\n    }\n\n    function totalAssetsOf(address _asset, uint256 _type) external view returns (uint256) {\n        return _calculateTotalAssets(FarmRegistry(farmRegistry).getAssetTypeFarms(_asset, uint256(_type)));\n    }\n\n    /// -------------------------------------------------------------------------------------------\n    /// Internal helpers\n    /// -------------------------------------------------------------------------------------------\n\n    function _calculateTotalAssets(address[] memory _farms) internal view returns (uint256 _totalAssets) {\n        uint256 length = _farms.length;\n        for (uint256 index = 0; index < length; index++) {\n            _totalAssets += IFarm(_farms[index]).assets();\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/libraries/GPv2Order.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\n\nimport \"../interfaces/IERC20.sol\";\n\n/// @title Gnosis Protocol v2 Order Library\n/// @author Gnosis Developers\nlibrary GPv2Order {\n    /// @dev The complete data for a Gnosis Protocol order. This struct contains\n    /// all order parameters that are signed for submitting to GP.\n    struct Data {\n        IERC20 sellToken;\n        IERC20 buyToken;\n        address receiver;\n        uint256 sellAmount;\n        uint256 buyAmount;\n        uint32 validTo;\n        bytes32 appData;\n        uint256 feeAmount;\n        bytes32 kind;\n        bool partiallyFillable;\n        bytes32 sellTokenBalance;\n        bytes32 buyTokenBalance;\n    }\n\n    /// @dev The order EIP-712 type hash for the [`GPv2Order.Data`] struct.\n    ///\n    /// This value is pre-computed from the following expression:\n    /// ```\n    /// keccak256(\n    ///     \"Order(\" +\n    ///         \"address sellToken,\" +\n    ///         \"address buyToken,\" +\n    ///         \"address receiver,\" +\n    ///         \"uint256 sellAmount,\" +\n    ///         \"uint256 buyAmount,\" +\n    ///         \"uint32 validTo,\" +\n    ///         \"bytes32 appData,\" +\n    ///         \"uint256 feeAmount,\" +\n    ///         \"string kind,\" +\n    ///         \"bool partiallyFillable,\" +\n    ///         \"string sellTokenBalance,\" +\n    ///         \"string buyTokenBalance\" +\n    ///     \")\"\n    /// )\n    /// ```\n    bytes32 internal constant TYPE_HASH =\n        hex\"d5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e489\";\n\n    /// @dev The marker value for a sell order for computing the order struct\n    /// hash. This allows the EIP-712 compatible wallets to display a\n    /// descriptive string for the order kind (instead of 0 or 1).\n    ///\n    /// This value is pre-computed from the following expression:\n    /// ```\n    /// keccak256(\"sell\")\n    /// ```\n    bytes32 internal constant KIND_SELL =\n        hex\"f3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee346775\";\n\n    /// @dev The OrderKind marker value for a buy order for computing the order\n    /// struct hash.\n    ///\n    /// This value is pre-computed from the following expression:\n    /// ```\n    /// keccak256(\"buy\")\n    /// ```\n    bytes32 internal constant KIND_BUY =\n        hex\"6ed88e868af0a1983e3886d5f3e95a2fafbd6c3450bc229e27342283dc429ccc\";\n\n    /// @dev The TokenBalance marker value for using direct ERC20 balances for\n    /// computing the order struct hash.\n    ///\n    /// This value is pre-computed from the following expression:\n    /// ```\n    /// keccak256(\"erc20\")\n    /// ```\n    bytes32 internal constant BALANCE_ERC20 =\n        hex\"5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9\";\n\n    /// @dev The TokenBalance marker value for using Balancer Vault external\n    /// balances (in order to re-use Vault ERC20 approvals) for computing the\n    /// order struct hash.\n    ///\n    /// This value is pre-computed from the following expression:\n    /// ```\n    /// keccak256(\"external\")\n    /// ```\n    bytes32 internal constant BALANCE_EXTERNAL =\n        hex\"abee3b73373acd583a130924aad6dc38cfdc44ba0555ba94ce2ff63980ea0632\";\n\n    /// @dev The TokenBalance marker value for using Balancer Vault internal\n    /// balances for computing the order struct hash.\n    ///\n    /// This value is pre-computed from the following expression:\n    /// ```\n    /// keccak256(\"internal\")\n    /// ```\n    bytes32 internal constant BALANCE_INTERNAL =\n        hex\"4ac99ace14ee0a5ef932dc609df0943ab7ac16b7583634612f8dc35a4289a6ce\";\n\n    /// @dev Marker address used to indicate that the receiver of the trade\n    /// proceeds should the owner of the order.\n    ///\n    /// This is chosen to be `address(0)` for gas efficiency as it is expected\n    /// to be the most common case.\n    address internal constant RECEIVER_SAME_AS_OWNER = address(0);\n\n    /// @dev The byte length of an order unique identifier.\n    uint256 internal constant UID_LENGTH = 56;\n\n    /// @dev Returns the actual receiver for an order. This function checks\n    /// whether or not the [`receiver`] field uses the marker value to indicate\n    /// it is the same as the order owner.\n    ///\n    /// @return receiver The actual receiver of trade proceeds.\n    function actualReceiver(\n        Data memory order,\n        address owner\n    ) internal pure returns (address receiver) {\n        if (order.receiver == RECEIVER_SAME_AS_OWNER) {\n            receiver = owner;\n        } else {\n            receiver = order.receiver;\n        }\n    }\n\n    /// @dev Return the EIP-712 signing hash for the specified order.\n    ///\n    /// @param order The order to compute the EIP-712 signing hash for.\n    /// @param domainSeparator The EIP-712 domain separator to use.\n    /// @return orderDigest The 32 byte EIP-712 struct hash.\n    function hash(\n        Data memory order,\n        bytes32 domainSeparator\n    ) internal pure returns (bytes32 orderDigest) {\n        bytes32 structHash;\n\n        // NOTE: Compute the EIP-712 order struct hash in place. As suggested\n        // in the EIP proposal, noting that the order struct has 12 fields, and\n        // prefixing the type hash `(1 + 12) * 32 = 416` bytes to hash.\n        // <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#rationale-for-encodedata>\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let dataStart := sub(order, 32)\n            let temp := mload(dataStart)\n            mstore(dataStart, TYPE_HASH)\n            structHash := keccak256(dataStart, 416)\n            mstore(dataStart, temp)\n        }\n\n        // NOTE: Now that we have the struct hash, compute the EIP-712 signing\n        // hash using scratch memory past the free memory pointer. The signing\n        // hash is computed from `\"\\x19\\x01\" || domainSeparator || structHash`.\n        // <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory>\n        // <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification>\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let freeMemoryPointer := mload(0x40)\n            mstore(freeMemoryPointer, \"\\x19\\x01\")\n            mstore(add(freeMemoryPointer, 2), domainSeparator)\n            mstore(add(freeMemoryPointer, 34), structHash)\n            orderDigest := keccak256(freeMemoryPointer, 66)\n        }\n    }\n\n    /// @dev Packs order UID parameters into the specified memory location. The\n    /// result is equivalent to `abi.encodePacked(...)` with the difference that\n    /// it allows re-using the memory for packing the order UID.\n    ///\n    /// This function reverts if the order UID buffer is not the correct size.\n    ///\n    /// @param orderUid The buffer pack the order UID parameters into.\n    /// @param orderDigest The EIP-712 struct digest derived from the order\n    /// parameters.\n    /// @param owner The address of the user who owns this order.\n    /// @param validTo The epoch time at which the order will stop being valid.\n    function packOrderUidParams(\n        bytes memory orderUid,\n        bytes32 orderDigest,\n        address owner,\n        uint32 validTo\n    ) internal pure {\n        require(orderUid.length == UID_LENGTH, \"GPv2: uid buffer overflow\");\n\n        // NOTE: Write the order UID to the allocated memory buffer. The order\n        // parameters are written to memory in **reverse order** as memory\n        // operations write 32-bytes at a time and we want to use a packed\n        // encoding. This means, for example, that after writing the value of\n        // `owner` to bytes `20:52`, writing the `orderDigest` to bytes `0:32`\n        // will **overwrite** bytes `20:32`. This is desirable as addresses are\n        // only 20 bytes and `20:32` should be `0`s:\n        //\n        //        |           1111111111222222222233333333334444444444555555\n        //   byte | 01234567890123456789012345678901234567890123456789012345\n        // -------+---------------------------------------------------------\n        //  field | [.........orderDigest..........][......owner.......][vT]\n        // -------+---------------------------------------------------------\n        // mstore |                         [000000000000000000000000000.vT]\n        //        |                     [00000000000.......owner.......]\n        //        | [.........orderDigest..........]\n        //\n        // Additionally, since Solidity `bytes memory` are length prefixed,\n        // 32 needs to be added to all the offsets.\n        //\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            mstore(add(orderUid, 56), validTo)\n            mstore(add(orderUid, 52), owner)\n            mstore(add(orderUid, 32), orderDigest)\n        }\n    }\n\n    /// @dev Extracts specific order information from the standardized unique\n    /// order id of the protocol.\n    ///\n    /// @param orderUid The unique identifier used to represent an order in\n    /// the protocol. This uid is the packed concatenation of the order digest,\n    /// the validTo order parameter and the address of the user who created the\n    /// order. It is used by the user to interface with the contract directly,\n    /// and not by calls that are triggered by the solvers.\n    /// @return orderDigest The EIP-712 signing digest derived from the order\n    /// parameters.\n    /// @return owner The address of the user who owns this order.\n    /// @return validTo The epoch time at which the order will stop being valid.\n    function extractOrderUidParams(\n        bytes calldata orderUid\n    )\n        internal\n        pure\n        returns (bytes32 orderDigest, address owner, uint32 validTo)\n    {\n        require(orderUid.length == UID_LENGTH, \"GPv2: invalid uid\");\n\n        // Use assembly to efficiently decode packed calldata.\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            orderDigest := calldataload(orderUid.offset)\n            owner := shr(96, calldataload(add(orderUid.offset, 32)))\n            validTo := shr(224, calldataload(add(orderUid.offset, 52)))\n        }\n    }\n}\n"},{"file_path":"src/integrations/FarmRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IFarm} from \"@interfaces/IFarm.sol\";\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {CoreControlled} from \"@core/CoreControlled.sol\";\n\n/// @notice InfiniFi Farm registry\ncontract FarmRegistry is CoreControlled {\n    error FarmAlreadyAdded(address farm);\n    error FarmNotFound(address farm);\n    error AssetNotEnabled(address farm, address asset);\n    error AssetAlreadyEnabled(address asset);\n    error AssetNotFound(address asset);\n\n    event AssetEnabled(uint256 indexed timestamp, address asset);\n    event AssetDisabled(uint256 indexed timestamp, address asset);\n    event FarmsAdded(uint256 indexed timestamp, uint256 farmType, address[] indexed farms);\n    event FarmsRemoved(uint256 indexed timestamp, uint256 farmType, address[] indexed farms);\n\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    EnumerableSet.AddressSet private assets;\n    EnumerableSet.AddressSet private farms;\n    mapping(uint256 _type => EnumerableSet.AddressSet _farms) private typeFarms;\n    mapping(address _asset => EnumerableSet.AddressSet _farms) private assetFarms;\n    mapping(address _asset => mapping(uint256 _type => EnumerableSet.AddressSet _farms)) private assetTypeFarms;\n\n    constructor(address _core) CoreControlled(_core) {}\n\n    /// ----------------------------------------------------------------------------\n    /// READ METHODS\n    /// ----------------------------------------------------------------------------\n\n    function getEnabledAssets() external view returns (address[] memory) {\n        return assets.values();\n    }\n\n    function isAssetEnabled(address _asset) external view returns (bool) {\n        return assets.contains(_asset);\n    }\n\n    function getFarms() external view returns (address[] memory) {\n        return farms.values();\n    }\n\n    function getTypeFarms(uint256 _type) external view returns (address[] memory) {\n        return typeFarms[_type].values();\n    }\n\n    function getAssetFarms(address _asset) external view returns (address[] memory) {\n        return assetFarms[_asset].values();\n    }\n\n    function getAssetTypeFarms(address _asset, uint256 _type) external view returns (address[] memory) {\n        return assetTypeFarms[_asset][_type].values();\n    }\n\n    function isFarm(address _farm) external view returns (bool) {\n        return farms.contains(_farm);\n    }\n\n    function isFarmOfAsset(address _farm, address _asset) external view returns (bool) {\n        return assetFarms[_asset].contains(_farm);\n    }\n\n    function isFarmOfType(address _farm, uint256 _type) external view returns (bool) {\n        return typeFarms[_type].contains(_farm);\n    }\n\n    /// ----------------------------------------------------------------------------\n    /// WRITE METHODS\n    /// ----------------------------------------------------------------------------\n\n    function enableAsset(address _asset) external onlyCoreRole(CoreRoles.GOVERNOR) {\n        require(assets.add(_asset), AssetAlreadyEnabled(_asset));\n        emit AssetEnabled(block.timestamp, _asset);\n    }\n\n    function disableAsset(address _asset) external onlyCoreRole(CoreRoles.GOVERNOR) {\n        require(assets.remove(_asset), AssetNotFound(_asset));\n        emit AssetDisabled(block.timestamp, _asset);\n    }\n\n    function addFarms(uint256 _type, address[] calldata _list) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        _addFarms(_type, _list);\n        emit FarmsAdded(block.timestamp, _type, _list);\n    }\n\n    function removeFarms(uint256 _type, address[] calldata _list) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        _removeFarms(_type, _list);\n        emit FarmsRemoved(block.timestamp, _type, _list);\n    }\n\n    /// ----------------------------------------------------------------------------\n    /// INTERNAL METHODS\n    /// ----------------------------------------------------------------------------\n\n    function _addFarms(uint256 _type, address[] calldata _list) internal {\n        for (uint256 i = 0; i < _list.length; i++) {\n            address farmAsset = IFarm(_list[i]).assetToken();\n            require(assets.contains(farmAsset), AssetNotEnabled(_list[i], farmAsset));\n            require(farms.add(_list[i]), FarmAlreadyAdded(_list[i]));\n            require(typeFarms[_type].add(_list[i]), FarmAlreadyAdded(_list[i]));\n            require(assetFarms[farmAsset].add(_list[i]), FarmAlreadyAdded(_list[i]));\n            require(assetTypeFarms[farmAsset][_type].add(_list[i]), FarmAlreadyAdded(_list[i]));\n        }\n    }\n\n    function _removeFarms(uint256 _type, address[] calldata _list) internal {\n        for (uint256 i = 0; i < _list.length; i++) {\n            address farmAsset = IFarm(_list[i]).assetToken();\n            require(farms.remove(_list[i]), FarmNotFound(_list[i]));\n            require(typeFarms[_type].remove(_list[i]), FarmNotFound(_list[i]));\n            require(assetFarms[farmAsset].remove(_list[i]), FarmNotFound(_list[i]));\n            require(assetTypeFarms[farmAsset][_type].remove(_list[i]), FarmNotFound(_list[i]));\n        }\n    }\n}\n"},{"file_path":"src/interfaces/aave/IAaveV4Spoke.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IAaveV4Hub {\n    function getAssetLiquidity(uint256 assetId) external view returns (uint256);\n    function getAddedShares(uint256 assetId) external view returns (uint256);\n    function getAssetDeficitRay(uint256 assetId) external view returns (uint256);\n}\n\ninterface IAaveV4Spoke {\n    struct Reserve {\n        address underlying;\n        address hub;\n        uint16 assetId;\n        uint8 decimals;\n        uint24 collateralRisk;\n        uint8 flags;\n        uint32 dynamicConfigKey;\n    }\n\n    struct ReserveConfig {\n        uint24 collateralRisk;\n        bool paused;\n        bool frozen;\n        bool borrowable;\n        bool receiveSharesEnabled;\n    }\n\n    struct UserPosition {\n        uint120 drawnShares;\n        uint120 premiumShares;\n        int200 premiumOffsetRay;\n        uint120 suppliedShares;\n        uint32 dynamicConfigKey;\n    }\n\n    function supply(uint256 reserveId, uint256 amount, address onBehalfOf) external returns (uint256, uint256);\n    function withdraw(uint256 reserveId, uint256 amount, address onBehalfOf) external returns (uint256, uint256);\n    function getReserve(uint256 reserveId) external view returns (Reserve memory);\n    function getReserveConfig(uint256 reserveId) external view returns (ReserveConfig memory);\n    function getUserPosition(uint256 reserveId, address user) external view returns (UserPosition memory);\n    function getUserSuppliedAssets(uint256 reserveId, address user) external view returns (uint256);\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/GPv2VaultRelayer.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\npragma abicoder v2;\n\nimport \"./interfaces/IERC20.sol\";\nimport \"./interfaces/IVault.sol\";\nimport \"./libraries/GPv2Transfer.sol\";\n\n/// @title Gnosis Protocol v2 Vault Relayer Contract\n/// @author Gnosis Developers\ncontract GPv2VaultRelayer {\n    using GPv2Transfer for IVault;\n\n    /// @dev The creator of the contract which has special permissions. This\n    /// value is set at creation time and cannot change.\n    address private immutable creator;\n\n    /// @dev The vault this relayer is for.\n    IVault private immutable vault;\n\n    constructor(IVault vault_) {\n        creator = msg.sender;\n        vault = vault_;\n    }\n\n    /// @dev Modifier that ensures that a function can only be called by the\n    /// creator of this contract.\n    modifier onlyCreator() {\n        require(msg.sender == creator, \"GPv2: not creator\");\n        _;\n    }\n\n    /// @dev Transfers all sell amounts for the executed trades from their\n    /// owners to the caller.\n    ///\n    /// This function reverts if:\n    /// - The caller is not the creator of the vault relayer\n    /// - Any ERC20 transfer fails\n    ///\n    /// @param transfers The transfers to execute.\n    function transferFromAccounts(\n        GPv2Transfer.Data[] calldata transfers\n    ) external onlyCreator {\n        vault.transferFromAccounts(transfers, msg.sender);\n    }\n\n    /// @dev Performs a Balancer batched swap on behalf of a user and sends a\n    /// fee to the caller.\n    ///\n    /// This function reverts if:\n    /// - The caller is not the creator of the vault relayer\n    /// - The swap fails\n    /// - The fee transfer fails\n    ///\n    /// @param kind The Balancer swap kind, this can either be `GIVEN_IN` for\n    /// sell orders or `GIVEN_OUT` for buy orders.\n    /// @param swaps The swaps to perform.\n    /// @param tokens The tokens for the swaps. Swaps encode to and from tokens\n    /// as indices into this array.\n    /// @param funds The fund management settings, specifying the user the swap\n    /// is being performed for as well as the recipient of the proceeds.\n    /// @param limits Swap limits for encoding limit prices.\n    /// @param deadline The deadline for the swap.\n    /// @param feeTransfer The transfer data for the caller fee.\n    /// @return tokenDeltas The executed swap amounts.\n    function batchSwapWithFee(\n        IVault.SwapKind kind,\n        IVault.BatchSwapStep[] calldata swaps,\n        IERC20[] memory tokens,\n        IVault.FundManagement memory funds,\n        int256[] memory limits,\n        uint256 deadline,\n        GPv2Transfer.Data calldata feeTransfer\n    ) external onlyCreator returns (int256[] memory tokenDeltas) {\n        tokenDeltas = vault.batchSwap(\n            kind,\n            swaps,\n            tokens,\n            funds,\n            limits,\n            deadline\n        );\n        vault.fastTransferFromAccount(feeTransfer, msg.sender);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/Comparators.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides a set of functions to compare values.\n *\n * _Available since v5.1._\n */\nlibrary Comparators {\n    function lt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a < b;\n    }\n\n    function gt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a > b;\n    }\n}\n"},{"file_path":"src/integrations/MultiAssetFarmV2.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {FixedPointMathLib} from \"@solmate/src/utils/FixedPointMathLib.sol\";\n\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {Accounting} from \"@finance/Accounting.sol\";\nimport {Farm} from \"@integrations/Farm.sol\";\n\n/// @title MultiAssetFarmV2\n/// @notice InfiniFi Farm that can hold multiple asset tokens.\n/// @dev This abstract contract extends the base Farm contract to support multiple asset tokens.\n/// @dev It provides functionality to manage supported assets, convert between them using oracle prices,\n/// @dev and handle deposits/withdrawals of various asset types.\nabstract contract MultiAssetFarmV2 is Farm {\n    using SafeERC20 for ERC20;\n    using FixedPointMathLib for uint256;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @notice Emitted when a new asset is enabled for the farm\n    /// @param timestamp The block timestamp when the asset was enabled\n    /// @param asset The address of the enabled asset token\n    event AssetEnabled(uint256 indexed timestamp, address asset);\n\n    /// @notice Emitted when an asset is disabled for the farm\n    /// @param timestamp The block timestamp when the asset was disabled\n    /// @param asset The address of the disabled asset token\n    event AssetDisabled(uint256 indexed timestamp, address asset);\n\n    /// @notice Thrown when an invalid array length is provided\n    error InvalidLength();\n\n    /// @notice Thrown when an invalid farm address is provided\n    /// @param farm The invalid farm address\n    error InvalidFarm(address farm);\n\n    /// @notice Thrown when an invalid asset address is provided\n    /// @param asset The invalid asset address\n    error InvalidAsset(address asset);\n\n    /// @notice Thrown when an asset doesn't have a valid oracle\n    /// @param _asset The asset address without a valid oracle\n    error InvalidOracle(address _asset);\n\n    /// @notice Thrown when trying to disable an asset with non-zero balance\n    /// @param _asset The asset address with non-zero balance\n    /// @param _balance The current balance of the asset\n    error InvalidBalance(address _asset, uint256 _balance);\n\n    /// @notice Base amount of assets required to prevent removal without decimals\n    uint256 public constant ASSET_REMOVAL_THRESHOLD = 1;\n\n    /// @notice Reference to the accounting contract used for price oracles and asset management\n    address public immutable accounting;\n\n    /// @notice Set of supported asset tokens (excluding the primary assetToken)\n    EnumerableSet.AddressSet private _assetTokens;\n\n    /// @notice Constructor for MultiAssetFarmV2\n    /// @param _core The address of the core contract\n    /// @param _assetToken The primary asset token for this farm\n    /// @param _accounting The address of the accounting contract\n    constructor(address _core, address _assetToken, address _accounting) Farm(_core, _assetToken) {\n        accounting = _accounting;\n    }\n\n    /// @notice Returns the list of asset tokens that the farm can hold\n    /// @dev MUST include the assetToken of the farm\n    /// @dev MUST only include tokens that can be freely airdropped to the farm\n    /// while being accounted properly in the assets() function\n    /// @return Array of supported asset token addresses\n    function assetTokens() public view virtual returns (address[] memory) {\n        return _assetTokens.values();\n    }\n\n    /// @notice Checks if the farm can hold the given asset token\n    /// @param _asset The asset token address to check\n    /// @return True if the asset is supported, false otherwise\n    function isAssetSupported(address _asset) public view virtual returns (bool) {\n        return _asset == assetToken || (_assetTokens.contains(_asset) && _hasOracle(_asset));\n    }\n\n    /// @notice Returns the total value of all assets held by the farm in terms of the primary assetToken\n    /// @dev Note that there may be conversion fees between supported assets and the assetToken.\n    /// This is not reflected in the amount returned by assets()\n    /// @return Total value of all assets in terms of the primary assetToken\n    function assets() public view virtual override returns (uint256) {\n        uint256 assetTokenBalance = ERC20(assetToken).balanceOf(address(this));\n        uint256 assetTokenPrice = Accounting(accounting).price(assetToken);\n\n        address[] memory supportedAssets = assetTokens();\n        for (uint256 i = 0; i < supportedAssets.length; i++) {\n            if (supportedAssets[i] == assetToken) continue;\n            uint256 balance = ERC20(supportedAssets[i]).balanceOf(address(this));\n            if (balance == 0) continue; // do not read price if the balance is 0 to save gas\n            uint256 price = Accounting(accounting).price(supportedAssets[i]);\n            assetTokenBalance += balance.mulDivDown(price, assetTokenPrice);\n        }\n\n        return assetTokenBalance;\n    }\n\n    /// @notice Returns the current liquidity of the farm (held reference assetToken)\n    /// @return The balance of the primary assetToken held by the farm\n    function liquidity() public view override returns (uint256) {\n        return ERC20(assetToken).balanceOf(address(this));\n    }\n\n    /// @notice Converts a number of tokens to another token based on oracle rates\n    /// @param _tokenIn The input token address\n    /// @param _tokenOut The output token address\n    /// @param _amountIn The amount of input tokens to convert\n    /// @return The equivalent amount of output tokens\n    function convert(address _tokenIn, address _tokenOut, uint256 _amountIn) public view returns (uint256) {\n        if (_tokenIn == _tokenOut) return _amountIn;\n        uint256 tokenInPrice = Accounting(accounting).price(_tokenIn);\n        uint256 tokenOutPrice = Accounting(accounting).price(_tokenOut);\n        return _amountIn.mulDivDown(tokenInPrice, tokenOutPrice);\n    }\n\n    /// @notice Enables a set of assets that will be reported by this farm\n    /// @param _assetList Array of asset token addresses to enable\n    function enableAssets(address[] calldata _assetList) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        require(_assetList.length > 0, InvalidLength());\n        for (uint256 i = 0; i < _assetList.length; i++) {\n            address _asset = _assetList[i];\n            require(!isAssetSupported(_asset), InvalidAsset(_asset));\n            _enableAsset(_asset);\n        }\n    }\n\n    /// @notice Disables a set of assets that are no longer required by this farm\n    /// @param _assetList Array of asset token addresses to disable\n    function disableAssets(address[] calldata _assetList) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        require(_assetList.length > 0, InvalidLength());\n        for (uint256 i = 0; i < _assetList.length; i++) {\n            _disableAsset(_assetList[i]);\n        }\n    }\n\n    /// @dev Deposit does nothing, assetTokens are just held on this farm\n    /// @dev There should be other functions to do conversions between the assetTokens or deploying\n    /// the funds to a productive yield source\n    /// @param _amount The amount to deposit (unused in this implementation)\n    function _deposit(uint256 _amount) internal view virtual override {}\n\n    /// @notice Deposits assets into the farm (used for airdrops)\n    /// @dev Note that in airdrops we do not know the amount of assets before the deposit,\n    /// therefore we emit an event that contains twice the assets after the deposit\n    function deposit() external virtual override onlyCoreRole(CoreRoles.FARM_MANAGER) whenNotPaused {\n        uint256 currentAssets = assets();\n        if (currentAssets > cap) {\n            revert CapExceeded(currentAssets, cap);\n        }\n\n        _deposit(0);\n\n        /// @dev note that in airdrops we do not know the amount of assets before the deposit,\n        /// therefore we emit an event that contains twice the assets after the deposit.\n        emit AssetsUpdated(block.timestamp, currentAssets, currentAssets);\n    }\n\n    /// @dev Withdrawal can only handle the reference assetToken (i.e. the liquidity())\n    /// @dev There should be other functions to do conversions between the assetTokens or pulling\n    /// the funds out of a productive yield source\n    /// @param _amount The amount of assetToken to withdraw\n    /// @param _to The address to send the withdrawn tokens to\n    function _withdraw(uint256 _amount, address _to) internal virtual override {\n        ERC20(assetToken).safeTransfer(_to, _amount);\n    }\n\n    /// @notice Withdraws the reference assetToken from the farm\n    /// @param amount The amount of assetToken to withdraw\n    /// @param to The address to send the withdrawn tokens to\n    function withdraw(uint256 amount, address to)\n        external\n        virtual\n        override\n        onlyCoreRole(CoreRoles.FARM_MANAGER)\n        whenNotPaused\n    {\n        uint256 assetsBefore = assets();\n        _withdraw(amount, to);\n\n        emit AssetsUpdated(block.timestamp, assetsBefore, assetsBefore - amount);\n    }\n\n    /// @notice Withdraws any supported secondary asset tokens from the farm\n    /// @param _asset The address of the asset token to withdraw\n    /// @param _amount The amount of the asset to withdraw\n    /// @param _to The address to send the withdrawn tokens to\n    function withdrawSecondaryAsset(address _asset, uint256 _amount, address _to)\n        external\n        virtual\n        onlyCoreRole(CoreRoles.FARM_MANAGER)\n        whenNotPaused\n    {\n        require(isAssetSupported(_asset) && _asset != assetToken, InvalidAsset(_asset));\n\n        uint256 assetsBefore = assets();\n        ERC20(_asset).safeTransfer(_to, _amount);\n        uint256 assetsAfter = assets();\n\n        emit AssetsUpdated(block.timestamp, assetsBefore, assetsAfter);\n    }\n\n    /// @notice Internal function to enable a new asset for the farm\n    /// @param _asset The address of the asset token to enable\n    /// @dev Can add if already added but doesn't hurt as it is a set\n    function _enableAsset(address _asset) internal {\n        require(_hasOracle(_asset), InvalidOracle(_asset));\n        // Oracle has to exist in order for new assets to be added\n        _assetTokens.add(_asset);\n        emit AssetEnabled(block.timestamp, _asset);\n    }\n\n    /// @dev Internal function to disable an asset for the farm\n    /// @param _asset The address of the asset token to disable\n    function _disableAsset(address _asset) internal {\n        require(_asset != assetToken, InvalidAsset(_asset));\n        require(isAssetSupported(_asset), InvalidAsset(_asset));\n\n        // do not allow removal of nonzero balance assets\n        uint256 balance = ERC20(_asset).balanceOf(address(this));\n        uint256 decimals = ERC20(_asset).decimals();\n        require(balance <= ASSET_REMOVAL_THRESHOLD * 10 ** decimals, InvalidBalance(_asset, balance));\n\n        _assetTokens.remove(_asset);\n        emit AssetDisabled(block.timestamp, _asset);\n    }\n\n    function _hasOracle(address _asset) internal view returns (bool) {\n        try Accounting(accounting).price(_asset) returns (uint256 _price) {\n            return _price > 0;\n        } catch {\n            return false;\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/mixins/StorageAccessible.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-only\n\n// Vendored from Gnosis utility contracts with minor modifications:\n// - Modified Solidity version\n// - Formatted code\n// - Added linter directives to ignore low level call and assembly warnings\n// <https://github.com/gnosis/util-contracts/blob/v3.1.0-solc-7/contracts/StorageAccessible.sol>\n\npragma solidity >=0.7.6 <0.9.0;\n\n/// @title ViewStorageAccessible - Interface on top of StorageAccessible base class to allow simulations from view functions\ninterface ViewStorageAccessible {\n    /**\n     * @dev Same as `simulateDelegatecall` on StorageAccessible. Marked as view so that it can be called from external contracts\n     * that want to run simulations from within view functions. Will revert if the invoked simulation attempts to change state.\n     */\n    function simulateDelegatecall(\n        address targetContract,\n        bytes memory calldataPayload\n    ) external view returns (bytes memory);\n\n    /**\n     * @dev Same as `getStorageAt` on StorageAccessible. This method allows reading aribtrary ranges of storage.\n     */\n    function getStorageAt(\n        uint256 offset,\n        uint256 length\n    ) external view returns (bytes memory);\n}\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\ncontract StorageAccessible {\n    /**\n     * @dev Reads `length` bytes of storage in the currents contract\n     * @param offset - the offset in the current contract's storage in words to start reading from\n     * @param length - the number of words (32 bytes) of data to read\n     * @return the bytes that were read.\n     */\n    function getStorageAt(\n        uint256 offset,\n        uint256 length\n    ) external view returns (bytes memory) {\n        bytes memory result = new bytes(length * 32);\n        for (uint256 index = 0; index < length; index++) {\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                let word := sload(add(offset, index))\n                mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Performs a delegetecall on a targetContract in the context of self.\n     * Internally reverts execution to avoid side effects (making it static). Catches revert and returns encoded result as bytes.\n     * @param targetContract Address of the contract containing the code to execute.\n     * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n     */\n    function simulateDelegatecall(\n        address targetContract,\n        bytes memory calldataPayload\n    ) public returns (bytes memory response) {\n        bytes memory innerCall = abi.encodeWithSelector(\n            this.simulateDelegatecallInternal.selector,\n            targetContract,\n            calldataPayload\n        );\n        // solhint-disable-next-line avoid-low-level-calls\n        (, response) = address(this).call(innerCall);\n        bool innerSuccess = response[response.length - 1] == 0x01;\n        setLength(response, response.length - 1);\n        if (innerSuccess) {\n            return response;\n        } else {\n            revertWith(response);\n        }\n    }\n\n    /**\n     * @dev Performs a delegetecall on a targetContract in the context of self.\n     * Internally reverts execution to avoid side effects (making it static). Returns encoded result as revert message\n     * concatenated with the success flag of the inner call as a last byte.\n     * @param targetContract Address of the contract containing the code to execute.\n     * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n     */\n    function simulateDelegatecallInternal(\n        address targetContract,\n        bytes memory calldataPayload\n    ) external returns (bytes memory response) {\n        bool success;\n        // solhint-disable-next-line avoid-low-level-calls\n        (success, response) = targetContract.delegatecall(calldataPayload);\n        revertWith(abi.encodePacked(response, success));\n    }\n\n    function revertWith(bytes memory response) internal pure {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            revert(add(response, 0x20), mload(response))\n        }\n    }\n\n    function setLength(bytes memory buffer, uint256 length) internal pure {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            mstore(buffer, length)\n        }\n    }\n}\n"},{"file_path":"src/integrations/Farm.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {FixedPointMathLib} from \"@solmate/src/utils/FixedPointMathLib.sol\";\n\nimport {IFarm} from \"@interfaces/IFarm.sol\";\nimport {CoreRoles} from \"@libraries/CoreRoles.sol\";\nimport {CoreControlled} from \"@core/CoreControlled.sol\";\n\n/// @notice InfiniFi Farm base contract\nabstract contract Farm is CoreControlled, IFarm {\n    using FixedPointMathLib for uint256;\n\n    address public immutable assetToken;\n\n    /// @notice cap on the amount of assets that can be deposited into the farm\n    uint256 public cap;\n\n    /// @notice Max slippage for depositing and witdhrawing assets from the farm.\n    /// @dev Stored as a percentage with 18 decimals of precision, of the minimum\n    /// position size compared to the previous position size (so actually 1 - slippage).\n    /// @dev Set to 0 to disable slippage checks.\n    uint256 public maxSlippage;\n\n    /// @notice reference to the rewards claimer contract\n    address public rewardContract;\n\n    error CapExceeded(uint256 newAmount, uint256 cap);\n    error SlippageTooHigh(uint256 minAssetsOut, uint256 assetsReceived);\n    error ZeroAddress(address);\n    error RewardsNotEnabled();\n    error RewardsClaimFailed();\n    error RewardsClaimLostAssets();\n\n    event CapUpdated(uint256 newCap);\n    event MaxSlippageUpdated(uint256 newMaxSlippage);\n    event RewardContractUpdated(uint256 indexed timestamp, address rewardContract);\n    event Claimed(uint256 indexed timestamp, uint256 amount);\n\n    constructor(address _core, address _assetToken) CoreControlled(_core) {\n        assetToken = _assetToken;\n        cap = type(uint256).max;\n\n        // default to 99.9999%\n        // most farms should not have deposits/withdrawals fees, unless explicitly\n        // implemented, and should at worst round against depositors which should\n        // only cause some wei of losses when our farms do a deposit/withdraw.\n        maxSlippage = 0.999999e18;\n    }\n\n    /// @notice used to check slippage on vault operations\n    modifier checkSlippage() {\n        uint256 assetsBefore = assets();\n        _;\n        uint256 assetsAfter = assets();\n        uint256 minAssetsAfter = assetsBefore.mulWadDown(maxSlippage);\n        require(assetsAfter >= minAssetsAfter, SlippageTooHigh(minAssetsAfter, assetsAfter));\n    }\n\n    function setRewardContract(address _rewardContract) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        require(_rewardContract != address(0), ZeroAddress(_rewardContract));\n        rewardContract = _rewardContract;\n        emit RewardContractUpdated(block.timestamp, _rewardContract);\n    }\n\n    /// @notice set the deposit cap of the farm\n    function setCap(uint256 _newCap) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        cap = _newCap;\n        emit CapUpdated(_newCap);\n    }\n\n    /// @notice set the max tolerated slippage for depositing and witdhrawing assets from the farm\n    function setMaxSlippage(uint256 _maxSlippage) external onlyCoreRole(CoreRoles.PROTOCOL_PARAMETERS) {\n        maxSlippage = _maxSlippage;\n        emit MaxSlippageUpdated(_maxSlippage);\n    }\n\n    // --------------------------------------------------------------------\n    // Accounting\n    // --------------------------------------------------------------------\n\n    function assets() public view virtual returns (uint256);\n\n    // --------------------------------------------------------------------\n    // Adapter logic\n    // --------------------------------------------------------------------\n\n    function maxDeposit() external view virtual returns (uint256) {\n        uint256 currentAssets = assets();\n        if (currentAssets >= cap) {\n            return 0;\n        }\n        return cap - currentAssets;\n    }\n\n    function deposit() external virtual onlyCoreRole(CoreRoles.FARM_MANAGER) whenNotPaused {\n        uint256 assetsToDeposit = ERC20(assetToken).balanceOf(address(this));\n        uint256 assetsBefore = assets();\n\n        if (assetsBefore + assetsToDeposit > cap) {\n            revert CapExceeded(assetsBefore + assetsToDeposit, cap);\n        }\n\n        _deposit(assetsToDeposit);\n\n        uint256 assetsAfter = assets();\n        uint256 assetsReceived = assetsAfter - assetsBefore;\n\n        // check slippage\n        uint256 minAssetsOut = assetsToDeposit.mulWadDown(maxSlippage);\n        require(assetsReceived >= minAssetsOut, SlippageTooHigh(minAssetsOut, assetsReceived));\n\n        emit AssetsUpdated(block.timestamp, assetsBefore, assetsAfter);\n    }\n\n    function _deposit(uint256 assetsToDeposit) internal virtual;\n\n    function withdraw(uint256 amount, address to) external virtual onlyCoreRole(CoreRoles.FARM_MANAGER) whenNotPaused {\n        uint256 assetsBefore = assets();\n        uint256 receiverBalanceBefore = ERC20(assetToken).balanceOf(to);\n\n        _withdraw(amount, to);\n\n        uint256 assetsAfter = assets();\n        uint256 receiverBalanceAfter = ERC20(assetToken).balanceOf(to);\n\n        uint256 assetsSpent = assetsBefore - assetsAfter;\n        uint256 receiverBalanceIncrease = receiverBalanceAfter - receiverBalanceBefore;\n        assert(receiverBalanceIncrease == amount); // sanity check for _withdraw implementations, should never fail\n\n        uint256 minAssetsOut = assetsSpent.mulWadDown(maxSlippage);\n        require(amount >= minAssetsOut, SlippageTooHigh(minAssetsOut, amount));\n\n        emit AssetsUpdated(block.timestamp, assetsBefore, assetsAfter);\n    }\n\n    /// @dev MAY spend more than _amount of assets() if there is slippage or rounding errors.\n    /// @dev MUST transfer exactly _amount of assets() to _to (or withdraw will revert)\n    function _withdraw(uint256 _amount, address _to) internal virtual;\n\n    // --------------------------------------------------------------------\n    // Rewards claiming\n    // --------------------------------------------------------------------\n    function claimRewards(bytes memory _calldata) external whenNotPaused onlyCoreRole(CoreRoles.FARM_SWAP_CALLER) {\n        address _rewardContract = rewardContract;\n        require(_rewardContract != address(0), RewardsNotEnabled());\n\n        uint256 assetsBefore = assets();\n\n        (bool success,) = _rewardContract.call(_calldata);\n        require(success, RewardsClaimFailed());\n\n        uint256 assetsAfter = assets();\n        require(assetsAfter >= assetsBefore, RewardsClaimLostAssets());\n\n        emit Claimed(block.timestamp, assetsAfter - assetsBefore);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/SlotDerivation.sol)\n// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots\n * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by\n * the solidity language / compiler.\n *\n * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].\n *\n * Example usage:\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using StorageSlot for bytes32;\n *     using SlotDerivation for *;\n *\n *     // Declare a namespace\n *     string private constant _NAMESPACE = \"<namespace>\"; // eg. OpenZeppelin.Slot\n *\n *     function setValueInNamespace(uint256 key, address newValue) internal {\n *         _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;\n *     }\n *\n *     function getValueInNamespace(uint256 key) internal view returns (address) {\n *         return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {StorageSlot}.\n *\n * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking\n * upgrade safety will ignore the slots accessed through this library.\n *\n * _Available since v5.1._\n */\nlibrary SlotDerivation {\n    /**\n     * @dev Derive an ERC-7201 slot from a string (namespace).\n     */\n    function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))\n            slot := and(keccak256(0x00, 0x20), not(0xff))\n        }\n    }\n\n    /**\n     * @dev Add an offset to a slot to get the n-th element of a structure or an array.\n     */\n    function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {\n        unchecked {\n            return bytes32(uint256(slot) + pos);\n        }\n    }\n\n    /**\n     * @dev Derive the location of the first element in an array from the slot where the length is stored.\n     */\n    function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, slot)\n            result := keccak256(0x00, 0x20)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, and(key, shr(96, not(0))))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, iszero(iszero(key)))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /// @inheritdoc IERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-721.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/libraries/GPv2Interaction.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\n\n/// @title Gnosis Protocol v2 Interaction Library\n/// @author Gnosis Developers\nlibrary GPv2Interaction {\n    /// @dev Interaction data for performing arbitrary contract interactions.\n    /// Submitted to [`GPv2Settlement.settle`] for code execution.\n    struct Data {\n        address target;\n        uint256 value;\n        bytes callData;\n    }\n\n    /// @dev Execute an arbitrary contract interaction.\n    ///\n    /// @param interaction Interaction data.\n    function execute(Data calldata interaction) internal {\n        address target = interaction.target;\n        uint256 value = interaction.value;\n        bytes calldata callData = interaction.callData;\n\n        // NOTE: Use assembly to call the interaction instead of a low level\n        // call for two reasons:\n        // - We don't want to copy the return data, since we discard it for\n        // interactions.\n        // - Solidity will under certain conditions generate code to copy input\n        // calldata twice to memory (the second being a \"memcopy loop\").\n        // <https://github.com/gnosis/gp-v2-contracts/pull/417#issuecomment-775091258>\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let freeMemoryPointer := mload(0x40)\n            calldatacopy(freeMemoryPointer, callData.offset, callData.length)\n            if iszero(\n                call(\n                    gas(),\n                    target,\n                    value,\n                    freeMemoryPointer,\n                    callData.length,\n                    0,\n                    0\n                )\n            ) {\n                returndatacopy(0, 0, returndatasize())\n                revert(0, returndatasize())\n            }\n        }\n    }\n\n    /// @dev Extracts the Solidity ABI selector for the specified interaction.\n    ///\n    /// @param interaction Interaction data.\n    /// @return result The 4 byte function selector of the call encoded in\n    /// this interaction.\n    function selector(\n        Data calldata interaction\n    ) internal pure returns (bytes4 result) {\n        bytes calldata callData = interaction.callData;\n        if (callData.length >= 4) {\n            // NOTE: Read the first word of the interaction's calldata. The\n            // value does not need to be shifted since `bytesN` values are left\n            // aligned, and the value does not need to be masked since masking\n            // occurs when the value is accessed and not stored:\n            // <https://docs.soliditylang.org/en/v0.7.6/abi-spec.html#encoding-of-indexed-event-parameters>\n            // <https://docs.soliditylang.org/en/v0.7.6/assembly.html#access-to-external-variables-functions-and-libraries>\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                result := calldataload(callData.offset)\n            }\n        }\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/libraries/GPv2Trade.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\n\nimport \"../interfaces/IERC20.sol\";\nimport \"../mixins/GPv2Signing.sol\";\nimport \"./GPv2Order.sol\";\n\n/// @title Gnosis Protocol v2 Trade Library.\n/// @author Gnosis Developers\nlibrary GPv2Trade {\n    using GPv2Order for GPv2Order.Data;\n    using GPv2Order for bytes;\n\n    /// @dev A struct representing a trade to be executed as part a batch\n    /// settlement.\n    struct Data {\n        uint256 sellTokenIndex;\n        uint256 buyTokenIndex;\n        address receiver;\n        uint256 sellAmount;\n        uint256 buyAmount;\n        uint32 validTo;\n        bytes32 appData;\n        uint256 feeAmount;\n        uint256 flags;\n        uint256 executedAmount;\n        bytes signature;\n    }\n\n    /// @dev Extracts the order data and signing scheme for the specified trade.\n    ///\n    /// @param trade The trade.\n    /// @param tokens The list of tokens included in the settlement. The token\n    /// indices in the trade parameters map to tokens in this array.\n    /// @param order The memory location to extract the order data to.\n    function extractOrder(\n        Data calldata trade,\n        IERC20[] calldata tokens,\n        GPv2Order.Data memory order\n    ) internal pure returns (GPv2Signing.Scheme signingScheme) {\n        order.sellToken = tokens[trade.sellTokenIndex];\n        order.buyToken = tokens[trade.buyTokenIndex];\n        order.receiver = trade.receiver;\n        order.sellAmount = trade.sellAmount;\n        order.buyAmount = trade.buyAmount;\n        order.validTo = trade.validTo;\n        order.appData = trade.appData;\n        order.feeAmount = trade.feeAmount;\n        (\n            order.kind,\n            order.partiallyFillable,\n            order.sellTokenBalance,\n            order.buyTokenBalance,\n            signingScheme\n        ) = extractFlags(trade.flags);\n    }\n\n    /// @dev Decodes trade flags.\n    ///\n    /// Trade flags are used to tightly encode information on how to decode\n    /// an order. Examples that directly affect the structure of an order are\n    /// the kind of order (either a sell or a buy order) as well as whether the\n    /// order is partially fillable or if it is a \"fill-or-kill\" order. It also\n    /// encodes the signature scheme used to validate the order. As the most\n    /// likely values are fill-or-kill sell orders by an externally owned\n    /// account, the flags are chosen such that `0x00` represents this kind of\n    /// order. The flags byte uses the following format:\n    ///\n    /// ```\n    /// bit | 31 ...   | 6 | 5 | 4 | 3 | 2 | 1 | 0 |\n    /// ----+----------+-------+---+-------+---+---+\n    ///     | reserved | *   * | * | *   * | * | * |\n    ///                  |   |   |   |   |   |   |\n    ///                  |   |   |   |   |   |   +---- order kind bit, 0 for a sell order\n    ///                  |   |   |   |   |   |         and 1 for a buy order\n    ///                  |   |   |   |   |   |\n    ///                  |   |   |   |   |   +-------- order fill bit, 0 for fill-or-kill\n    ///                  |   |   |   |   |             and 1 for a partially fillable order\n    ///                  |   |   |   |   |\n    ///                  |   |   |   +---+------------ use internal sell token balance bit:\n    ///                  |   |   |                     0x: ERC20 token balance\n    ///                  |   |   |                     10: external Balancer Vault balance\n    ///                  |   |   |                     11: internal Balancer Vault balance\n    ///                  |   |   |\n    ///                  |   |   +-------------------- use buy token balance bit\n    ///                  |   |                         0: ERC20 token balance\n    ///                  |   |                         1: internal Balancer Vault balance\n    ///                  |   |\n    ///                  +---+------------------------ signature scheme bits:\n    ///                                                00: EIP-712\n    ///                                                01: eth_sign\n    ///                                                10: EIP-1271\n    ///                                                11: pre_sign\n    /// ```\n    function extractFlags(\n        uint256 flags\n    )\n        internal\n        pure\n        returns (\n            bytes32 kind,\n            bool partiallyFillable,\n            bytes32 sellTokenBalance,\n            bytes32 buyTokenBalance,\n            GPv2Signing.Scheme signingScheme\n        )\n    {\n        if (flags & 0x01 == 0) {\n            kind = GPv2Order.KIND_SELL;\n        } else {\n            kind = GPv2Order.KIND_BUY;\n        }\n        partiallyFillable = flags & 0x02 != 0;\n        if (flags & 0x08 == 0) {\n            sellTokenBalance = GPv2Order.BALANCE_ERC20;\n        } else if (flags & 0x04 == 0) {\n            sellTokenBalance = GPv2Order.BALANCE_EXTERNAL;\n        } else {\n            sellTokenBalance = GPv2Order.BALANCE_INTERNAL;\n        }\n        if (flags & 0x10 == 0) {\n            buyTokenBalance = GPv2Order.BALANCE_ERC20;\n        } else {\n            buyTokenBalance = GPv2Order.BALANCE_INTERNAL;\n        }\n\n        // NOTE: Take advantage of the fact that Solidity will revert if the\n        // following expression does not produce a valid enum value. This means\n        // we check here that the leading reserved bits must be 0.\n        signingScheme = GPv2Signing.Scheme(flags >> 5);\n    }\n}\n"},{"file_path":"lib/cowprotocol/src/contracts/libraries/GPv2SafeERC20.sol","source_code":"// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.7.6 <0.9.0;\n\nimport \"../interfaces/IERC20.sol\";\n\n/// @title Gnosis Protocol v2 Safe ERC20 Transfer Library\n/// @author Gnosis Developers\n/// @dev Gas-efficient version of Openzeppelin's SafeERC20 contract.\nlibrary GPv2SafeERC20 {\n    /// @dev Wrapper around a call to the ERC20 function `transfer` that reverts\n    /// also when the token returns `false`.\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        bytes4 selector_ = token.transfer.selector;\n\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let freeMemoryPointer := mload(0x40)\n            mstore(freeMemoryPointer, selector_)\n            mstore(\n                add(freeMemoryPointer, 4),\n                and(to, 0xffffffffffffffffffffffffffffffffffffffff)\n            )\n            mstore(add(freeMemoryPointer, 36), value)\n\n            if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)) {\n                returndatacopy(0, 0, returndatasize())\n                revert(0, returndatasize())\n            }\n        }\n\n        require(getLastTransferResult(token), \"GPv2: failed transfer\");\n    }\n\n    /// @dev Wrapper around a call to the ERC20 function `transferFrom` that\n    /// reverts also when the token returns `false`.\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) internal {\n        bytes4 selector_ = token.transferFrom.selector;\n\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let freeMemoryPointer := mload(0x40)\n            mstore(freeMemoryPointer, selector_)\n            mstore(\n                add(freeMemoryPointer, 4),\n                and(from, 0xffffffffffffffffffffffffffffffffffffffff)\n            )\n            mstore(\n                add(freeMemoryPointer, 36),\n                and(to, 0xffffffffffffffffffffffffffffffffffffffff)\n            )\n            mstore(add(freeMemoryPointer, 68), value)\n\n            if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)) {\n                returndatacopy(0, 0, returndatasize())\n                revert(0, returndatasize())\n            }\n        }\n\n        require(getLastTransferResult(token), \"GPv2: failed transferFrom\");\n    }\n\n    /// @dev Verifies that the last return was a successful `transfer*` call.\n    /// This is done by checking that the return data is either empty, or\n    /// is a valid ABI encoded boolean.\n    function getLastTransferResult(\n        IERC20 token\n    ) private view returns (bool success) {\n        // NOTE: Inspecting previous return data requires assembly. Note that\n        // we write the return data to memory 0 in the case where the return\n        // data size is 32, this is OK since the first 64 bytes of memory are\n        // reserved by Solidy as a scratch space that can be used within\n        // assembly blocks.\n        // <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html>\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            /// @dev Revert with an ABI encoded Solidity error with a message\n            /// that fits into 32-bytes.\n            ///\n            /// An ABI encoded Solidity error has the following memory layout:\n            ///\n            /// ------------+----------------------------------\n            ///  byte range | value\n            /// ------------+----------------------------------\n            ///  0x00..0x04 |        selector(\"Error(string)\")\n            ///  0x04..0x24 |      string offset (always 0x20)\n            ///  0x24..0x44 |                    string length\n            ///  0x44..0x64 | string value, padded to 32-bytes\n            function revertWithMessage(length, message) {\n                mstore(0x00, \"\\x08\\xc3\\x79\\xa0\")\n                mstore(0x04, 0x20)\n                mstore(0x24, length)\n                mstore(0x44, message)\n                revert(0x00, 0x64)\n            }\n\n            switch returndatasize()\n            // Non-standard ERC20 transfer without return.\n            case 0 {\n                // NOTE: When the return data size is 0, verify that there\n                // is code at the address. This is done in order to maintain\n                // compatibility with Solidity calling conventions.\n                // <https://docs.soliditylang.org/en/v0.7.6/control-structures.html#external-function-calls>\n                if iszero(extcodesize(token)) {\n                    revertWithMessage(20, \"GPv2: not a contract\")\n                }\n\n                success := 1\n            }\n            // Standard ERC20 transfer returning boolean success value.\n            case 32 {\n                returndatacopy(0, 0, returndatasize())\n\n                // NOTE: For ABI encoding v1, any non-zero value is accepted\n                // as `true` for a boolean. In order to stay compatible with\n                // OpenZeppelin's `SafeERC20` library which is known to work\n                // with the existing ERC20 implementation we care about,\n                // make sure we return success for any non-zero return value\n                // from the `transfer*` call.\n                success := iszero(iszero(mload(0)))\n            }\n            default {\n                revertWithMessage(31, \"GPv2: malformed transfer result\")\n            }\n        }\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_core","type":"address"},{"internalType":"address","name":"_assetToken","type":"address"},{"internalType":"address","name":"_accounting","type":"address"},{"internalType":"address","name":"_settlementContract","type":"address"},{"internalType":"address","name":"_vaultRelayer","type":"address"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"uint256","name":"_reserveId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"newAmount","type":"uint256"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"CapExceeded","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"InvalidAmountIn","type":"error"},{"inputs":[{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint256","name":"provided","type":"uint256"}],"name":"InvalidAmountOut","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"InvalidAsset","type":"error"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_balance","type":"uint256"}],"name":"InvalidBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"_cooldown","type":"uint256"}],"name":"InvalidCooldown","type":"error"},{"inputs":[{"internalType":"address","name":"farm","type":"address"}],"name":"InvalidFarm","type":"error"},{"inputs":[],"name":"InvalidLength","type":"error"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"InvalidOracle","type":"error"},{"inputs":[{"internalType":"uint256","name":"_configuredSlipage","type":"uint256"},{"internalType":"uint256","name":"_maxSlippage","type":"uint256"}],"name":"InvalidSlippage","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"RewardsClaimFailed","type":"error"},{"inputs":[],"name":"RewardsClaimLostAssets","type":"error"},{"inputs":[],"name":"RewardsNotEnabled","type":"error"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"RouterNotEnabled","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"uint256","name":"minAssetsOut","type":"uint256"},{"internalType":"uint256","name":"assetsReceived","type":"uint256"}],"name":"SlippageTooHigh","type":"error"},{"inputs":[],"name":"SwapCooldown","type":"error"},{"inputs":[{"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"SwapFailed","type":"error"},{"inputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"UnderlyingCallReverted","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"asset","type":"address"}],"name":"AssetDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"asset","type":"address"}],"name":"AssetEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetsBefore","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetsAfter","type":"uint256"}],"name":"AssetsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newCap","type":"uint256"}],"name":"CapUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldCore","type":"address"},{"indexed":true,"internalType":"address","name":"newCore","type":"address"}],"name":"CoreUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxSlippage","type":"uint256"}],"name":"MaxSlippageUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"orderUid","type":"bytes"},{"components":[{"internalType":"contract IERC20","name":"sellToken","type":"address"},{"internalType":"contract IERC20","name":"buyToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"uint32","name":"validTo","type":"uint32"},{"internalType":"bytes32","name":"appData","type":"bytes32"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"bytes32","name":"kind","type":"bytes32"},{"internalType":"bool","name":"partiallyFillable","type":"bool"},{"internalType":"bytes32","name":"sellTokenBalance","type":"bytes32"},{"internalType":"bytes32","name":"buyTokenBalance","type":"bytes32"}],"indexed":false,"internalType":"struct GPv2Order.Data","name":"order","type":"tuple"},{"indexed":false,"internalType":"uint32","name":"validTo","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"buyAmount","type":"uint256"}],"name":"OrderSigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"rewardContract","type":"address"}],"name":"RewardContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"router","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SetEnabledRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"address","name":"token2","type":"address"},{"indexed":false,"internalType":"uint256","name":"cooldown","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxSlippage","type":"uint256"}],"name":"SetPairConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"address","name":"_tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountIn","type":"uint256"},{"indexed":false,"internalType":"address","name":"_tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountOut","type":"uint256"}],"name":"TokensSwapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ASSET_REMOVAL_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_MAX_COOLDOWN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_SIGN_COOLDOWN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aaveAssetId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aaveAssetToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accounting","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetTokens","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"}],"name":"convert","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"core","outputs":[{"internalType":"contract InfiniFiCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositToAave","outputs":[{"internalType":"uint256","name":"suppliedShares","type":"uint256"},{"internalType":"uint256","name":"suppliedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assetList","type":"address[]"}],"name":"disableAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct CoreControlled.Call[]","name":"calls","type":"tuple[]"}],"name":"emergencyAction","outputs":[{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assetList","type":"address[]"}],"name":"enableAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"enabledRouters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enforceCooldown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"}],"name":"getSwapPairConfig","outputs":[{"components":[{"internalType":"uint64","name":"lastSwap","type":"uint64"},{"internalType":"uint64","name":"cooldown","type":"uint64"},{"internalType":"uint128","name":"maxSlippage","type":"uint128"}],"internalType":"struct SwapFarmV2.PairConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"}],"name":"getSwapPairKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"hub","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"isAssetSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastOrderSignTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSlippage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserveId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCap","type":"uint256"}],"name":"setCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newCore","type":"address"}],"name":"setCore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setEnabledRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSlippage","type":"uint256"}],"name":"setMaxSlippage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_cooldown","type":"uint256"},{"internalType":"uint256","name":"_slippage","type":"uint256"}],"name":"setPairConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardContract","type":"address"}],"name":"setRewardContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settlementContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_minAmountOut","type":"uint256"}],"name":"signSwapOrder","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"spoke","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_router","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"swapWithAggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultRelayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFromAave","outputs":[{"internalType":"uint256","name":"withdrawnShares","type":"uint256"},{"internalType":"uint256","name":"withdrawnAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawSecondaryAsset","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0x000000000000000000000000f6d48735eccf12bdc1df2674b1ce3fcb3bd25490000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000007a5c5dba4fbd0e1e1a2ecdbe752fae55f6e842b30000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41000000000000000000000000c92e8bdf79f0507f65a392b0ab4667716bfe01100000000000000000000000000000000000000000000000000000000000093a8000000000000000000000000094e7a5dcbe816e498b89ab752661904e2f56c485000000000000000000000000000000000000000000000000000000000000000b"}