{"file_path":"src/FlashLoopAdapter.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @title FlashLoopAdapter — atomic open/close of Aave v3 leveraged loops via a Safe module\n/// @notice Installed as a Safe MODULE (safe.enableModule(adapter)). The Safe calls open()/close()\n///         in ONE transaction; the adapter takes free flash liquidity (Morpho / Balancer v2, or\n///         Aave flashLoanSimple as paid fallback), and drives the Safe itself for every\n///         position-touching call via execTransactionFromModule — so the POSITION IS OWNED BY THE\n///         SAFE, with no credit delegation and no aToken approvals to any external contract.\n///\n///         open:  flash debt (L-1)*E -> swap debt->collateral (router calldata) -> supply to pool\n///                onBehalfOf safe -> [setUserEMode] -> safe borrows debt (module) -> safe transfers\n///                debt to adapter (module) -> repay flash -> sweep dust to safe.\n///         close: flash debt -> repay pool onBehalfOf safe -> safe withdraws collateral to adapter\n///                (module) -> swap collateral->debt (router calldata) -> repay flash -> sweep BOTH\n///                tokens to safe.\n///\n///         Aave-v3-only surface; swap route/calldata is quoted OFF-CHAIN at execution and\n///         min-out enforced ON-CHAIN. Stateless between calls (transient pending-op hash).\n///\n///         Engine contract: ~/goals/aave-yield-hunter/engine/CONTRACTS.md (\"Flash liquidity\").\n\ninterface IERC20 {\n    function balanceOf(address) external view returns (uint256);\n    function transfer(address, uint256) external returns (bool);\n    function approve(address, uint256) external returns (bool);\n}\n\ninterface ISafe {\n    function execTransactionFromModule(address to, uint256 value, bytes calldata data, uint8 operation)\n        external returns (bool);\n    function isModuleEnabled(address module) external view returns (bool);\n}\n\ninterface IAavePool {\n    function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n    function repay(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf)\n        external returns (uint256);\n    function flashLoanSimple(address receiverAddress, address asset, uint256 amount, bytes calldata params,\n        uint16 referralCode) external;\n}\n\ninterface IMorpho {\n    function flashLoan(address token, uint256 assets, bytes calldata data) external;\n}\n\ninterface IBalancerV2Vault {\n    function flashLoan(address recipient, address[] calldata tokens, uint256[] calldata amounts,\n        bytes calldata userData) external;\n}\n\ncontract FlashLoopAdapter {\n    enum Provider { MORPHO, BALANCER_V2, AAVE_SIMPLE }\n    enum Op { OPEN, CLOSE }\n\n    struct Params {\n        Op op;\n        Provider provider;\n        address providerAddr;   // Morpho / Balancer vault / Aave pool (flash source)\n        address pool;           // Aave v3 Pool of the target market\n        address collateral;     // collateral underlying\n        address debt;           // debt underlying (== flashed asset)\n        uint256 flashAmount;    // debt units to flash: open = (L-1)*E equiv; close = outstanding debt\n        address swapRouter;     // aggregator router (quoted off-chain at execution)\n        bytes   swapCalldata;   // router call: open = debt->collateral, close = collateral->debt\n        uint256 minOut;         // min output of the swap leg, on-chain enforced\n        uint8   emodeId;        // 0 = skip setUserEMode\n        uint256 withdrawAmount; // close only: collateral to withdraw (type(uint).max = all)\n    }\n\n    error NotSafeOwner();\n    error ModuleNotEnabled();\n    error UntrustedCallback();\n    error ModuleExecFailed(string what);\n    error SwapMinOut(uint256 got, uint256 want);\n    error FlashShortfall(uint256 have, uint256 owe);\n\n    uint256 private constant VARIABLE_RATE = 2;\n\n    // transient pending-operation guard: hash of (safe, params) set right before the\n    // flash call, checked+cleared in the callback. tstore -> zero cost between txs.\n    bytes32 private transient _pending;\n    address private transient _safe;\n\n    // ---------------------------------------------------------------- entrypoints\n\n    /// @notice msg.sender MUST be the Safe (which has this adapter enabled as module).\n    function open(Params calldata p) external { _start(p); }\n    function close(Params calldata p) external { _start(p); }\n\n    function _start(Params calldata p) internal {\n        if (!ISafe(msg.sender).isModuleEnabled(address(this))) revert ModuleNotEnabled();\n        _safe = msg.sender;\n        _pending = keccak256(abi.encode(msg.sender, p));\n        bytes memory data = abi.encode(p);\n        if (p.provider == Provider.MORPHO) {\n            IMorpho(p.providerAddr).flashLoan(p.debt, p.flashAmount, data);\n        } else if (p.provider == Provider.BALANCER_V2) {\n            address[] memory tokens = new address[](1);\n            uint256[] memory amounts = new uint256[](1);\n            tokens[0] = p.debt; amounts[0] = p.flashAmount;\n            IBalancerV2Vault(p.providerAddr).flashLoan(address(this), tokens, amounts, data);\n        } else {\n            IAavePool(p.providerAddr).flashLoanSimple(address(this), p.debt, p.flashAmount, data, 0);\n        }\n        // sweep every touched token back to the Safe — adapter never holds funds\n        _sweep(p.debt);\n        _sweep(p.collateral);\n    }\n\n    // ---------------------------------------------------------------- flash callbacks\n\n    /// Morpho: onMorphoFlashLoan(uint256 assets, bytes data); repay via approve (Morpho pulls).\n    function onMorphoFlashLoan(uint256 assets, bytes calldata data) external {\n        Params memory p = _validate(data);\n        _run(p, assets, 0);\n        IERC20(p.debt).approve(msg.sender, assets);\n    }\n\n    /// Balancer v2: receiveFlashLoan(tokens, amounts, feeAmounts, userData); repay via transfer.\n    function receiveFlashLoan(address[] calldata tokens, uint256[] calldata amounts,\n                              uint256[] calldata feeAmounts, bytes calldata userData) external {\n        Params memory p = _validate(userData);\n        _run(p, amounts[0], feeAmounts[0]);\n        IERC20(tokens[0]).transfer(msg.sender, amounts[0] + feeAmounts[0]);\n    }\n\n    /// Aave: executeOperation(asset, amount, premium, initiator, params); repay via approve (pool pulls).\n    function executeOperation(address asset, uint256 amount, uint256 premium, address initiator,\n                              bytes calldata params) external returns (bool) {\n        if (initiator != address(this)) revert UntrustedCallback();\n        Params memory p = _validate(params);\n        _run(p, amount, premium);\n        IERC20(asset).approve(msg.sender, amount + premium);\n        return true;\n    }\n\n    // ---------------------------------------------------------------- core\n\n    function _validate(bytes memory data) internal returns (Params memory p) {\n        p = abi.decode(data, (Params));\n        // provider addr is bound into the pending hash — only the flash source we just\n        // called can re-enter, with exactly the params we committed to.\n        if (msg.sender != p.providerAddr) revert UntrustedCallback();\n        bytes32 h = keccak256(abi.encode(_safe, p));\n        if (h != _pending) revert UntrustedCallback();\n        _pending = bytes32(0);\n    }\n\n    function _run(Params memory p, uint256 flashed, uint256 fee) internal {\n        address safe = _safe;\n        if (p.op == Op.OPEN) {\n            // 1. swap flashed debt -> collateral (router quoted off-chain, min-out on-chain)\n            uint256 got = _swap(p.debt, p.collateral, p.swapRouter, p.swapCalldata, p.minOut);\n            // 2. supply collateral to the pool, position owned by the Safe\n            IERC20(p.collateral).approve(p.pool, got);\n            IAavePool(p.pool).supply(p.collateral, got, safe, 0);\n            // 3. e-mode BEFORE borrow — the quoted LTV only exists inside the category\n            if (p.emodeId != 0) {\n                _moduleExec(safe, p.pool, abi.encodeWithSignature(\"setUserEMode(uint8)\", p.emodeId), \"setUserEMode\");\n            }\n            // 4. Safe borrows the flash repayment (+fee) against its new collateral\n            uint256 owed = flashed + fee;\n            _moduleExec(safe, p.pool,\n                abi.encodeWithSignature(\"borrow(address,uint256,uint256,uint16,address)\",\n                                        p.debt, owed, VARIABLE_RATE, uint16(0), safe), \"borrow\");\n            // 5. Safe funds the flash repayment\n            _moduleExec(safe, p.debt,\n                abi.encodeWithSignature(\"transfer(address,uint256)\", address(this), owed), \"fund repay\");\n        } else {\n            // 1. repay the Safe's debt with the flashed asset\n            IERC20(p.debt).approve(p.pool, flashed);\n            IAavePool(p.pool).repay(p.debt, flashed, VARIABLE_RATE, safe);\n            // 2. Safe withdraws collateral straight to the adapter\n            _moduleExec(safe, p.pool,\n                abi.encodeWithSignature(\"withdraw(address,uint256,address)\",\n                                        p.collateral, p.withdrawAmount, address(this)), \"withdraw\");\n            // 3. swap collateral -> debt to cover the flash (+fee); leftovers sweep to Safe\n            _swap(p.collateral, p.debt, p.swapRouter, p.swapCalldata, p.minOut);\n            uint256 have = IERC20(p.debt).balanceOf(address(this));\n            if (have < flashed + fee) revert FlashShortfall(have, flashed + fee);\n        }\n    }\n\n    function _swap(address tokenIn, address tokenOut, address router, bytes memory data, uint256 minOut)\n        internal returns (uint256 got)\n    {\n        IERC20(tokenIn).approve(router, type(uint256).max);\n        (bool ok, bytes memory ret) = router.call(data);\n        if (!ok) {\n            assembly { revert(add(ret, 0x20), mload(ret)) }\n        }\n        IERC20(tokenIn).approve(router, 0);\n        got = IERC20(tokenOut).balanceOf(address(this));\n        if (got < minOut) revert SwapMinOut(got, minOut);\n    }\n\n    function _moduleExec(address safe, address to, bytes memory data, string memory what) internal {\n        if (!ISafe(safe).execTransactionFromModule(to, 0, data, 0)) revert ModuleExecFailed(what);\n    }\n\n    function _sweep(address token) internal {\n        uint256 bal = IERC20(token).balanceOf(address(this));\n        if (bal > 0) IERC20(token).transfer(_safe, bal);\n    }\n}\n","deployed_bytecode":"0x608060405234801561000f575f5ffd5b5060043610610055575f3560e01c80631b11d0ff1461005957806331f57072146100805780637d1eba3614610095578063a10acfd614610095578063f04f2707146100a8575b5f5ffd5b61006c61006736600461118d565b6100bb565b604051901515815260200160405180910390f35b61009361008e366004611203565b6101c6565b005b6100936100a336600461124a565b61028d565b6100936100b63660046112c8565b610299565b5f6001600160a01b03841630146100e557604051631d7ba4eb60e21b815260040160405180910390fd5b5f61012484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506103ff92505050565b9050610131818888610513565b6001600160a01b03881663095ea7b33361014b898b611392565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af1158015610193573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101b791906113b7565b50600198975050505050505050565b5f61020583838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506103ff92505050565b905061021281855f610513565b60a081015160405163095ea7b360e01b8152336004820152602481018690526001600160a01b039091169063095ea7b3906044016020604051808303815f875af1158015610262573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061028691906113b7565b5050505050565b61029681610a3f565b50565b5f6102d883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506103ff92505050565b90506103158188885f8181106102f0576102f06113d6565b9050602002013587875f818110610309576103096113d6565b90506020020135610513565b88885f818110610327576103276113d6565b905060200201602081019061033c91906113ea565b6001600160a01b031663a9059cbb3387875f81811061035d5761035d6113d6565b905060200201358a8a5f818110610376576103766113d6565b905060200201356103879190611392565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af11580156103cf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103f391906113b7565b50505050505050505050565b610463604080516101808101909152805f81526020015f81525f602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e0830152610100820181905261012082018190526101409091015290565b81806020019051810190610477919061151d565b905080604001516001600160a01b0316336001600160a01b0316146104af57604051631d7ba4eb60e21b815260040160405180910390fd5b6040515f906104cf906001600160a01b0360015c1690849060200161169c565b6040516020818303038152906040528051906020012090505f5c811461050857604051631d7ba4eb60e21b815260040160405180910390fd5b5f80805d5050919050565b6001600160a01b0360015c165f8451600181111561053357610533611636565b036107dc575f61055c8560a0015186608001518760e00151886101000151896101200151610dc1565b6080860151606087015160405163095ea7b360e01b81526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303815f875af11580156105b4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105d891906113b7565b506060850151608086015160405163617ba03760e01b81526001600160a01b0391821660048201526024810184905284821660448201525f606482015291169063617ba037906084015f604051808303815f87803b158015610638575f5ffd5b505af115801561064a573d5f5f3e3d5ffd5b5050505084610140015160ff165f146106ce57606085015161014086015160405160ff90911660248201526106ce91849160440160408051601f19818403018152918152602080830180516001600160e01b03166328530a4760e01b1790528151808301909252600c82526b73657455736572454d6f646560a01b90820152610fad565b5f6106d98486611392565b606087015160a08801516040516001600160a01b03918216602482015260448101849052600260648201525f608482015290861660a48201529192506107699185919060c40160408051601f19818403018152918152602080830180516001600160e01b031663a415bcad60e01b17905281518083019092526006825265626f72726f7760d01b90820152610fad565b60a0860151604051306024820152604481018390526107d591859160640160408051601f19818403018152918152602080830180516001600160e01b031663a9059cbb60e01b1790528151808301909252600a82526966756e6420726570617960b01b90820152610fad565b5050610a39565b60a0840151606085015160405163095ea7b360e01b81526001600160a01b0391821660048201526024810186905291169063095ea7b3906044016020604051808303815f875af1158015610832573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061085691906113b7565b50606084015160a085015160405163573ade8160e01b81526001600160a01b0391821660048201526024810186905260026044820152838216606482015291169063573ade81906084016020604051808303815f875af11580156108bc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108e091906117a1565b50606084015160808501516101608601516040516001600160a01b039092166024830152604482015230606482015261096491839160840160408051601f19818403018152918152602080830180516001600160e01b0316631a4ca37b60e21b17905281518083019092526008825267776974686472617760c01b90820152610fad565b61098784608001518560a001518660e00151876101000151886101200151610dc1565b5060a08401516040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa1580156109d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109f491906117a1565b9050610a008385611392565b8110156102865780610a128486611392565b6040516311e92f0360e01b8152600481019290925260248201526044015b60405180910390fd5b50505050565b604051632d9ad53d60e01b81523060048201523390632d9ad53d90602401602060405180830381865afa158015610a78573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9c91906113b7565b610ab957604051639a043ec160e01b815260040160405180910390fd5b336001805c6001600160a01b0319168217905d503381604051602001610ae0929190611959565b604051602081830303815290604052805190602001205f81905d505f81604051602001610b0d9190611984565b60408051601f1981840301815291905290505f610b306040840160208501611996565b6002811115610b4157610b41611636565b03610bca57610b5660608301604084016113ea565b6001600160a01b031663e0232b42610b7460c0850160a086016113ea565b8460c00135846040518463ffffffff1660e01b8152600401610b98939291906119b1565b5f604051808303815f87803b158015610baf575f5ffd5b505af1158015610bc1573d5f5f3e3d5ffd5b50505050610d92565b6001610bdc6040840160208501611996565b6002811115610bed57610bed611636565b03610d0e576040805160018082528183019092525f916020808301908036833750506040805160018082528183019092529293505f92915060208083019080368337019050509050610c4560c0850160a086016113ea565b825f81518110610c5757610c576113d6565b60200260200101906001600160a01b031690816001600160a01b0316815250508360c00135815f81518110610c8e57610c8e6113d6565b6020908102919091010152610ca960608501604086016113ea565b6001600160a01b0316635c38449e308484876040518563ffffffff1660e01b8152600401610cda94939291906119e0565b5f604051808303815f87803b158015610cf1575f5ffd5b505af1158015610d03573d5f5f3e3d5ffd5b505050505050610d92565b610d1e60608301604084016113ea565b6001600160a01b03166342b0b77c30610d3d60c0860160a087016113ea565b8560c00135855f6040518663ffffffff1660e01b8152600401610d64959493929190611a8f565b5f604051808303815f87803b158015610d7b575f5ffd5b505af1158015610d8d573d5f5f3e3d5ffd5b505050505b610daa610da560c0840160a085016113ea565b61103e565b610dbd610da560a08401608085016113ea565b5050565b60405163095ea7b360e01b81526001600160a01b0384811660048301525f1960248301525f919087169063095ea7b3906044016020604051808303815f875af1158015610e10573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e3491906113b7565b505f5f856001600160a01b031685604051610e4f9190611ad7565b5f604051808303815f865af19150503d805f8114610e88576040519150601f19603f3d011682016040523d82523d5f602084013e610e8d565b606091505b509150915081610e9f57805160208201fd5b60405163095ea7b360e01b81526001600160a01b0387811660048301525f602483015289169063095ea7b3906044016020604051808303815f875af1158015610eea573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f0e91906113b7565b506040516370a0823160e01b81523060048201526001600160a01b038816906370a0823190602401602060405180830381865afa158015610f51573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f7591906117a1565b925083831015610fa25760405163ab32395f60e01b81526004810184905260248101859052604401610a30565b505095945050505050565b60405163468721a760e01b81526001600160a01b0385169063468721a790610fdf9086905f9087908290600401611aed565b6020604051808303815f875af1158015610ffb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061101f91906113b7565b610a3957806040516366f9a97560e01b8152600401610a309190611b27565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611082573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a691906117a1565b90508015610dbd5760405163a9059cbb60e01b81526001600160a01b0360015c811660048301526024820183905283169063a9059cbb906044016020604051808303815f875af11580156110fc573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112091906113b7565b505050565b6001600160a01b0381168114610296575f5ffd5b803561114481611125565b919050565b5f5f83601f840112611159575f5ffd5b5081356001600160401b0381111561116f575f5ffd5b602083019150836020828501011115611186575f5ffd5b9250929050565b5f5f5f5f5f5f60a087890312156111a2575f5ffd5b86356111ad81611125565b9550602087013594506040870135935060608701356111cb81611125565b925060808701356001600160401b038111156111e5575f5ffd5b6111f189828a01611149565b979a9699509497509295939492505050565b5f5f5f60408486031215611215575f5ffd5b8335925060208401356001600160401b03811115611231575f5ffd5b61123d86828701611149565b9497909650939450505050565b5f6020828403121561125a575f5ffd5b81356001600160401b0381111561126f575f5ffd5b82016101808185031215611281575f5ffd5b9392505050565b5f5f83601f840112611298575f5ffd5b5081356001600160401b038111156112ae575f5ffd5b6020830191508360208260051b8501011115611186575f5ffd5b5f5f5f5f5f5f5f5f6080898b0312156112df575f5ffd5b88356001600160401b038111156112f4575f5ffd5b6113008b828c01611288565b90995097505060208901356001600160401b0381111561131e575f5ffd5b61132a8b828c01611288565b90975095505060408901356001600160401b03811115611348575f5ffd5b6113548b828c01611288565b90955093505060608901356001600160401b03811115611372575f5ffd5b61137e8b828c01611149565b999c989b5096995094979396929594505050565b808201808211156113b157634e487b7160e01b5f52601160045260245ffd5b92915050565b5f602082840312156113c7575f5ffd5b81518015158114611281575f5ffd5b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156113fa575f5ffd5b813561128181611125565b634e487b7160e01b5f52604160045260245ffd5b60405161018081016001600160401b038111828210171561143c5761143c611405565b60405290565b60028110610296575f5ffd5b805161114481611442565b60038110610296575f5ffd5b805161114481611459565b805161114481611125565b5f82601f83011261148a575f5ffd5b81516001600160401b038111156114a3576114a3611405565b604051601f8201601f19908116603f011681016001600160401b03811182821017156114d1576114d1611405565b6040528181528382016020018510156114e8575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b60ff81168114610296575f5ffd5b805161114481611504565b5f6020828403121561152d575f5ffd5b81516001600160401b03811115611542575f5ffd5b82016101808185031215611554575f5ffd5b61155c611419565b6115658261144e565b815261157360208301611465565b602082015261158460408301611470565b604082015261159560608301611470565b60608201526115a660808301611470565b60808201526115b760a08301611470565b60a082015260c082810151908201526115d260e08301611470565b60e08201526101008201516001600160401b038111156115f0575f5ffd5b6115fc8682850161147b565b61010083015250610120828101519082015261161b6101408301611512565b61014082015261016091820151918101919091529392505050565b634e487b7160e01b5f52602160045260245ffd5b6002811061165a5761165a611636565b9052565b6003811061165a5761165a611636565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038316815260406020820181905282516116bf9183019061164a565b5f60208301516116d2606084018261165e565b5060408301516001600160a01b03811660808401525060608301516001600160a01b03811660a08401525060808301516001600160a01b03811660c08401525060a08301516001600160a01b03811660e08401525060c083015161010083015260e08301516001600160a01b038116610120840152506101008301516101806101408401526117656101c084018261166e565b905061012084015161016084015261014084015161178961018085018260ff169052565b506101608401516101a0840152809150509392505050565b5f602082840312156117b1575f5ffd5b5051919050565b803561114481611442565b803561114481611459565b5f5f8335601e198436030181126117e3575f5ffd5b83016020810192503590506001600160401b03811115611801575f5ffd5b803603821315611186575f5ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b803561114481611504565b6118548261184f836117b8565b61164a565b5f611861602083016117c3565b61186e602085018261165e565b5061187b60408301611139565b6001600160a01b0316604084015261189560608301611139565b6001600160a01b031660608401526118af60808301611139565b6001600160a01b031660808401526118c960a08301611139565b6001600160a01b031660a084015260c082810135908401526118ed60e08301611139565b6001600160a01b031660e08401526119096101008301836117ce565b6101806101008601526119216101808601828461180f565b6101208581013590870152915061193d90506101408401611837565b60ff166101408501526101609283013592909301919091525090565b6001600160a01b03831681526040602082018190525f9061197c90830184611842565b949350505050565b602081525f6112816020830184611842565b5f602082840312156119a6575f5ffd5b813561128181611459565b60018060a01b0384168152826020820152606060408201525f6119d7606083018461166e565b95945050505050565b6001600160a01b03851681526080602080830182905285519183018290525f919086019060a0840190835b81811015611a325783516001600160a01b0316835260209384019390920191600101611a0b565b50508381036040850152855180825260209182019250908601905f90815b81811015611a6e578351855260209485019490930192600101611a50565b505050508281036060840152611a84818561166e565b979650505050505050565b6001600160a01b038681168252851660208201526040810184905260a0606082018190525f90611ac19083018561166e565b905061ffff831660808301529695505050505050565b5f82518060208501845e5f920191825250919050565b60018060a01b0385168152836020820152608060408201525f611b13608083018561166e565b905060ff8316606083015295945050505050565b602081525f611281602083018461166e56fea264697066735822122034a198e161a354b2142a541afdda31b68c1072b01b36d767fa944ac79880deac64736f6c634300081c0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}},"remappings":["forge-std/=lib/forge-std/src/"],"viaIR":false},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.28+commit.7893614a","is_verified_via_verifier_alliance":false,"verified_at":"2026-08-18T10:47:31.892585Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x6080604052348015600e575f5ffd5b50611b6f8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610055575f3560e01c80631b11d0ff1461005957806331f57072146100805780637d1eba3614610095578063a10acfd614610095578063f04f2707146100a8575b5f5ffd5b61006c61006736600461118d565b6100bb565b604051901515815260200160405180910390f35b61009361008e366004611203565b6101c6565b005b6100936100a336600461124a565b61028d565b6100936100b63660046112c8565b610299565b5f6001600160a01b03841630146100e557604051631d7ba4eb60e21b815260040160405180910390fd5b5f61012484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506103ff92505050565b9050610131818888610513565b6001600160a01b03881663095ea7b33361014b898b611392565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af1158015610193573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101b791906113b7565b50600198975050505050505050565b5f61020583838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506103ff92505050565b905061021281855f610513565b60a081015160405163095ea7b360e01b8152336004820152602481018690526001600160a01b039091169063095ea7b3906044016020604051808303815f875af1158015610262573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061028691906113b7565b5050505050565b61029681610a3f565b50565b5f6102d883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506103ff92505050565b90506103158188885f8181106102f0576102f06113d6565b9050602002013587875f818110610309576103096113d6565b90506020020135610513565b88885f818110610327576103276113d6565b905060200201602081019061033c91906113ea565b6001600160a01b031663a9059cbb3387875f81811061035d5761035d6113d6565b905060200201358a8a5f818110610376576103766113d6565b905060200201356103879190611392565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af11580156103cf573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103f391906113b7565b50505050505050505050565b610463604080516101808101909152805f81526020015f81525f602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e0830152610100820181905261012082018190526101409091015290565b81806020019051810190610477919061151d565b905080604001516001600160a01b0316336001600160a01b0316146104af57604051631d7ba4eb60e21b815260040160405180910390fd5b6040515f906104cf906001600160a01b0360015c1690849060200161169c565b6040516020818303038152906040528051906020012090505f5c811461050857604051631d7ba4eb60e21b815260040160405180910390fd5b5f80805d5050919050565b6001600160a01b0360015c165f8451600181111561053357610533611636565b036107dc575f61055c8560a0015186608001518760e00151886101000151896101200151610dc1565b6080860151606087015160405163095ea7b360e01b81526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303815f875af11580156105b4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105d891906113b7565b506060850151608086015160405163617ba03760e01b81526001600160a01b0391821660048201526024810184905284821660448201525f606482015291169063617ba037906084015f604051808303815f87803b158015610638575f5ffd5b505af115801561064a573d5f5f3e3d5ffd5b5050505084610140015160ff165f146106ce57606085015161014086015160405160ff90911660248201526106ce91849160440160408051601f19818403018152918152602080830180516001600160e01b03166328530a4760e01b1790528151808301909252600c82526b73657455736572454d6f646560a01b90820152610fad565b5f6106d98486611392565b606087015160a08801516040516001600160a01b03918216602482015260448101849052600260648201525f608482015290861660a48201529192506107699185919060c40160408051601f19818403018152918152602080830180516001600160e01b031663a415bcad60e01b17905281518083019092526006825265626f72726f7760d01b90820152610fad565b60a0860151604051306024820152604481018390526107d591859160640160408051601f19818403018152918152602080830180516001600160e01b031663a9059cbb60e01b1790528151808301909252600a82526966756e6420726570617960b01b90820152610fad565b5050610a39565b60a0840151606085015160405163095ea7b360e01b81526001600160a01b0391821660048201526024810186905291169063095ea7b3906044016020604051808303815f875af1158015610832573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061085691906113b7565b50606084015160a085015160405163573ade8160e01b81526001600160a01b0391821660048201526024810186905260026044820152838216606482015291169063573ade81906084016020604051808303815f875af11580156108bc573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108e091906117a1565b50606084015160808501516101608601516040516001600160a01b039092166024830152604482015230606482015261096491839160840160408051601f19818403018152918152602080830180516001600160e01b0316631a4ca37b60e21b17905281518083019092526008825267776974686472617760c01b90820152610fad565b61098784608001518560a001518660e00151876101000151886101200151610dc1565b5060a08401516040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa1580156109d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109f491906117a1565b9050610a008385611392565b8110156102865780610a128486611392565b6040516311e92f0360e01b8152600481019290925260248201526044015b60405180910390fd5b50505050565b604051632d9ad53d60e01b81523060048201523390632d9ad53d90602401602060405180830381865afa158015610a78573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9c91906113b7565b610ab957604051639a043ec160e01b815260040160405180910390fd5b336001805c6001600160a01b0319168217905d503381604051602001610ae0929190611959565b604051602081830303815290604052805190602001205f81905d505f81604051602001610b0d9190611984565b60408051601f1981840301815291905290505f610b306040840160208501611996565b6002811115610b4157610b41611636565b03610bca57610b5660608301604084016113ea565b6001600160a01b031663e0232b42610b7460c0850160a086016113ea565b8460c00135846040518463ffffffff1660e01b8152600401610b98939291906119b1565b5f604051808303815f87803b158015610baf575f5ffd5b505af1158015610bc1573d5f5f3e3d5ffd5b50505050610d92565b6001610bdc6040840160208501611996565b6002811115610bed57610bed611636565b03610d0e576040805160018082528183019092525f916020808301908036833750506040805160018082528183019092529293505f92915060208083019080368337019050509050610c4560c0850160a086016113ea565b825f81518110610c5757610c576113d6565b60200260200101906001600160a01b031690816001600160a01b0316815250508360c00135815f81518110610c8e57610c8e6113d6565b6020908102919091010152610ca960608501604086016113ea565b6001600160a01b0316635c38449e308484876040518563ffffffff1660e01b8152600401610cda94939291906119e0565b5f604051808303815f87803b158015610cf1575f5ffd5b505af1158015610d03573d5f5f3e3d5ffd5b505050505050610d92565b610d1e60608301604084016113ea565b6001600160a01b03166342b0b77c30610d3d60c0860160a087016113ea565b8560c00135855f6040518663ffffffff1660e01b8152600401610d64959493929190611a8f565b5f604051808303815f87803b158015610d7b575f5ffd5b505af1158015610d8d573d5f5f3e3d5ffd5b505050505b610daa610da560c0840160a085016113ea565b61103e565b610dbd610da560a08401608085016113ea565b5050565b60405163095ea7b360e01b81526001600160a01b0384811660048301525f1960248301525f919087169063095ea7b3906044016020604051808303815f875af1158015610e10573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e3491906113b7565b505f5f856001600160a01b031685604051610e4f9190611ad7565b5f604051808303815f865af19150503d805f8114610e88576040519150601f19603f3d011682016040523d82523d5f602084013e610e8d565b606091505b509150915081610e9f57805160208201fd5b60405163095ea7b360e01b81526001600160a01b0387811660048301525f602483015289169063095ea7b3906044016020604051808303815f875af1158015610eea573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f0e91906113b7565b506040516370a0823160e01b81523060048201526001600160a01b038816906370a0823190602401602060405180830381865afa158015610f51573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f7591906117a1565b925083831015610fa25760405163ab32395f60e01b81526004810184905260248101859052604401610a30565b505095945050505050565b60405163468721a760e01b81526001600160a01b0385169063468721a790610fdf9086905f9087908290600401611aed565b6020604051808303815f875af1158015610ffb573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061101f91906113b7565b610a3957806040516366f9a97560e01b8152600401610a309190611b27565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611082573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a691906117a1565b90508015610dbd5760405163a9059cbb60e01b81526001600160a01b0360015c811660048301526024820183905283169063a9059cbb906044016020604051808303815f875af11580156110fc573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112091906113b7565b505050565b6001600160a01b0381168114610296575f5ffd5b803561114481611125565b919050565b5f5f83601f840112611159575f5ffd5b5081356001600160401b0381111561116f575f5ffd5b602083019150836020828501011115611186575f5ffd5b9250929050565b5f5f5f5f5f5f60a087890312156111a2575f5ffd5b86356111ad81611125565b9550602087013594506040870135935060608701356111cb81611125565b925060808701356001600160401b038111156111e5575f5ffd5b6111f189828a01611149565b979a9699509497509295939492505050565b5f5f5f60408486031215611215575f5ffd5b8335925060208401356001600160401b03811115611231575f5ffd5b61123d86828701611149565b9497909650939450505050565b5f6020828403121561125a575f5ffd5b81356001600160401b0381111561126f575f5ffd5b82016101808185031215611281575f5ffd5b9392505050565b5f5f83601f840112611298575f5ffd5b5081356001600160401b038111156112ae575f5ffd5b6020830191508360208260051b8501011115611186575f5ffd5b5f5f5f5f5f5f5f5f6080898b0312156112df575f5ffd5b88356001600160401b038111156112f4575f5ffd5b6113008b828c01611288565b90995097505060208901356001600160401b0381111561131e575f5ffd5b61132a8b828c01611288565b90975095505060408901356001600160401b03811115611348575f5ffd5b6113548b828c01611288565b90955093505060608901356001600160401b03811115611372575f5ffd5b61137e8b828c01611149565b999c989b5096995094979396929594505050565b808201808211156113b157634e487b7160e01b5f52601160045260245ffd5b92915050565b5f602082840312156113c7575f5ffd5b81518015158114611281575f5ffd5b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156113fa575f5ffd5b813561128181611125565b634e487b7160e01b5f52604160045260245ffd5b60405161018081016001600160401b038111828210171561143c5761143c611405565b60405290565b60028110610296575f5ffd5b805161114481611442565b60038110610296575f5ffd5b805161114481611459565b805161114481611125565b5f82601f83011261148a575f5ffd5b81516001600160401b038111156114a3576114a3611405565b604051601f8201601f19908116603f011681016001600160401b03811182821017156114d1576114d1611405565b6040528181528382016020018510156114e8575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b60ff81168114610296575f5ffd5b805161114481611504565b5f6020828403121561152d575f5ffd5b81516001600160401b03811115611542575f5ffd5b82016101808185031215611554575f5ffd5b61155c611419565b6115658261144e565b815261157360208301611465565b602082015261158460408301611470565b604082015261159560608301611470565b60608201526115a660808301611470565b60808201526115b760a08301611470565b60a082015260c082810151908201526115d260e08301611470565b60e08201526101008201516001600160401b038111156115f0575f5ffd5b6115fc8682850161147b565b61010083015250610120828101519082015261161b6101408301611512565b61014082015261016091820151918101919091529392505050565b634e487b7160e01b5f52602160045260245ffd5b6002811061165a5761165a611636565b9052565b6003811061165a5761165a611636565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b038316815260406020820181905282516116bf9183019061164a565b5f60208301516116d2606084018261165e565b5060408301516001600160a01b03811660808401525060608301516001600160a01b03811660a08401525060808301516001600160a01b03811660c08401525060a08301516001600160a01b03811660e08401525060c083015161010083015260e08301516001600160a01b038116610120840152506101008301516101806101408401526117656101c084018261166e565b905061012084015161016084015261014084015161178961018085018260ff169052565b506101608401516101a0840152809150509392505050565b5f602082840312156117b1575f5ffd5b5051919050565b803561114481611442565b803561114481611459565b5f5f8335601e198436030181126117e3575f5ffd5b83016020810192503590506001600160401b03811115611801575f5ffd5b803603821315611186575f5ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b803561114481611504565b6118548261184f836117b8565b61164a565b5f611861602083016117c3565b61186e602085018261165e565b5061187b60408301611139565b6001600160a01b0316604084015261189560608301611139565b6001600160a01b031660608401526118af60808301611139565b6001600160a01b031660808401526118c960a08301611139565b6001600160a01b031660a084015260c082810135908401526118ed60e08301611139565b6001600160a01b031660e08401526119096101008301836117ce565b6101806101008601526119216101808601828461180f565b6101208581013590870152915061193d90506101408401611837565b60ff166101408501526101609283013592909301919091525090565b6001600160a01b03831681526040602082018190525f9061197c90830184611842565b949350505050565b602081525f6112816020830184611842565b5f602082840312156119a6575f5ffd5b813561128181611459565b60018060a01b0384168152826020820152606060408201525f6119d7606083018461166e565b95945050505050565b6001600160a01b03851681526080602080830182905285519183018290525f919086019060a0840190835b81811015611a325783516001600160a01b0316835260209384019390920191600101611a0b565b50508381036040850152855180825260209182019250908601905f90815b81811015611a6e578351855260209485019490930192600101611a50565b505050508281036060840152611a84818561166e565b979650505050505050565b6001600160a01b038681168252851660208201526040810184905260a0606082018190525f90611ac19083018561166e565b905061ffff831660808301529695505050505050565b5f82518060208501845e5f920191825250919050565b60018060a01b0385168152836020820152608060408201525f611b13608083018561166e565b905060ff8316606083015295945050505050565b602081525f611281602083018461166e56fea264697066735822122034a198e161a354b2142a541afdda31b68c1072b01b36d767fa944ac79880deac64736f6c634300081c0033","name":"FlashLoopAdapter","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":false,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"uint256","name":"have","type":"uint256"},{"internalType":"uint256","name":"owe","type":"uint256"}],"name":"FlashShortfall","type":"error"},{"inputs":[{"internalType":"string","name":"what","type":"string"}],"name":"ModuleExecFailed","type":"error"},{"inputs":[],"name":"ModuleNotEnabled","type":"error"},{"inputs":[],"name":"NotSafeOwner","type":"error"},{"inputs":[{"internalType":"uint256","name":"got","type":"uint256"},{"internalType":"uint256","name":"want","type":"uint256"}],"name":"SwapMinOut","type":"error"},{"inputs":[],"name":"UntrustedCallback","type":"error"},{"inputs":[{"components":[{"internalType":"enum FlashLoopAdapter.Op","name":"op","type":"uint8"},{"internalType":"enum FlashLoopAdapter.Provider","name":"provider","type":"uint8"},{"internalType":"address","name":"providerAddr","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"debt","type":"address"},{"internalType":"uint256","name":"flashAmount","type":"uint256"},{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"bytes","name":"swapCalldata","type":"bytes"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint8","name":"emodeId","type":"uint8"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"}],"internalType":"struct FlashLoopAdapter.Params","name":"p","type":"tuple"}],"name":"close","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"premium","type":"uint256"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"executeOperation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onMorphoFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum FlashLoopAdapter.Op","name":"op","type":"uint8"},{"internalType":"enum FlashLoopAdapter.Provider","name":"provider","type":"uint8"},{"internalType":"address","name":"providerAddr","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"debt","type":"address"},{"internalType":"uint256","name":"flashAmount","type":"uint256"},{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"bytes","name":"swapCalldata","type":"bytes"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint8","name":"emodeId","type":"uint8"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"}],"internalType":"struct FlashLoopAdapter.Params","name":"p","type":"tuple"}],"name":"open","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"feeAmounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"receiveFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}