Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xf6749c436cebC29A14196ffb1D58e3098c96f43b
Balance 0 ETH
Nonce 1
Code Size 6013 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

6013 bytes
0x6080604052600436106100dc575f3560e01c8063715018a61161007c578063a03017ec11610057578063a03017ec1461020e578063b62e3a2b14610221578063d7a5791a1461023e578063f2fde38b1461025d575f80fd5b8063715018a6146101bf57806382529ab2146101d35780638da5cb5b146101f2575f80fd5b80633e4d0310116100b75780633e4d03101461013d578063487c5f861461015c5780635459060d1461017b5780636fefa7e6146101ac575f80fd5b806302d2f0a8146100e7578063350c35e91461010957806339a725741461012a575f80fd5b366100e357005b5f80fd5b3480156100f2575f80fd5b506005546040519081526020015b60405180910390f35b348015610114575f80fd5b5061012861012336600461137f565b61027c565b005b6101286101383660046113a9565b610549565b348015610148575f80fd5b506101286101573660046113db565b6107c5565b348015610167575f80fd5b506101286101763660046113a9565b61087c565b348015610186575f80fd5b506003546001600160a01b03165b6040516001600160a01b039091168152602001610100565b6101286101ba36600461137f565b610a44565b3480156101ca575f80fd5b50610128610d6d565b3480156101de575f80fd5b506101286101ed3660046113db565b610d80565b3480156101fd575f80fd5b505f546001600160a01b0316610194565b61012861021c3660046113fd565b610e37565b34801561022c575f80fd5b506004546001600160a01b0316610194565b348015610249575f80fd5b5061012861025836600461147f565b61103b565b348015610268575f80fd5b506101286102773660046113db565b6110d4565b5f336001546040516335ea6a7560e01b81526001600160a01b0386811660048301529293505f92909116906335ea6a75906024016101e060405180830381865afa1580156102cc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102f0919061156c565b610100015190506001600160a01b03811661031e5760405163736240c360e11b815260040160405180910390fd5b6040516323b872dd60e01b815281906001600160a01b038216906323b872dd906103509086903090899060040161168d565b5f604051808303815f87803b158015610367575f80fd5b505af1158015610379573d5f803e3d5ffd5b505050506103e48273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316876001600160a01b0316146103c8577387870bca3f3fd6335c3f4ce8392d69350b4fa4e26103de565b73a434d495249abe33e031fe71a969b81f3c07950d5b86611116565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc1196001600160a01b0386160161047757600254604051630402806960e51b81526001600160a01b038781166004830152602482018790528581166044830152909116906380500d20906064015f604051808303815f87803b15801561045c575f80fd5b505af115801561046e573d5f803e3d5ffd5b505050506104f5565b600154604051631a4ca37b60e21b81526001600160a01b038781166004830152602482018790528581166044830152909116906369328dec906064016020604051808303815f875af11580156104cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104f391906116b1565b505b846001600160a01b0316836001600160a01b03167f45892a46e6cef329bb642da6d69846d324db43d19008edc141ed82382eda1bee8660405161053a91815260200190565b60405180910390a35050505050565b6001600160a01b0383166105705760405163736240c360e11b815260040160405180910390fd5b6040516323b872dd60e01b8152339084906001600160a01b038216906323b872dd906105a49085903090889060040161168d565b5f604051808303815f87803b1580156105bb575f80fd5b505af11580156105cd573d5f803e3d5ffd5b505050506105f0857387870bca3f3fd6335c3f4ce8392d69350b4fa4e285611116565b60015460405163573ade8160e01b81526001600160a01b038781166004830152602482018690526044820187905284811660648301525f92169063573ade81906084016020604051808303815f875af115801561064f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061067391906116b1565b90505f61067f826111f2565b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529193508516915063a9059cbb906044015f604051808303815f87803b1580156106cd575f80fd5b505af11580156106df573d5f803e3d5ffd5b505050505f81836106f091906116dc565b90508086111561076e576001600160a01b03841663a9059cbb86610714848a6116ef565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015f604051808303815f87803b158015610757575f80fd5b505af1158015610769573d5f803e3d5ffd5b505050505b876001600160a01b0316856001600160a01b03167feef1a28252f7c3266ccea3202ee9693f0834485bc3551310a406e04829c7e2cf856040516107b391815260200190565b60405180910390a35050505050505050565b6107cd611242565b6001600160a01b0381166107f45760405163736240c360e11b815260040160405180910390fd5b60035433906001600160a01b03908116908316810361082657604051632207bb5560e21b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b03858116918217909255604051909183811691908516907fc3dbed633419bef4f3e9a5c99c8ec27cfe0be61602f694260c9bb74938d74333905f90a4505050565b6001600160a01b0383166108a35760405163736240c360e11b815260040160405180910390fd5b5f3360015460405163a415bcad60e01b81526001600160a01b03808816600483015260248201879052604482018690525f6064830152808416608483015292935086929091169063a415bcad9060a4015f604051808303815f87803b15801561090a575f80fd5b505af115801561091c573d5f803e3d5ffd5b505050505f8061092b866111f2565b60035460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905292945090925084169063a9059cbb906044015f604051808303815f87803b15801561097b575f80fd5b505af115801561098d573d5f803e3d5ffd5b505060405163a9059cbb60e01b81526001600160a01b038781166004830152602482018690528616925063a9059cbb91506044015f604051808303815f87803b1580156109d8575f80fd5b505af11580156109ea573d5f803e3d5ffd5b50505050866001600160a01b0316846001600160a01b03167f9bdaf399f8887e92c0b0e61b959bc392518bddb3c55aeae6dca185393f77c85c88604051610a3391815260200190565b60405180910390a350505050505050565b6001600160a01b038216610a6b5760405163736240c360e11b815260040160405180910390fd5b335f80610a778561126e565b15610b0557610a85346111f2565b9092509050610a93816112a7565b60025460405163474cf53d60e01b81525f600482018190526001600160a01b03868116602484015260448301919091529091169063474cf53d9084906064015f604051808303818588803b158015610ae9575f80fd5b505af1158015610afb573d5f803e3d5ffd5b5050505050610d28565b6040516323b872dd60e01b815285906001600160a01b038216906323b872dd90610b3790879030908a9060040161168d565b5f604051808303815f87803b158015610b4e575f80fd5b505af1158015610b60573d5f803e3d5ffd5b50505050610b6d856111f2565b60035460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810183905292955090935082169063a9059cbb906044015f604051808303815f87803b158015610bbd575f80fd5b505af1158015610bcf573d5f803e3d5ffd5b5050505073ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316866001600160a01b031603610c9857610c1f86737f39c581f595b53c5cb19bd0b3f8da6c935e2ca085611116565b604051630ea598cb60e41b815260048101849052737f39c581f595b53c5cb19bd0b3f8da6c935e2ca09650869063ea598cb0906024016020604051808303815f875af1158015610c71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c9591906116b1565b92505b610cb7867387870bca3f3fd6335c3f4ce8392d69350b4fa4e285611116565b60015460405163617ba03760e01b81526001600160a01b0388811660048301526024820186905286811660448301525f60648301529091169063617ba037906084015f604051808303815f87803b158015610d10575f80fd5b505af1158015610d22573d5f803e3d5ffd5b50505050505b846001600160a01b0316836001600160a01b03167ff61b12856dcc5ac340f42141c209e2939c73a5b74c6c5a8e8d3ab4f5b09b50678460405161053a91815260200190565b610d75611242565b610d7e5f61131c565b565b610d88611242565b6001600160a01b038116610daf5760405163736240c360e11b815260040160405180910390fd5b60045433906001600160a01b039081169083168103610de157604051632207bb5560e21b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b03858116918217909255604051909183811691908516907f979878e260cf2ff28339b73908e50e7963687d6eb12b05120d960edc99f75f12905f90a4505050565b3334610e435783610e45565b345b93505f80610e52866111f2565b91509150610e5f8761126e565b15610e7257610e6d816112a7565b610f4c565b6040516323b872dd60e01b815287906001600160a01b038216906323b872dd90610ea490879030908c9060040161168d565b5f604051808303815f87803b158015610ebb575f80fd5b505af1158015610ecd573d5f803e3d5ffd5b505060035460405163a9059cbb60e01b81526001600160a01b03918216600482015260248101869052908416925063a9059cbb91506044015f604051808303815f87803b158015610f1c575f80fd5b505af1158015610f2e573d5f803e3d5ffd5b5050600454610f4a92508a91506001600160a01b031689611116565b505b5f803411610f5a575f610f5c565b825b6004546040519192505f916001600160a01b03909116908390610f82908a908a90611702565b5f6040518083038185875af1925050503d805f8114610fbc576040519150601f19603f3d011682016040523d82523d5f602084013e610fc1565b606091505b5050905080610fe357604051633ed2f09560e21b815260040160405180910390fd5b886001600160a01b0316856001600160a01b03167fb390769946a1738b154fb55ca5dc9fd4f2bd4ce6cb14c1b3a7e79afd9dcdf2f78660405161102891815260200190565b60405180910390a3505050505050505050565b611043611242565b612710811061106557604051633238c54560e11b815260040160405180910390fd5b600554339082810361108a57604051632207bb5560e21b815260040160405180910390fd5b600583905560405183815281906001600160a01b038416907f942a5da75669c7b1137863f869c2552897c65b2a6046d482ad0826d5420c2af79060200160405180910390a3505050565b6110dc611242565b6001600160a01b03811661110a57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6111138161131c565b50565b604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284919082169063dd62ed3e90604401602060405180830381865afa158015611163573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061118791906116b1565b8211156111ec5760405163095ea7b360e01b81526001600160a01b0384811660048301525f19602483015282169063095ea7b3906044015f604051808303815f87803b1580156111d5575f80fd5b505af11580156111e7573d5f803e3d5ffd5b505050505b50505050565b5f80825f036112145760405163172e2f6760e31b815260040160405180910390fd5b612710600554846112259190611711565b61122f9190611728565b905061123b81846116ef565b9150915091565b5f546001600160a01b03163314610d7e5760405163118cdaa760e01b8152336004820152602401611101565b5f6001600160a01b03821615806112a157506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b92915050565b6003546040515f916001600160a01b03169083908381818185875af1925050503d805f81146112f1576040519150601f19603f3d011682016040523d82523d5f602084013e6112f6565b606091505b50509050806113185760405163ed0bce0560e01b815260040160405180910390fd5b5050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381168114611113575f80fd5b5f8060408385031215611390575f80fd5b823561139b8161136b565b946020939093013593505050565b5f805f606084860312156113bb575f80fd5b83356113c68161136b565b95602085013595506040909401359392505050565b5f602082840312156113eb575f80fd5b81356113f68161136b565b9392505050565b5f805f8060608587031215611410575f80fd5b843561141b8161136b565b935060208501359250604085013567ffffffffffffffff8082111561143e575f80fd5b818701915087601f830112611451575f80fd5b81358181111561145f575f80fd5b886020828501011115611470575f80fd5b95989497505060200194505050565b5f6020828403121561148f575f80fd5b5035919050565b6040516101e0810167ffffffffffffffff811182821017156114c657634e487b7160e01b5f52604160045260245ffd5b60405290565b5f602082840312156114dc575f80fd5b6040516020810181811067ffffffffffffffff8211171561150b57634e487b7160e01b5f52604160045260245ffd5b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff81168114611537575f80fd5b919050565b805164ffffffffff81168114611537575f80fd5b805161ffff81168114611537575f80fd5b80516115378161136b565b5f6101e0828403121561157d575f80fd5b611585611496565b61158f84846114cc565b815261159d60208401611518565b60208201526115ae60408401611518565b60408201526115bf60608401611518565b60608201526115d060808401611518565b60808201526115e160a08401611518565b60a08201526115f260c0840161153c565b60c082015261160360e08401611550565b60e0820152610100611616818501611561565b90820152610120611628848201611561565b9082015261014061163a848201611561565b9082015261016061164c848201611561565b9082015261018061165e848201611518565b908201526101a0611670848201611518565b908201526101c0611682848201611518565b908201529392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f602082840312156116c1575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156112a1576112a16116c8565b818103818111156112a1576112a16116c8565b818382375f9101908152919050565b80820281158282048414176112a1576112a16116c8565b5f8261174257634e487b7160e01b5f52601260045260245ffd5b50049056fea26469706673582212205eca1e6088ccb4e8cda60ee3b0b061b73890f054dca642fd41e0fc9e437818f164736f6c63430008140033

Verified Source Code Full Match

Compiler: v0.8.20+commit.a1b79de6 EVM: shanghai Optimization: Yes (200 runs)
IPool.sol 737 lines
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;

import {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';

/**
 * @title IPool
 * @author Aave
 * @notice Defines the basic interface for an Aave Pool.
 */
interface IPool {
  /**
   * @dev Emitted on mintUnbacked()
   * @param reserve The address of the underlying asset of the reserve
   * @param user The address initiating the supply
   * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens
   * @param amount The amount of supplied assets
   * @param referralCode The referral code used
   */
  event MintUnbacked(
    address indexed reserve,
    address user,
    address indexed onBehalfOf,
    uint256 amount,
    uint16 indexed referralCode
  );

  /**
   * @dev Emitted on backUnbacked()
   * @param reserve The address of the underlying asset of the reserve
   * @param backer The address paying for the backing
   * @param amount The amount added as backing
   * @param fee The amount paid in fees
   */
  event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee);

  /**
   * @dev Emitted on supply()
   * @param reserve The address of the underlying asset of the reserve
   * @param user The address initiating the supply
   * @param onBehalfOf The beneficiary of the supply, receiving the aTokens
   * @param amount The amount supplied
   * @param referralCode The referral code used
   */
  event Supply(
    address indexed reserve,
    address user,
    address indexed onBehalfOf,
    uint256 amount,
    uint16 indexed referralCode
  );

  /**
   * @dev Emitted on withdraw()
   * @param reserve The address of the underlying asset being withdrawn
   * @param user The address initiating the withdrawal, owner of aTokens
   * @param to The address that will receive the underlying
   * @param amount The amount to be withdrawn
   */
  event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);

  /**
   * @dev Emitted on borrow() and flashLoan() when debt needs to be opened
   * @param reserve The address of the underlying asset being borrowed
   * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
   * initiator of the transaction on flashLoan()
   * @param onBehalfOf The address that will be getting the debt
   * @param amount The amount borrowed out
   * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable
   * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray
   * @param referralCode The referral code used
   */
  event Borrow(
    address indexed reserve,
    address user,
    address indexed onBehalfOf,
    uint256 amount,
    DataTypes.InterestRateMode interestRateMode,
    uint256 borrowRate,
    uint16 indexed referralCode
  );

  /**
   * @dev Emitted on repay()
   * @param reserve The address of the underlying asset of the reserve
   * @param user The beneficiary of the repayment, getting his debt reduced
   * @param repayer The address of the user initiating the repay(), providing the funds
   * @param amount The amount repaid
   * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly
   */
  event Repay(
    address indexed reserve,
    address indexed user,
    address indexed repayer,
    uint256 amount,
    bool useATokens
  );

  /**
   * @dev Emitted on swapBorrowRateMode()
   * @param reserve The address of the underlying asset of the reserve
   * @param user The address of the user swapping his rate mode
   * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable
   */
  event SwapBorrowRateMode(
    address indexed reserve,
    address indexed user,
    DataTypes.InterestRateMode interestRateMode
  );

  /**
   * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets
   * @param asset The address of the underlying asset of the reserve
   * @param totalDebt The total isolation mode debt for the reserve
   */
  event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt);

  /**
   * @dev Emitted when the user selects a certain asset category for eMode
   * @param user The address of the user
   * @param categoryId The category id
   */
  event UserEModeSet(address indexed user, uint8 categoryId);

  /**
   * @dev Emitted on setUserUseReserveAsCollateral()
   * @param reserve The address of the underlying asset of the reserve
   * @param user The address of the user enabling the usage as collateral
   */
  event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);

  /**
   * @dev Emitted on setUserUseReserveAsCollateral()
   * @param reserve The address of the underlying asset of the reserve
   * @param user The address of the user enabling the usage as collateral
   */
  event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);

  /**
   * @dev Emitted on rebalanceStableBorrowRate()
   * @param reserve The address of the underlying asset of the reserve
   * @param user The address of the user for which the rebalance has been executed
   */
  event RebalanceStableBorrowRate(address indexed reserve, address indexed user);

  /**
   * @dev Emitted on flashLoan()
   * @param target The address of the flash loan receiver contract
   * @param initiator The address initiating the flash loan
   * @param asset The address of the asset being flash borrowed
   * @param amount The amount flash borrowed
   * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt
   * @param premium The fee flash borrowed
   * @param referralCode The referral code used
   */
  event FlashLoan(
    address indexed target,
    address initiator,
    address indexed asset,
    uint256 amount,
    DataTypes.InterestRateMode interestRateMode,
    uint256 premium,
    uint16 indexed referralCode
  );

  /**
   * @dev Emitted when a borrower is liquidated.
   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
   * @param user The address of the borrower getting liquidated
   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
   * @param liquidatedCollateralAmount The amount of collateral received by the liquidator
   * @param liquidator The address of the liquidator
   * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
   * to receive the underlying collateral asset directly
   */
  event LiquidationCall(
    address indexed collateralAsset,
    address indexed debtAsset,
    address indexed user,
    uint256 debtToCover,
    uint256 liquidatedCollateralAmount,
    address liquidator,
    bool receiveAToken
  );

  /**
   * @dev Emitted when the state of a reserve is updated.
   * @param reserve The address of the underlying asset of the reserve
   * @param liquidityRate The next liquidity rate
   * @param stableBorrowRate The next stable borrow rate
   * @param variableBorrowRate The next variable borrow rate
   * @param liquidityIndex The next liquidity index
   * @param variableBorrowIndex The next variable borrow index
   */
  event ReserveDataUpdated(
    address indexed reserve,
    uint256 liquidityRate,
    uint256 stableBorrowRate,
    uint256 variableBorrowRate,
    uint256 liquidityIndex,
    uint256 variableBorrowIndex
  );

  /**
   * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest.
   * @param reserve The address of the reserve
   * @param amountMinted The amount minted to the treasury
   */
  event MintedToTreasury(address indexed reserve, uint256 amountMinted);

  /**
   * @notice Mints an `amount` of aTokens to the `onBehalfOf`
   * @param asset The address of the underlying asset to mint
   * @param amount The amount to mint
   * @param onBehalfOf The address that will receive the aTokens
   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
   *   0 if the action is executed directly by the user, without any middle-man
   */
  function mintUnbacked(
    address asset,
    uint256 amount,
    address onBehalfOf,
    uint16 referralCode
  ) external;

  /**
   * @notice Back the current unbacked underlying with `amount` and pay `fee`.
   * @param asset The address of the underlying asset to back
   * @param amount The amount to back
   * @param fee The amount paid in fees
   * @return The backed amount
   */
  function backUnbacked(address asset, uint256 amount, uint256 fee) external returns (uint256);

  /**
   * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
   * - E.g. User supplies 100 USDC and gets in return 100 aUSDC
   * @param asset The address of the underlying asset to supply
   * @param amount The amount to be supplied
   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
   *   is a different wallet
   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
   *   0 if the action is executed directly by the user, without any middle-man
   */
  function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;

  /**
   * @notice Supply with transfer approval of asset to be supplied done via permit function
   * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
   * @param asset The address of the underlying asset to supply
   * @param amount The amount to be supplied
   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
   *   is a different wallet
   * @param deadline The deadline timestamp that the permit is valid
   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
   *   0 if the action is executed directly by the user, without any middle-man
   * @param permitV The V parameter of ERC712 permit sig
   * @param permitR The R parameter of ERC712 permit sig
   * @param permitS The S parameter of ERC712 permit sig
   */
  function supplyWithPermit(
    address asset,
    uint256 amount,
    address onBehalfOf,
    uint16 referralCode,
    uint256 deadline,
    uint8 permitV,
    bytes32 permitR,
    bytes32 permitS
  ) external;

  /**
   * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
   * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
   * @param asset The address of the underlying asset to withdraw
   * @param amount The underlying amount to be withdrawn
   *   - Send the value type(uint256).max in order to withdraw the whole aToken balance
   * @param to The address that will receive the underlying, same as msg.sender if the user
   *   wants to receive it on his own wallet, or a different address if the beneficiary is a
   *   different wallet
   * @return The final amount withdrawn
   */
  function withdraw(address asset, uint256 amount, address to) external returns (uint256);

  /**
   * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
   * already supplied enough collateral, or he was given enough allowance by a credit delegator on the
   * corresponding debt token (StableDebtToken or VariableDebtToken)
   * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
   *   and 100 stable/variable debt tokens, depending on the `interestRateMode`
   * @param asset The address of the underlying asset to borrow
   * @param amount The amount to be borrowed
   * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
   * @param referralCode The code used to register the integrator originating the operation, for potential rewards.
   *   0 if the action is executed directly by the user, without any middle-man
   * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself
   * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
   * if he has been given credit delegation allowance
   */
  function borrow(
    address asset,
    uint256 amount,
    uint256 interestRateMode,
    uint16 referralCode,
    address onBehalfOf
  ) external;

  /**
   * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
   * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
   * @param asset The address of the borrowed underlying asset previously borrowed
   * @param amount The amount to repay
   * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
   * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
   * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the
   * user calling the function if he wants to reduce/remove his own debt, or the address of any other
   * other borrower whose debt should be removed
   * @return The final amount repaid
   */
  function repay(
    address asset,
    uint256 amount,
    uint256 interestRateMode,
    address onBehalfOf
  ) external returns (uint256);

  /**
   * @notice Repay with transfer approval of asset to be repaid done via permit function
   * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713
   * @param asset The address of the borrowed underlying asset previously borrowed
   * @param amount The amount to repay
   * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
   * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
   * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
   * user calling the function if he wants to reduce/remove his own debt, or the address of any other
   * other borrower whose debt should be removed
   * @param deadline The deadline timestamp that the permit is valid
   * @param permitV The V parameter of ERC712 permit sig
   * @param permitR The R parameter of ERC712 permit sig
   * @param permitS The S parameter of ERC712 permit sig
   * @return The final amount repaid
   */
  function repayWithPermit(
    address asset,
    uint256 amount,
    uint256 interestRateMode,
    address onBehalfOf,
    uint256 deadline,
    uint8 permitV,
    bytes32 permitR,
    bytes32 permitS
  ) external returns (uint256);

  /**
   * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the
   * equivalent debt tokens
   * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens
   * @dev  Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken
   * balance is not enough to cover the whole debt
   * @param asset The address of the borrowed underlying asset previously borrowed
   * @param amount The amount to repay
   * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
   * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
   * @return The final amount repaid
   */
  function repayWithATokens(
    address asset,
    uint256 amount,
    uint256 interestRateMode
  ) external returns (uint256);

  /**
   * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa
   * @param asset The address of the underlying asset borrowed
   * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable
   */
  function swapBorrowRateMode(address asset, uint256 interestRateMode) external;

  /**
   * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
   * - Users can be rebalanced if the following conditions are satisfied:
   *     1. Usage ratio is above 95%
   *     2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too
   *        much has been borrowed at a stable rate and suppliers are not earning enough
   * @param asset The address of the underlying asset borrowed
   * @param user The address of the user to be rebalanced
   */
  function rebalanceStableBorrowRate(address asset, address user) external;

  /**
   * @notice Allows suppliers to enable/disable a specific supplied asset as collateral
   * @param asset The address of the underlying asset supplied
   * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise
   */
  function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;

  /**
   * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
   * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
   *   a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
   * @param user The address of the borrower getting liquidated
   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
   * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants
   * to receive the underlying collateral asset directly
   */
  function liquidationCall(
    address collateralAsset,
    address debtAsset,
    address user,
    uint256 debtToCover,
    bool receiveAToken
  ) external;

  /**
   * @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
   * as long as the amount taken plus a fee is returned.
   * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
   * into consideration. For further details please visit https://docs.aave.com/developers/
   * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface
   * @param assets The addresses of the assets being flash-borrowed
   * @param amounts The amounts of the assets being flash-borrowed
   * @param interestRateModes Types of the debt to open if the flash loan is not returned:
   *   0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
   *   1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
   *   2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
   * @param onBehalfOf The address  that will receive the debt in the case of using on `modes` 1 or 2
   * @param params Variadic packed params to pass to the receiver as extra information
   * @param referralCode The code used to register the integrator originating the operation, for potential rewards.
   *   0 if the action is executed directly by the user, without any middle-man
   */
  function flashLoan(
    address receiverAddress,
    address[] calldata assets,
    uint256[] calldata amounts,
    uint256[] calldata interestRateModes,
    address onBehalfOf,
    bytes calldata params,
    uint16 referralCode
  ) external;

  /**
   * @notice Allows smartcontracts to access the liquidity of the pool within one transaction,
   * as long as the amount taken plus a fee is returned.
   * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept
   * into consideration. For further details please visit https://docs.aave.com/developers/
   * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface
   * @param asset The address of the asset being flash-borrowed
   * @param amount The amount of the asset being flash-borrowed
   * @param params Variadic packed params to pass to the receiver as extra information
   * @param referralCode The code used to register the integrator originating the operation, for potential rewards.
   *   0 if the action is executed directly by the user, without any middle-man
   */
  function flashLoanSimple(
    address receiverAddress,
    address asset,
    uint256 amount,
    bytes calldata params,
    uint16 referralCode
  ) external;

  /**
   * @notice Returns the user account data across all the reserves
   * @param user The address of the user
   * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed
   * @return totalDebtBase The total debt of the user in the base currency used by the price feed
   * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed
   * @return currentLiquidationThreshold The liquidation threshold of the user
   * @return ltv The loan to value of The user
   * @return healthFactor The current health factor of the user
   */
  function getUserAccountData(
    address user
  )
    external
    view
    returns (
      uint256 totalCollateralBase,
      uint256 totalDebtBase,
      uint256 availableBorrowsBase,
      uint256 currentLiquidationThreshold,
      uint256 ltv,
      uint256 healthFactor
    );

  /**
   * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an
   * interest rate strategy
   * @dev Only callable by the PoolConfigurator contract
   * @param asset The address of the underlying asset of the reserve
   * @param aTokenAddress The address of the aToken that will be assigned to the reserve
   * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve
   * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve
   * @param interestRateStrategyAddress The address of the interest rate strategy contract
   */
  function initReserve(
    address asset,
    address aTokenAddress,
    address stableDebtAddress,
    address variableDebtAddress,
    address interestRateStrategyAddress
  ) external;

  /**
   * @notice Drop a reserve
   * @dev Only callable by the PoolConfigurator contract
   * @param asset The address of the underlying asset of the reserve
   */
  function dropReserve(address asset) external;

  /**
   * @notice Updates the address of the interest rate strategy contract
   * @dev Only callable by the PoolConfigurator contract
   * @param asset The address of the underlying asset of the reserve
   * @param rateStrategyAddress The address of the interest rate strategy contract
   */
  function setReserveInterestRateStrategyAddress(
    address asset,
    address rateStrategyAddress
  ) external;

  /**
   * @notice Sets the configuration bitmap of the reserve as a whole
   * @dev Only callable by the PoolConfigurator contract
   * @param asset The address of the underlying asset of the reserve
   * @param configuration The new configuration bitmap
   */
  function setConfiguration(
    address asset,
    DataTypes.ReserveConfigurationMap calldata configuration
  ) external;

  /**
   * @notice Returns the configuration of the reserve
   * @param asset The address of the underlying asset of the reserve
   * @return The configuration of the reserve
   */
  function getConfiguration(
    address asset
  ) external view returns (DataTypes.ReserveConfigurationMap memory);

  /**
   * @notice Returns the configuration of the user across all the reserves
   * @param user The user address
   * @return The configuration of the user
   */
  function getUserConfiguration(
    address user
  ) external view returns (DataTypes.UserConfigurationMap memory);

  /**
   * @notice Returns the normalized income of the reserve
   * @param asset The address of the underlying asset of the reserve
   * @return The reserve's normalized income
   */
  function getReserveNormalizedIncome(address asset) external view returns (uint256);

  /**
   * @notice Returns the normalized variable debt per unit of asset
   * @dev WARNING: This function is intended to be used primarily by the protocol itself to get a
   * "dynamic" variable index based on time, current stored index and virtual rate at the current
   * moment (approx. a borrower would get if opening a position). This means that is always used in
   * combination with variable debt supply/balances.
   * If using this function externally, consider that is possible to have an increasing normalized
   * variable debt that is not equivalent to how the variable debt index would be updated in storage
   * (e.g. only updates with non-zero variable debt supply)
   * @param asset The address of the underlying asset of the reserve
   * @return The reserve normalized variable debt
   */
  function getReserveNormalizedVariableDebt(address asset) external view returns (uint256);

  /**
   * @notice Returns the state and configuration of the reserve
   * @param asset The address of the underlying asset of the reserve
   * @return The state and configuration data of the reserve
   */
  function getReserveData(address asset) external view returns (DataTypes.ReserveData memory);

  /**
   * @notice Validates and finalizes an aToken transfer
   * @dev Only callable by the overlying aToken of the `asset`
   * @param asset The address of the underlying asset of the aToken
   * @param from The user from which the aTokens are transferred
   * @param to The user receiving the aTokens
   * @param amount The amount being transferred/withdrawn
   * @param balanceFromBefore The aToken balance of the `from` user before the transfer
   * @param balanceToBefore The aToken balance of the `to` user before the transfer
   */
  function finalizeTransfer(
    address asset,
    address from,
    address to,
    uint256 amount,
    uint256 balanceFromBefore,
    uint256 balanceToBefore
  ) external;

  /**
   * @notice Returns the list of the underlying assets of all the initialized reserves
   * @dev It does not include dropped reserves
   * @return The addresses of the underlying assets of the initialized reserves
   */
  function getReservesList() external view returns (address[] memory);

  /**
   * @notice Returns the address of the underlying asset of a reserve by the reserve id as stored in the DataTypes.ReserveData struct
   * @param id The id of the reserve as stored in the DataTypes.ReserveData struct
   * @return The address of the reserve associated with id
   */
  function getReserveAddressById(uint16 id) external view returns (address);

  /**
   * @notice Returns the PoolAddressesProvider connected to this contract
   * @return The address of the PoolAddressesProvider
   */
  function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);

  /**
   * @notice Updates the protocol fee on the bridging
   * @param bridgeProtocolFee The part of the premium sent to the protocol treasury
   */
  function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external;

  /**
   * @notice Updates flash loan premiums. Flash loan premium consists of two parts:
   * - A part is sent to aToken holders as extra, one time accumulated interest
   * - A part is collected by the protocol treasury
   * @dev The total premium is calculated on the total borrowed amount
   * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal`
   * @dev Only callable by the PoolConfigurator contract
   * @param flashLoanPremiumTotal The total premium, expressed in bps
   * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps
   */
  function updateFlashloanPremiums(
    uint128 flashLoanPremiumTotal,
    uint128 flashLoanPremiumToProtocol
  ) external;

  /**
   * @notice Configures a new category for the eMode.
   * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category.
   * The category 0 is reserved as it's the default for volatile assets
   * @param id The id of the category
   * @param config The configuration of the category
   */
  function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external;

  /**
   * @notice Returns the data of an eMode category
   * @param id The id of the category
   * @return The configuration data of the category
   */
  function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory);

  /**
   * @notice Allows a user to use the protocol in eMode
   * @param categoryId The id of the category
   */
  function setUserEMode(uint8 categoryId) external;

  /**
   * @notice Returns the eMode the user is using
   * @param user The address of the user
   * @return The eMode id
   */
  function getUserEMode(address user) external view returns (uint256);

  /**
   * @notice Resets the isolation mode total debt of the given asset to zero
   * @dev It requires the given asset has zero debt ceiling
   * @param asset The address of the underlying asset to reset the isolationModeTotalDebt
   */
  function resetIsolationModeTotalDebt(address asset) external;

  /**
   * @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate
   * @return The percentage of available liquidity to borrow, expressed in bps
   */
  function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256);

  /**
   * @notice Returns the total fee on flash loans
   * @return The total fee on flashloans
   */
  function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);

  /**
   * @notice Returns the part of the bridge fees sent to protocol
   * @return The bridge fee sent to the protocol treasury
   */
  function BRIDGE_PROTOCOL_FEE() external view returns (uint256);

  /**
   * @notice Returns the part of the flashloan fees sent to protocol
   * @return The flashloan fee sent to the protocol treasury
   */
  function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128);

  /**
   * @notice Returns the maximum number of reserves supported to be listed in this Pool
   * @return The maximum number of reserves supported
   */
  function MAX_NUMBER_RESERVES() external view returns (uint16);

  /**
   * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens
   * @param assets The list of reserves for which the minting needs to be executed
   */
  function mintToTreasury(address[] calldata assets) external;

  /**
   * @notice Rescue and transfer tokens locked in this contract
   * @param token The address of the token
   * @param to The address of the recipient
   * @param amount The amount of token to transfer
   */
  function rescueTokens(address token, address to, uint256 amount) external;

  /**
   * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
   * - E.g. User supplies 100 USDC and gets in return 100 aUSDC
   * @dev Deprecated: Use the `supply` function instead
   * @param asset The address of the underlying asset to supply
   * @param amount The amount to be supplied
   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
   *   is a different wallet
   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
   *   0 if the action is executed directly by the user, without any middle-man
   */
  function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;
}
IPoolAddressesProvider.sol 227 lines
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;

/**
 * @title IPoolAddressesProvider
 * @author Aave
 * @notice Defines the basic interface for a Pool Addresses Provider.
 */
interface IPoolAddressesProvider {
  /**
   * @dev Emitted when the market identifier is updated.
   * @param oldMarketId The old id of the market
   * @param newMarketId The new id of the market
   */
  event MarketIdSet(string indexed oldMarketId, string indexed newMarketId);

  /**
   * @dev Emitted when the pool is updated.
   * @param oldAddress The old address of the Pool
   * @param newAddress The new address of the Pool
   */
  event PoolUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the pool configurator is updated.
   * @param oldAddress The old address of the PoolConfigurator
   * @param newAddress The new address of the PoolConfigurator
   */
  event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the price oracle is updated.
   * @param oldAddress The old address of the PriceOracle
   * @param newAddress The new address of the PriceOracle
   */
  event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the ACL manager is updated.
   * @param oldAddress The old address of the ACLManager
   * @param newAddress The new address of the ACLManager
   */
  event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the ACL admin is updated.
   * @param oldAddress The old address of the ACLAdmin
   * @param newAddress The new address of the ACLAdmin
   */
  event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the price oracle sentinel is updated.
   * @param oldAddress The old address of the PriceOracleSentinel
   * @param newAddress The new address of the PriceOracleSentinel
   */
  event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the pool data provider is updated.
   * @param oldAddress The old address of the PoolDataProvider
   * @param newAddress The new address of the PoolDataProvider
   */
  event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when a new proxy is created.
   * @param id The identifier of the proxy
   * @param proxyAddress The address of the created proxy contract
   * @param implementationAddress The address of the implementation contract
   */
  event ProxyCreated(
    bytes32 indexed id,
    address indexed proxyAddress,
    address indexed implementationAddress
  );

  /**
   * @dev Emitted when a new non-proxied contract address is registered.
   * @param id The identifier of the contract
   * @param oldAddress The address of the old contract
   * @param newAddress The address of the new contract
   */
  event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress);

  /**
   * @dev Emitted when the implementation of the proxy registered with id is updated
   * @param id The identifier of the contract
   * @param proxyAddress The address of the proxy contract
   * @param oldImplementationAddress The address of the old implementation contract
   * @param newImplementationAddress The address of the new implementation contract
   */
  event AddressSetAsProxy(
    bytes32 indexed id,
    address indexed proxyAddress,
    address oldImplementationAddress,
    address indexed newImplementationAddress
  );

  /**
   * @notice Returns the id of the Aave market to which this contract points to.
   * @return The market id
   */
  function getMarketId() external view returns (string memory);

  /**
   * @notice Associates an id with a specific PoolAddressesProvider.
   * @dev This can be used to create an onchain registry of PoolAddressesProviders to
   * identify and validate multiple Aave markets.
   * @param newMarketId The market id
   */
  function setMarketId(string calldata newMarketId) external;

  /**
   * @notice Returns an address by its identifier.
   * @dev The returned address might be an EOA or a contract, potentially proxied
   * @dev It returns ZERO if there is no registered address with the given id
   * @param id The id
   * @return The address of the registered for the specified id
   */
  function getAddress(bytes32 id) external view returns (address);

  /**
   * @notice General function to update the implementation of a proxy registered with
   * certain `id`. If there is no proxy registered, it will instantiate one and
   * set as implementation the `newImplementationAddress`.
   * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit
   * setter function, in order to avoid unexpected consequences
   * @param id The id
   * @param newImplementationAddress The address of the new implementation
   */
  function setAddressAsProxy(bytes32 id, address newImplementationAddress) external;

  /**
   * @notice Sets an address for an id replacing the address saved in the addresses map.
   * @dev IMPORTANT Use this function carefully, as it will do a hard replacement
   * @param id The id
   * @param newAddress The address to set
   */
  function setAddress(bytes32 id, address newAddress) external;

  /**
   * @notice Returns the address of the Pool proxy.
   * @return The Pool proxy address
   */
  function getPool() external view returns (address);

  /**
   * @notice Updates the implementation of the Pool, or creates a proxy
   * setting the new `pool` implementation when the function is called for the first time.
   * @param newPoolImpl The new Pool implementation
   */
  function setPoolImpl(address newPoolImpl) external;

  /**
   * @notice Returns the address of the PoolConfigurator proxy.
   * @return The PoolConfigurator proxy address
   */
  function getPoolConfigurator() external view returns (address);

  /**
   * @notice Updates the implementation of the PoolConfigurator, or creates a proxy
   * setting the new `PoolConfigurator` implementation when the function is called for the first time.
   * @param newPoolConfiguratorImpl The new PoolConfigurator implementation
   */
  function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external;

  /**
   * @notice Returns the address of the price oracle.
   * @return The address of the PriceOracle
   */
  function getPriceOracle() external view returns (address);

  /**
   * @notice Updates the address of the price oracle.
   * @param newPriceOracle The address of the new PriceOracle
   */
  function setPriceOracle(address newPriceOracle) external;

  /**
   * @notice Returns the address of the ACL manager.
   * @return The address of the ACLManager
   */
  function getACLManager() external view returns (address);

  /**
   * @notice Updates the address of the ACL manager.
   * @param newAclManager The address of the new ACLManager
   */
  function setACLManager(address newAclManager) external;

  /**
   * @notice Returns the address of the ACL admin.
   * @return The address of the ACL admin
   */
  function getACLAdmin() external view returns (address);

  /**
   * @notice Updates the address of the ACL admin.
   * @param newAclAdmin The address of the new ACL admin
   */
  function setACLAdmin(address newAclAdmin) external;

  /**
   * @notice Returns the address of the price oracle sentinel.
   * @return The address of the PriceOracleSentinel
   */
  function getPriceOracleSentinel() external view returns (address);

  /**
   * @notice Updates the address of the price oracle sentinel.
   * @param newPriceOracleSentinel The address of the new PriceOracleSentinel
   */
  function setPriceOracleSentinel(address newPriceOracleSentinel) external;

  /**
   * @notice Returns the address of the data provider.
   * @return The address of the DataProvider
   */
  function getPoolDataProvider() external view returns (address);

  /**
   * @notice Updates the address of the data provider.
   * @param newDataProvider The address of the new DataProvider
   */
  function setPoolDataProvider(address newDataProvider) external;
}
DataTypes.sol 265 lines
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

library DataTypes {
  struct ReserveData {
    //stores the reserve configuration
    ReserveConfigurationMap configuration;
    //the liquidity index. Expressed in ray
    uint128 liquidityIndex;
    //the current supply rate. Expressed in ray
    uint128 currentLiquidityRate;
    //variable borrow index. Expressed in ray
    uint128 variableBorrowIndex;
    //the current variable borrow rate. Expressed in ray
    uint128 currentVariableBorrowRate;
    //the current stable borrow rate. Expressed in ray
    uint128 currentStableBorrowRate;
    //timestamp of last update
    uint40 lastUpdateTimestamp;
    //the id of the reserve. Represents the position in the list of the active reserves
    uint16 id;
    //aToken address
    address aTokenAddress;
    //stableDebtToken address
    address stableDebtTokenAddress;
    //variableDebtToken address
    address variableDebtTokenAddress;
    //address of the interest rate strategy
    address interestRateStrategyAddress;
    //the current treasury balance, scaled
    uint128 accruedToTreasury;
    //the outstanding unbacked aTokens minted through the bridging feature
    uint128 unbacked;
    //the outstanding debt borrowed against this asset in isolation mode
    uint128 isolationModeTotalDebt;
  }

  struct ReserveConfigurationMap {
    //bit 0-15: LTV
    //bit 16-31: Liq. threshold
    //bit 32-47: Liq. bonus
    //bit 48-55: Decimals
    //bit 56: reserve is active
    //bit 57: reserve is frozen
    //bit 58: borrowing is enabled
    //bit 59: stable rate borrowing enabled
    //bit 60: asset is paused
    //bit 61: borrowing in isolation mode is enabled
    //bit 62: siloed borrowing enabled
    //bit 63: flashloaning enabled
    //bit 64-79: reserve factor
    //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap
    //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap
    //bit 152-167 liquidation protocol fee
    //bit 168-175 eMode category
    //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
    //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
    //bit 252-255 unused

    uint256 data;
  }

  struct UserConfigurationMap {
    /**
     * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset.
     * The first bit indicates if an asset is used as collateral by the user, the second whether an
     * asset is borrowed by the user.
     */
    uint256 data;
  }

  struct EModeCategory {
    // each eMode category has a custom ltv and liquidation threshold
    uint16 ltv;
    uint16 liquidationThreshold;
    uint16 liquidationBonus;
    // each eMode category may or may not have a custom oracle to override the individual assets price oracles
    address priceSource;
    string label;
  }

  enum InterestRateMode {NONE, STABLE, VARIABLE}

  struct ReserveCache {
    uint256 currScaledVariableDebt;
    uint256 nextScaledVariableDebt;
    uint256 currPrincipalStableDebt;
    uint256 currAvgStableBorrowRate;
    uint256 currTotalStableDebt;
    uint256 nextAvgStableBorrowRate;
    uint256 nextTotalStableDebt;
    uint256 currLiquidityIndex;
    uint256 nextLiquidityIndex;
    uint256 currVariableBorrowIndex;
    uint256 nextVariableBorrowIndex;
    uint256 currLiquidityRate;
    uint256 currVariableBorrowRate;
    uint256 reserveFactor;
    ReserveConfigurationMap reserveConfiguration;
    address aTokenAddress;
    address stableDebtTokenAddress;
    address variableDebtTokenAddress;
    uint40 reserveLastUpdateTimestamp;
    uint40 stableDebtLastUpdateTimestamp;
  }

  struct ExecuteLiquidationCallParams {
    uint256 reservesCount;
    uint256 debtToCover;
    address collateralAsset;
    address debtAsset;
    address user;
    bool receiveAToken;
    address priceOracle;
    uint8 userEModeCategory;
    address priceOracleSentinel;
  }

  struct ExecuteSupplyParams {
    address asset;
    uint256 amount;
    address onBehalfOf;
    uint16 referralCode;
  }

  struct ExecuteBorrowParams {
    address asset;
    address user;
    address onBehalfOf;
    uint256 amount;
    InterestRateMode interestRateMode;
    uint16 referralCode;
    bool releaseUnderlying;
    uint256 maxStableRateBorrowSizePercent;
    uint256 reservesCount;
    address oracle;
    uint8 userEModeCategory;
    address priceOracleSentinel;
  }

  struct ExecuteRepayParams {
    address asset;
    uint256 amount;
    InterestRateMode interestRateMode;
    address onBehalfOf;
    bool useATokens;
  }

  struct ExecuteWithdrawParams {
    address asset;
    uint256 amount;
    address to;
    uint256 reservesCount;
    address oracle;
    uint8 userEModeCategory;
  }

  struct ExecuteSetUserEModeParams {
    uint256 reservesCount;
    address oracle;
    uint8 categoryId;
  }

  struct FinalizeTransferParams {
    address asset;
    address from;
    address to;
    uint256 amount;
    uint256 balanceFromBefore;
    uint256 balanceToBefore;
    uint256 reservesCount;
    address oracle;
    uint8 fromEModeCategory;
  }

  struct FlashloanParams {
    address receiverAddress;
    address[] assets;
    uint256[] amounts;
    uint256[] interestRateModes;
    address onBehalfOf;
    bytes params;
    uint16 referralCode;
    uint256 flashLoanPremiumToProtocol;
    uint256 flashLoanPremiumTotal;
    uint256 maxStableRateBorrowSizePercent;
    uint256 reservesCount;
    address addressesProvider;
    uint8 userEModeCategory;
    bool isAuthorizedFlashBorrower;
  }

  struct FlashloanSimpleParams {
    address receiverAddress;
    address asset;
    uint256 amount;
    bytes params;
    uint16 referralCode;
    uint256 flashLoanPremiumToProtocol;
    uint256 flashLoanPremiumTotal;
  }

  struct FlashLoanRepaymentParams {
    uint256 amount;
    uint256 totalPremium;
    uint256 flashLoanPremiumToProtocol;
    address asset;
    address receiverAddress;
    uint16 referralCode;
  }

  struct CalculateUserAccountDataParams {
    UserConfigurationMap userConfig;
    uint256 reservesCount;
    address user;
    address oracle;
    uint8 userEModeCategory;
  }

  struct ValidateBorrowParams {
    ReserveCache reserveCache;
    UserConfigurationMap userConfig;
    address asset;
    address userAddress;
    uint256 amount;
    InterestRateMode interestRateMode;
    uint256 maxStableLoanPercent;
    uint256 reservesCount;
    address oracle;
    uint8 userEModeCategory;
    address priceOracleSentinel;
    bool isolationModeActive;
    address isolationModeCollateralAddress;
    uint256 isolationModeDebtCeiling;
  }

  struct ValidateLiquidationCallParams {
    ReserveCache debtReserveCache;
    uint256 totalDebt;
    uint256 healthFactor;
    address priceOracleSentinel;
  }

  struct CalculateInterestRatesParams {
    uint256 unbacked;
    uint256 liquidityAdded;
    uint256 liquidityTaken;
    uint256 totalStableDebt;
    uint256 totalVariableDebt;
    uint256 averageStableBorrowRate;
    uint256 reserveFactor;
    address reserve;
    address aToken;
  }

  struct InitReserveParams {
    address asset;
    address aTokenAddress;
    address stableDebtAddress;
    address variableDebtAddress;
    address interestRateStrategyAddress;
    uint16 reservesCount;
    uint16 maxNumberReserves;
  }
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
DegenSmartFees.sol 487 lines
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/// Company: Decrypted Labs
/// @title DegenSmartFees - A contract that interacts with Aave and 1inch to lend, borrow, swap, and repay tokens
/// @author Rabeeb Aqdas
/// @notice This contract allows users to lend assets on Aave, borrow assets, repay debts, and execute swaps using 1inch, while deducting platform fees
/// @dev The contract integrates with Aave's lending pool and the 1inch router, handling both native ETH and ERC20 tokens

import {IPool} from "@aave/core-v3/contracts/interfaces/IPool.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/// @title IERC20 Interface
/// @notice Standard interface for ERC20 token interactions
interface IERC20 {
    /// @notice Transfers tokens to a specified address
    /// @param to The address of the recipient
    /// @param value The amount of tokens to transfer
    function transfer(address to, uint256 value) external;

    /// @notice Approves a spender to transfer tokens on behalf of the owner
    /// @param spender The address authorized to spend the tokens
    /// @param value The amount of tokens to approve
    function approve(address spender, uint256 value) external;

    /// @notice Returns the remaining number of tokens that the spender is allowed to spend
    /// @param owner The address of the token owner
    /// @param spender The address of the spender
    /// @return The remaining allowance for the spender
    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);

    /// @notice Transfers tokens from one address to another
    /// @param from The address from which tokens are transferred
    /// @param to The address to which tokens are transferred
    /// @param value The amount of tokens to transfer
    function transferFrom(address from, address to, uint256 value) external;
}

/// @title IWETHGate Interface
/// @notice Interface for interacting with the WETHGate contract to handle wrapping/unwrapping ETH
interface IWETHGate {
    /// @notice Deposits ETH into the WETHGate contract
    /// @param onBehalfOf The address on whose behalf the deposit is made
    /// @param referralCode A referral code for tracking
    function depositETH(
        address,
        address onBehalfOf,
        uint16 referralCode
    ) external payable;

    /// @notice Withdraws ETH from the WETHGate contract
    /// @param amount The amount of ETH to withdraw
    /// @param to The address to receive the withdrawn ETH
    function withdrawETH(address, uint256 amount, address to) external payable;
}

/// @title IWstETH Interface
/// @notice Interface for wrapping stETH into wstETH
interface IWstETH {
    /// @notice Wraps a specified amount of stETH into wstETH
    /// @param _stETHAmount The amount of stETH to wrap
    /// @return The amount of wstETH received after wrapping
    function wrap(uint256 _stETHAmount) external returns (uint256);
}

/// @notice Thrown when attempting to set a value that is the same as the current value
error DegenWallet__SameAsBefore();

/// @notice Thrown when a value is provided as zero, which is not allowed
error DegenWallet__ValueCantBeZero();

/// @notice Thrown when an ETH or token transfer fails
error DegenWallet__TransferFailed();

/// @notice Thrown when an invalid address (e.g., zero address) is provided
error DegenWallet__InvalidAddress();

/// @notice Thrown when an invalid fee value is provided
error DegenWallet__InvalidFee();

/// @notice Thrown when a transaction fails for any reason
error DegenWallet__TransactionFailed();

contract DegenSmartFees is Ownable {
    ///////////////////////////////////////////State Variables///////////////////////////////////////////////////////////////////

    /// @notice Base value used for percentage calculations
    uint256 private constant BASE = 10000;

    /// @notice Address of the AAVE protocol
    address private constant AAVE = 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2;

    /// @notice Address of the stETH token
    address private constant STETH = 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84;

    /// @notice Address of the wstETH (wrapped stETH) token
    address private constant WSTETH =
        0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0;

    /// @notice Address representing native ETH in this context
    address private constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    /// @notice Address of the WETH (Wrapped Ethereum) token
    address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    /// @notice Address of the WETHGate contract
    address private constant WETHGate =
        0xA434D495249abE33E031Fe71a969B81f3c07950D;

    /// @notice Instance of the AAVE pool as IPool interface
    IPool private _poolHelper = IPool(AAVE);

    /// @notice Instance of WETHGate as IWETHGate interface
    IWETHGate private _wethGateHelper = IWETHGate(WETHGate);

    /// @notice Address of the fee collector wallet
    address private _feeCollector;

    /// @notice Address of the 1inch router used for swaps
    address private _oneInchRouter;

    /// @notice Platform fee rate expressed as a percentage of BASE
    uint256 private _plateFormfee;

    /// @notice Emitted when tokens are lent on the Aave protocol
    /// @param _by The address of the user who lent the tokens
    /// @param _token The address of the token that was lent
    /// @param _amount The amount of the token that was lent
    event TokenLentOnAave(
        address indexed _by,
        address indexed _token,
        uint256 _amount
    );

    /// @notice Emitted when collateral is withdrawn
    /// @param _by The address of the user who withdrew the collateral
    /// @param _token The address of the collateral token that was withdrawn
    /// @param _amount The amount of the token that was withdrawn
    event CollateralWithdrawn(
        address indexed _by,
        address indexed _token,
        uint256 _amount
    );

    /// @notice Emitted when tokens are borrowed from the Aave protocol
    /// @param _by The address of the user who borrowed the tokens
    /// @param _token The address of the token that was borrowed
    /// @param _amount The amount of the token that was borrowed
    event BorrowedOnAave(
        address indexed _by,
        address indexed _token,
        uint256 _amount
    );

    /// @notice Emitted when debt is repaid
    /// @param _by The address of the user who repaid the debt
    /// @param _token The address of the token used to repay the debt
    /// @param _amount The amount of the token that was repaid
    event DebtRepaid(
        address indexed _by,
        address indexed _token,
        uint256 _amount
    );

    /// @notice Emitted when a token swap is executed using 1inch
    /// @param _by The address of the user who performed the swap
    /// @param _token The address of the token that was swapped
    /// @param _amount The amount of the token that was swapped
    event OneInchSwapped(
        address indexed _by,
        address indexed _token,
        uint256 _amount
    );

    /// @notice Emitted when the platform fee is changed
    /// @param _by The address of the user who changed the fee
    /// @param _oldFee The previous fee value
    /// @param _newFee The new fee value
    event PlatformFeeChanged(
        address indexed _by,
        uint256 indexed _oldFee,
        uint256 _newFee
    );

    /// @notice Emitted when the 1inch router address is changed
    /// @param _by The address of the user who changed the router address
    /// @param _oldAddress The previous 1inch router address
    /// @param _newAddress The new 1inch router address
    event OneInchRouterChanged(
        address indexed _by,
        address indexed _oldAddress,
        address indexed _newAddress
    );

    /// @notice Emitted when the fee collector wallet address is changed
    /// @param _by The address of the user who changed the fee wallet address
    /// @param _oldAddress The previous fee wallet address
    /// @param _newAddress The new fee wallet address
    event FeeWalletChanged(
        address indexed _by,
        address indexed _oldAddress,
        address indexed _newAddress
    );

    /// @notice Function to handle incoming ETH transfers to the contract
    receive() external payable {}

    /// @notice Constructor to initialize the contract with platform fee, owner, fee collector, and 1inch router address
    /// @param _fee The initial fee rate for the platform
    /// @param _owner The address of the contract owner
    /// @param _feeWallet The address where collected fees will be sent
    /// @param _oneInchRouterAddr The address of the 1inch router
    constructor(
        uint256 _fee,
        address _owner,
        address _feeWallet,
        address _oneInchRouterAddr
    ) Ownable(_owner) {
        _plateFormfee = _fee;
        _feeCollector = _feeWallet;
        _oneInchRouter = _oneInchRouterAddr;
    }

    ////////////////////////////////////////////Main Functions///////////////////////////////////////////////////////////////////
    /// @notice Lends tokens to the Aave protocol
    /// @dev Can handle both native and ERC20 tokens, and calculates a fee before lending
    /// @param _token The address of the token to be lent (use address(0) for native ETH)
    /// @param _amount The amount of the token to lend (ignored if lending native ETH)
    function lendTokenOnAave(address _token, uint256 _amount) external payable {
        if (_token == address(0)) revert DegenWallet__InvalidAddress();
        address _sender = _msgSender();
        uint256 _amountAfterFee;
        uint256 _fee;
        if (_isNative(_token)) {
            (_amountAfterFee, _fee) = _calculationForFee(msg.value);
            _sendETH(_fee);
            _wethGateHelper.depositETH{value: _amountAfterFee}(
                address(0),
                _sender,
                0
            );
        } else {
            IERC20 _helper = IERC20(_token);
            _helper.transferFrom(_sender, address(this), _amount);
            (_amountAfterFee, _fee) = _calculationForFee(_amount);

            _helper.transfer(_feeCollector, _fee);

            if (_token == STETH) {
                _giveApproval(_token, WSTETH, _amountAfterFee);
                _token = WSTETH;
                _amountAfterFee = IWstETH(WSTETH).wrap(_amountAfterFee);
            }
            _giveApproval(_token, AAVE, _amountAfterFee);

            _poolHelper.supply(_token, _amountAfterFee, _sender, 0);
        }
        emit TokenLentOnAave(_sender, _token, _amountAfterFee);
    }

    /// @notice Withdraws collateral from the Aave protocol
    /// @dev Supports both WETH and other tokens, requires collateral in the Aave protocol
    /// @param _asset The address of the asset to withdraw
    /// @param _amount The amount of the asset to withdraw
    function withdrawCollateral(address _asset, uint256 _amount) external {
        address _sender = _msgSender();
        address _aTokenAddress = _poolHelper
            .getReserveData(_asset)
            .aTokenAddress;
        if (_aTokenAddress == address(0)) revert DegenWallet__InvalidAddress();
        IERC20 _helper = IERC20(_aTokenAddress);
        _helper.transferFrom(_sender, address(this), _amount);
        _giveApproval(
            _aTokenAddress,
            _asset == WETH ? WETHGate : AAVE,
            _amount
        );
        if (_asset == WETH)
            _wethGateHelper.withdrawETH(_asset, _amount, _sender);
        else _poolHelper.withdraw(_asset, _amount, _sender);

        emit CollateralWithdrawn(_sender, _asset, _amount);
    }

    /// @notice Borrows assets from the Aave protocol
    /// @dev Calculates a fee before sending the borrowed amount to the user
    /// @param _asset The address of the asset to borrow
    /// @param _amount The amount of the asset to borrow
    /// @param _interestRateMode The interest rate mode (1 for stable, 2 for variable)
    function borrowOnAave(
        address _asset,
        uint256 _amount,
        uint256 _interestRateMode
    ) external {
        if (_asset == address(0)) revert DegenWallet__InvalidAddress();
        address _sender = _msgSender();

        IERC20 _helper = IERC20(_asset);
        _poolHelper.borrow(_asset, _amount, _interestRateMode, 0, _sender);
        (uint256 _amountAfterFee, uint256 _fee) = _calculationForFee(_amount);
        _helper.transfer(_feeCollector, _fee);
        _helper.transfer(_sender, _amountAfterFee);

        emit BorrowedOnAave(_sender, _asset, _amount);
    }

    /// @notice Repays a debt on the Aave protocol
    /// @dev Calculates and deducts a fee from the repaid amount
    /// @param _asset The address of the asset to repay
    /// @param _interestRateMode The interest rate mode used for the borrowed amount
    /// @param _amount The amount to repay
    function repayDebt(
        address _asset,
        uint256 _interestRateMode,
        uint256 _amount
    ) external payable {
        if (_asset == address(0)) revert DegenWallet__InvalidAddress();
        address _sender = _msgSender();
        IERC20 _helper = IERC20(_asset);
        _helper.transferFrom(_sender, address(this), _amount);

        _giveApproval(_asset, AAVE, _amount);
        uint256 _repaidAmount = _poolHelper.repay(
            _asset,
            _amount,
            _interestRateMode,
            _sender
        );

        (, uint256 _fee) = _calculationForFee(_repaidAmount);

        _helper.transfer(_feeCollector, _fee);

        uint256 _totalAmountUsed = _repaidAmount + _fee;
        if (_amount > _totalAmountUsed)
            _helper.transfer(_sender, (_amount - _totalAmountUsed));

        emit DebtRepaid(_sender, _asset, _repaidAmount);
    }

    /// @notice Executes a token swap using 1inch
    /// @dev Handles both native ETH and ERC20 swaps, deducting a fee before executing the swap
    /// @param _fromToken The address of the token being swapped (use address(0) for ETH)
    /// @param _amount The amount of the token to swap
    /// @param _oneInchDataParam The calldata required by 1inch for the swap
    function oneInchSwap(
        address _fromToken,
        uint256 _amount,
        bytes calldata _oneInchDataParam
    ) external payable {
        address _sender = _msgSender();
        _amount = msg.value > 0 ? msg.value : _amount;
        (uint256 _amountAfterFee, uint256 _fee) = _calculationForFee(_amount);

        if (_isNative(_fromToken)) _sendETH(_fee);
        else {
            IERC20 _helper = IERC20(_fromToken);

            _helper.transferFrom(_sender, address(this), _amount);

            _helper.transfer(_feeCollector, _fee);
            _giveApproval(_fromToken, _oneInchRouter, _amount);
        }
        uint256 amountToBeSent = msg.value > 0 ? _amountAfterFee : 0;
        (bool success, ) = _oneInchRouter.call{value: amountToBeSent}(
            _oneInchDataParam
        );
        if (!success) revert DegenWallet__TransactionFailed();

        emit OneInchSwapped(_sender, _fromToken, _amountAfterFee);
    }

    /// @notice Calculates the fee and the remaining amount after deducting the fee
    /// @dev Private view function to calculate platform fees based on a specified rate
    /// @param _amount The original amount before the fee is applied
    /// @return _amountAfterFee The amount remaining after the fee deduction
    /// @return _fee The calculated fee amount
    function _calculationForFee(
        uint256 _amount
    ) private view returns (uint256 _amountAfterFee, uint256 _fee) {
        if (_amount == 0) revert DegenWallet__ValueCantBeZero();
        _fee = (_amount * _plateFormfee) / BASE;
        _amountAfterFee = _amount - _fee;
    }

    /// @notice Sends ETH to the fee collector address
    /// @dev Private function to transfer ETH, reverts if the transfer fails
    /// @param _amount The amount of ETH to send to the fee collector
    function _sendETH(uint256 _amount) private {
        (bool success, ) = payable(_feeCollector).call{value: _amount}("");
        if (!success) revert DegenWallet__TransferFailed();
    }

    /// @notice Gives approval to spend a specific token amount
    /// @dev  Private function only for contract
    /// @param _token The address of the ERC20 token to approve
    /// @param _to The address to which approval is granted
    /// @param _amount The amount of tokens to approve for spending
    function _giveApproval(
        address _token,
        address _to,
        uint256 _amount
    ) private {
        IERC20 _tokenHelper = IERC20(_token);
        if (_amount > _tokenHelper.allowance(address(this), _to))
            _tokenHelper.approve(_to, type(uint256).max);
    }

    /////////////////////////////////////////Only Owner Functions///////////////////////////////////////////////////////////////////

    /// @notice Change the fee percentage of platform
    /// @dev  Ristrict to only owner of the contract
    /// @param _newPlateFormfee New fee in the form of bips
    function changePlatformFee(uint256 _newPlateFormfee) external onlyOwner {
        if (_newPlateFormfee >= BASE) revert DegenWallet__InvalidFee();
        address _sender = _msgSender();
        uint256 _oldPlateFormfee = _plateFormfee;
        if (_oldPlateFormfee == _newPlateFormfee)
            revert DegenWallet__SameAsBefore();
        _plateFormfee = _newPlateFormfee;
        emit PlatformFeeChanged(_sender, _oldPlateFormfee, _newPlateFormfee);
    }

    /// @notice Changes the 1inch router address
    /// @dev  Can only be called by the contract owner
    /// @param _newRouterAddress The new address for the 1inch router
    function changeOneInchRouter(address _newRouterAddress) external onlyOwner {
        if (_newRouterAddress == address(0))
            revert DegenWallet__InvalidAddress();
        address _sender = _msgSender();
        address _oldRouterAddress = _oneInchRouter;
        if (_oldRouterAddress == _newRouterAddress)
            revert DegenWallet__SameAsBefore();
        _oneInchRouter = _newRouterAddress;
        emit OneInchRouterChanged(
            _sender,
            _oldRouterAddress,
            _newRouterAddress
        );
    }

    /// @notice Changes the fee collector wallet address
    /// @dev Can only be called by the contract owner
    /// @param _newFeeWallet The new address for the fee collector wallet
    function changeFeeWallet(address _newFeeWallet) external onlyOwner {
        if (_newFeeWallet == address(0)) revert DegenWallet__InvalidAddress();
        address _sender = _msgSender();
        address _oldFeeWallet = _feeCollector;
        if (_oldFeeWallet == _newFeeWallet) revert DegenWallet__SameAsBefore();
        _feeCollector = _newFeeWallet;

        emit FeeWalletChanged(_sender, _oldFeeWallet, _newFeeWallet);
    }

    ///////////////////////////////////////////View Functions///////////////////////////////////////////////////////////////////

    /// @notice Tell either the asset is eth or not
    /// @dev  Returns Boolean Value.
    /// @param _token The asset which you want to check
    /// @return bool true if asset is eth
    function _isNative(address _token) private pure returns (bool) {
        return (_token == address(0) || _token == ETH);
    }

    /// @notice Tell the fee of PlateForm
    /// @dev  Returns bips. e.g 69 ==> 0.69%
    /// @return _plateFormfee in bips
    function getPlateFormfee() external view returns (uint256) {
        return _plateFormfee;
    }

    /// @notice Tell the fee wallet address
    /// @dev  Returns wallet address in which fee will send
    /// @return _feeCollector address
    function getFeeWallet() external view returns (address) {
        return _feeCollector;
    }

    /// @notice Provides the 1Inch router contract address
    /// @dev Returns the address of the 1Inch router contract used for swaps
    /// @return _oneInchRouter The address of the 1Inch router
    function getOneInchRouter() external view returns (address) {
        return _oneInchRouter;
    }
}

Read Contract

getFeeWallet 0x5459060d → address
getOneInchRouter 0xb62e3a2b → address
getPlateFormfee 0x02d2f0a8 → uint256
owner 0x8da5cb5b → address

Write Contract 10 functions

These functions modify contract state and require a wallet transaction to execute.

borrowOnAave 0x487c5f86
address _asset
uint256 _amount
uint256 _interestRateMode
changeFeeWallet 0x3e4d0310
address _newFeeWallet
changeOneInchRouter 0x82529ab2
address _newRouterAddress
changePlatformFee 0xd7a5791a
uint256 _newPlateFormfee
lendTokenOnAave 0x6fefa7e6
address _token
uint256 _amount
oneInchSwap 0xa03017ec
address _fromToken
uint256 _amount
bytes _oneInchDataParam
renounceOwnership 0x715018a6
No parameters
repayDebt 0x39a72574
address _asset
uint256 _interestRateMode
uint256 _amount
transferOwnership 0xf2fde38b
address newOwner
withdrawCollateral 0x350c35e9
address _asset
uint256 _amount

Recent Transactions

No transactions found for this address