LCOV - code coverage report
Current view: top level - extensions/paraswap-adapters - ParaSwapLiquiditySwapAdapter.sol (source / functions) Coverage Total Hit
Test: lcov.info.p Lines: 97.1 % 35 34
Test Date: 2024-09-24 09:34:24 Functions: 75.0 % 4 3
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: BUSL-1.1
       2                 :             : pragma solidity ^0.8.10;
       3                 :             : 
       4                 :             : import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
       5                 :             : import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol';
       6                 :             : import {IPoolAddressesProvider} from '../../interfaces/IPoolAddressesProvider.sol';
       7                 :             : import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
       8                 :             : import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
       9                 :             : import {BaseParaSwapSellAdapter} from './BaseParaSwapSellAdapter.sol';
      10                 :             : import {IParaSwapAugustusRegistry} from './interfaces/IParaSwapAugustusRegistry.sol';
      11                 :             : import {IParaSwapAugustus} from './interfaces/IParaSwapAugustus.sol';
      12                 :             : import {ReentrancyGuard} from '../../dependencies/openzeppelin/ReentrancyGuard.sol';
      13                 :             : 
      14                 :             : /**
      15                 :             :  * @title ParaSwapLiquiditySwapAdapter
      16                 :             :  * @notice Adapter to swap liquidity using ParaSwap.
      17                 :             :  * @author Jason Raymond Bell
      18                 :             :  */
      19                 :             : contract ParaSwapLiquiditySwapAdapter is BaseParaSwapSellAdapter, ReentrancyGuard {
      20                 :             :   using SafeMath for uint256;
      21                 :             :   using SafeERC20 for IERC20Detailed;
      22                 :             : 
      23                 :             :   constructor(
      24                 :             :     IPoolAddressesProvider addressesProvider,
      25                 :             :     IParaSwapAugustusRegistry augustusRegistry,
      26                 :             :     address owner
      27                 :             :   ) BaseParaSwapSellAdapter(addressesProvider, augustusRegistry) {
      28                 :           0 :     transferOwnership(owner);
      29                 :             :   }
      30                 :             : 
      31                 :             :   /**
      32                 :             :    * @dev Swaps the received reserve amount from the flash loan into the asset specified in the params.
      33                 :             :    * The received funds from the swap are then deposited into the protocol on behalf of the user.
      34                 :             :    * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and repay the flash loan.
      35                 :             :    * @param asset The address of the flash-borrowed asset
      36                 :             :    * @param amount The amount of the flash-borrowed asset
      37                 :             :    * @param premium The fee of the flash-borrowed asset
      38                 :             :    * @param initiator The address of the flashloan initiator
      39                 :             :    * @param params The byte-encoded params passed when initiating the flashloan
      40                 :             :    * @return True if the execution of the operation succeeds, false otherwise
      41                 :             :    *   address assetToSwapTo Address of the underlying asset to be swapped to and deposited
      42                 :             :    *   uint256 minAmountToReceive Min amount to be received from the swap
      43                 :             :    *   uint256 swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0
      44                 :             :    *   bytes swapCalldata Calldata for ParaSwap's AugustusSwapper contract
      45                 :             :    *   address augustus Address of ParaSwap's AugustusSwapper contract
      46                 :             :    *   PermitSignature permitParams Struct containing the permit signatures, set to all zeroes if not used
      47                 :             :    */
      48                 :             :   function executeOperation(
      49                 :             :     address asset,
      50                 :             :     uint256 amount,
      51                 :             :     uint256 premium,
      52                 :             :     address initiator,
      53                 :             :     bytes calldata params
      54                 :             :   ) external override nonReentrant returns (bool) {
      55                 :           3 :     require(msg.sender == address(POOL), 'CALLER_MUST_BE_POOL');
      56                 :             : 
      57                 :           3 :     uint256 flashLoanAmount = amount;
      58                 :           3 :     uint256 premiumLocal = premium;
      59                 :           3 :     address initiatorLocal = initiator;
      60                 :           3 :     IERC20Detailed assetToSwapFrom = IERC20Detailed(asset);
      61                 :           3 :     (
      62                 :             :       IERC20Detailed assetToSwapTo,
      63                 :             :       uint256 minAmountToReceive,
      64                 :             :       uint256 swapAllBalanceOffset,
      65                 :             :       bytes memory swapCalldata,
      66                 :             :       IParaSwapAugustus augustus,
      67                 :             :       PermitSignature memory permitParams
      68                 :           3 :     ) = abi.decode(
      69                 :             :         params,
      70                 :             :         (IERC20Detailed, uint256, uint256, bytes, IParaSwapAugustus, PermitSignature)
      71                 :             :       );
      72                 :             : 
      73                 :           3 :     _swapLiquidity(
      74                 :             :       swapAllBalanceOffset,
      75                 :             :       swapCalldata,
      76                 :             :       augustus,
      77                 :             :       permitParams,
      78                 :             :       flashLoanAmount,
      79                 :             :       premiumLocal,
      80                 :             :       initiatorLocal,
      81                 :             :       assetToSwapFrom,
      82                 :             :       assetToSwapTo,
      83                 :             :       minAmountToReceive
      84                 :             :     );
      85                 :             : 
      86                 :           2 :     return true;
      87                 :             :   }
      88                 :             : 
      89                 :             :   /**
      90                 :             :    * @dev Swaps an amount of an asset to another and deposits the new asset amount on behalf of the user without using a flash loan.
      91                 :             :    * This method can be used when the temporary transfer of the collateral asset to this contract does not affect the user position.
      92                 :             :    * The user should give this contract allowance to pull the ATokens in order to withdraw the underlying asset and perform the swap.
      93                 :             :    * @param assetToSwapFrom Address of the underlying asset to be swapped from
      94                 :             :    * @param assetToSwapTo Address of the underlying asset to be swapped to and deposited
      95                 :             :    * @param amountToSwap Amount to be swapped, or maximum amount when swapping all balance
      96                 :             :    * @param minAmountToReceive Minimum amount to be received from the swap
      97                 :             :    * @param swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0
      98                 :             :    * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract
      99                 :             :    * @param augustus Address of ParaSwap's AugustusSwapper contract
     100                 :             :    * @param permitParams Struct containing the permit signatures, set to all zeroes if not used
     101                 :             :    */
     102                 :             :   function swapAndDeposit(
     103                 :             :     IERC20Detailed assetToSwapFrom,
     104                 :             :     IERC20Detailed assetToSwapTo,
     105                 :             :     uint256 amountToSwap,
     106                 :             :     uint256 minAmountToReceive,
     107                 :             :     uint256 swapAllBalanceOffset,
     108                 :             :     bytes calldata swapCalldata,
     109                 :             :     IParaSwapAugustus augustus,
     110                 :             :     PermitSignature calldata permitParams
     111                 :             :   ) external nonReentrant {
     112                 :           3 :     IERC20WithPermit aToken = IERC20WithPermit(
     113                 :             :       _getReserveData(address(assetToSwapFrom)).aTokenAddress
     114                 :             :     );
     115                 :             : 
     116                 :           3 :     if (swapAllBalanceOffset != 0) {
     117                 :           1 :       uint256 balance = aToken.balanceOf(msg.sender);
     118                 :           1 :       require(balance <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP');
     119                 :           1 :       amountToSwap = balance;
     120                 :             :     }
     121                 :             : 
     122                 :           3 :     _pullATokenAndWithdraw(
     123                 :             :       address(assetToSwapFrom),
     124                 :             :       aToken,
     125                 :             :       msg.sender,
     126                 :             :       amountToSwap,
     127                 :             :       permitParams
     128                 :             :     );
     129                 :             : 
     130                 :           3 :     uint256 amountReceived = _sellOnParaSwap(
     131                 :             :       swapAllBalanceOffset,
     132                 :             :       swapCalldata,
     133                 :             :       augustus,
     134                 :             :       assetToSwapFrom,
     135                 :             :       assetToSwapTo,
     136                 :             :       amountToSwap,
     137                 :             :       minAmountToReceive
     138                 :             :     );
     139                 :             : 
     140                 :           2 :     assetToSwapTo.safeApprove(address(POOL), 0);
     141                 :           2 :     assetToSwapTo.safeApprove(address(POOL), amountReceived);
     142                 :           2 :     POOL.deposit(address(assetToSwapTo), amountReceived, msg.sender, 0);
     143                 :             :   }
     144                 :             : 
     145                 :             :   /**
     146                 :             :    * @dev Swaps an amount of an asset to another and deposits the funds on behalf of the initiator.
     147                 :             :    * @param swapAllBalanceOffset Set to offset of fromAmount in Augustus calldata if wanting to swap all balance, otherwise 0
     148                 :             :    * @param swapCalldata Calldata for ParaSwap's AugustusSwapper contract
     149                 :             :    * @param augustus Address of ParaSwap's AugustusSwapper contract
     150                 :             :    * @param permitParams Struct containing the permit signatures, set to all zeroes if not used
     151                 :             :    * @param flashLoanAmount Amount of the flash loan i.e. maximum amount to swap
     152                 :             :    * @param premium Fee of the flash loan
     153                 :             :    * @param initiator Account that initiated the flash loan
     154                 :             :    * @param assetToSwapFrom Address of the underyling asset to be swapped from
     155                 :             :    * @param assetToSwapTo Address of the underlying asset to be swapped to and deposited
     156                 :             :    * @param minAmountToReceive Min amount to be received from the swap
     157                 :             :    */
     158                 :             :   function _swapLiquidity(
     159                 :             :     uint256 swapAllBalanceOffset,
     160                 :             :     bytes memory swapCalldata,
     161                 :             :     IParaSwapAugustus augustus,
     162                 :             :     PermitSignature memory permitParams,
     163                 :             :     uint256 flashLoanAmount,
     164                 :             :     uint256 premium,
     165                 :             :     address initiator,
     166                 :             :     IERC20Detailed assetToSwapFrom,
     167                 :             :     IERC20Detailed assetToSwapTo,
     168                 :             :     uint256 minAmountToReceive
     169                 :             :   ) internal {
     170                 :           3 :     IERC20WithPermit aToken = IERC20WithPermit(
     171                 :             :       _getReserveData(address(assetToSwapFrom)).aTokenAddress
     172                 :             :     );
     173                 :           3 :     uint256 amountToSwap = flashLoanAmount;
     174                 :             : 
     175                 :           3 :     uint256 balance = aToken.balanceOf(initiator);
     176                 :           3 :     if (swapAllBalanceOffset != 0) {
     177                 :           1 :       uint256 balanceToSwap = balance.sub(premium);
     178                 :           1 :       require(balanceToSwap <= amountToSwap, 'INSUFFICIENT_AMOUNT_TO_SWAP');
     179                 :           1 :       amountToSwap = balanceToSwap;
     180                 :             :     } else {
     181                 :           2 :       require(balance >= amountToSwap.add(premium), 'INSUFFICIENT_ATOKEN_BALANCE');
     182                 :             :     }
     183                 :             : 
     184                 :           3 :     uint256 amountReceived = _sellOnParaSwap(
     185                 :             :       swapAllBalanceOffset,
     186                 :             :       swapCalldata,
     187                 :             :       augustus,
     188                 :             :       assetToSwapFrom,
     189                 :             :       assetToSwapTo,
     190                 :             :       amountToSwap,
     191                 :             :       minAmountToReceive
     192                 :             :     );
     193                 :             : 
     194                 :           2 :     assetToSwapTo.safeApprove(address(POOL), 0);
     195                 :           2 :     assetToSwapTo.safeApprove(address(POOL), amountReceived);
     196                 :           2 :     POOL.deposit(address(assetToSwapTo), amountReceived, initiator, 0);
     197                 :             : 
     198                 :           2 :     _pullATokenAndWithdraw(
     199                 :             :       address(assetToSwapFrom),
     200                 :             :       aToken,
     201                 :             :       initiator,
     202                 :             :       amountToSwap.add(premium),
     203                 :             :       permitParams
     204                 :             :     );
     205                 :             : 
     206                 :             :     // Repay flash loan
     207                 :           2 :     assetToSwapFrom.safeApprove(address(POOL), 0);
     208                 :           2 :     assetToSwapFrom.safeApprove(address(POOL), flashLoanAmount.add(premium));
     209                 :             :   }
     210                 :             : }
        

Generated by: LCOV version 2.1-1