Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 424711646 | 40 hrs ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Minimal Proxy Contract for 0xac27f3f86e78b14721d07c4f9ce999285f9aaa06
Contract Name:
RepayWithCollateralAaveV3Adapter
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 999999 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
// Copyright (c) 2025 Aave Labs
pragma solidity 0.8.28;
import {AaveV3BaseAdapter} from 'src/contracts/AaveV3BaseAdapter.sol';
import {
IRepayWithCollateralAaveV3Adapter,
DataTypes
} from 'src/interfaces/IRepayWithCollateralAaveV3Adapter.sol';
/// @notice CowSwap Adapter Hook for Aave V3 - Action : Repay Debt With Collateral With Flash Loan.
/// @author Aave Labs.
contract RepayWithCollateralAaveV3Adapter is AaveV3BaseAdapter, IRepayWithCollateralAaveV3Adapter {
constructor(
address factory_,
address aavePool_,
address settlement_
) AaveV3BaseAdapter(factory_, aavePool_, settlement_) {}
/// @inheritdoc IRepayWithCollateralAaveV3Adapter
/// @dev For RepayWithCollateral : hookSellTokenAmount => amount to withdraw && hookBuyTokenAmount => amount to repay
function repayDebtWithFlashLoan(DataTypes.Permit calldata erc20Permit) external checkExpiry {
// Repay the debt with the received outcome of the swap
_repay({
asset: _buyToken,
user: owner,
repayAmount: _hookBuyTokenAmount,
orderAmount: _buyAmount
});
// Withdraw the asset to repay the flashloan (and more if specified)
_withdraw({
asset: _sellToken,
user: owner,
withdrawAmount: _hookSellTokenAmount,
orderAmount: _sellAmount,
receiver: address(this),
erc20Permit: erc20Permit
});
// Notify to start the FlashLoan repay process on the Factory
// and sweep any leftovers in this contract
uint256 totalFlashLoanAmount = _flashLoanAmount + _flashLoanFeeAmount;
_repayFlashLoan(_sellToken, totalFlashLoanAmount);
_sweepDust(_sellToken);
_sweepDust(_buyToken);
}
}// SPDX-License-Identifier: UNLICENSED
// Copyright (c) 2025 Aave Labs
pragma solidity 0.8.28;
import {IERC20} from 'openzeppelin/token/ERC20/IERC20.sol';
import {SafeERC20} from 'openzeppelin/token/ERC20/utils/SafeERC20.sol';
import {ICreditDelegationToken} from 'aave-v3-origin/contracts/interfaces/ICreditDelegationToken.sol';
import {IERC20WithPermit} from 'aave-v3-origin/contracts/interfaces/IERC20WithPermit.sol';
import {IPool} from 'aave-v3-origin/contracts/interfaces/IPool.sol';
import {GPv2Order} from 'cowprotocol/contracts/libraries/GPv2Order.sol';
import {ISettlement} from 'src/interfaces/ISettlement.sol';
import {DataTypes} from 'src/libraries/DataTypes.sol';
import {IAaveBaseAdapter} from 'src/interfaces/IAaveBaseAdapter.sol';
import {IBaseAdapterFactory} from 'src/interfaces/IBaseAdapterFactory.sol';
/// @notice Base for AdapterHooks with all the interactions with the Aave V3 Pool and the Adapter Factory contracts.
/// @author Aave Labs.
contract AaveV3BaseAdapter is IAaveBaseAdapter {
using SafeERC20 for IERC20;
using GPv2Order for GPv2Order.Data;
/// @dev Rate mode for variable rate borrowings.
uint256 private constant BORROW_VARIABLE_RATE = 2;
/// @dev Referral code to pass to the Aave Pool.
uint16 private constant REFERRAL_CODE = 4300;
address public immutable FACTORY;
address public immutable AAVE_POOL;
address public immutable SETTLEMENT_CONTRACT;
bool private initialized;
/// @notice Owner of the AdapterHook Instance (the user signing the Order).
address public owner;
// DataTypes.HookOrderData struct
address internal transient _sellToken;
address internal transient _buyToken;
uint256 internal transient _sellAmount;
uint256 internal transient _buyAmount;
bytes32 internal transient _kind;
uint256 internal transient _validTo;
uint256 internal transient _flashLoanAmount;
uint256 internal transient _flashLoanFeeAmount;
uint256 internal transient _hookSellTokenAmount;
uint256 internal transient _hookBuyTokenAmount;
/// @notice Only the Instance owner can call.
modifier onlyInstanceOwner() {
require(msg.sender == owner, CallerNotInstanceOwner());
_;
}
/// @notice Check that the Order for the Instance is still valid.
modifier checkExpiry() {
require(block.timestamp <= _validTo, OrderExpired());
_;
}
/// @dev Constructor.
/// @param factory_ The address of the AaveV3AdapterFactory contract.
/// @param aavePool_ The address of the Aave V3 Pool contract.
/// @param settlement_ The address of the Cow Settlement contract.
constructor(address factory_, address aavePool_, address settlement_) {
require(
factory_ != address(0) && aavePool_ != address(0) && settlement_ != address(0),
InvalidZeroAddress()
);
FACTORY = factory_;
AAVE_POOL = aavePool_;
SETTLEMENT_CONTRACT = settlement_;
initialized = true;
}
/// @inheritdoc IAaveBaseAdapter
function setParameters(DataTypes.HookOrderData calldata hookData_) external {
require(!initialized, AlreadyInitialized());
initialized = true;
owner = hookData_.owner;
// Store the Order data in the transient storage for this deployment
_sellToken = hookData_.sellToken;
_buyToken = hookData_.buyToken;
_sellAmount = hookData_.sellAmount;
_buyAmount = hookData_.buyAmount;
_kind = hookData_.kind;
_validTo = hookData_.validTo;
_flashLoanAmount = hookData_.flashLoanAmount;
_flashLoanFeeAmount = hookData_.flashLoanFeeAmount;
_hookSellTokenAmount = hookData_.hookSellTokenAmount;
_hookBuyTokenAmount = hookData_.hookBuyTokenAmount;
// Check the postHook amounts
// and make sure they allow to cover the total amount to repay the FlashLoan
require(
hookData_.flashLoanAmount > 0 &&
hookData_.hookBuyTokenAmount > 0 &&
hookData_.hookSellTokenAmount > 0,
InvalidZeroAmount()
);
if (hookData_.sellAmount == hookData_.flashLoanAmount) {
// If we sell the full flashloan amount, we need to withdraw/borrow at least the flashloan amount + fee amount
// to return the correct funds to the Factory
require(
hookData_.hookSellTokenAmount >= (hookData_.flashLoanAmount + hookData_.flashLoanFeeAmount),
InvalidHookSellAmount()
);
} else if (hookData_.sellAmount == hookData_.flashLoanAmount - hookData_.flashLoanFeeAmount) {
// If we do not sell the full flashloan amount, we want to keep the required fee amount before the swap
// and only withdraw/borrow the flashloan amount to return the correct funds to the Factory
require(hookData_.hookSellTokenAmount >= hookData_.flashLoanAmount, InvalidHookSellAmount());
} else {
revert InvalidHookSellAmount();
}
// Give the allowance to pull the Flashloaned assets for the swap
IERC20(hookData_.sellToken).forceApprove(
ISettlement(SETTLEMENT_CONTRACT).vaultRelayer(),
hookData_.sellAmount
);
}
/// @notice Rescue any ERC20 tokens left on the contract.
/// @dev Emergency rescue for token stucked on this contract, as failsafe mechanism.
/// @dev Funds should never remain in this contract more time than during transactions.
/// @dev Only callable by the owner.
function rescueTokens(IERC20 token) external onlyInstanceOwner {
token.safeTransfer(owner, token.balanceOf(address(this)));
}
/// @inheritdoc IAaveBaseAdapter
function getHookData() external view returns (DataTypes.HookOrderData memory) {
return _getHookData();
}
/// @notice Checks that the given Order signature matches the Order used to deploy this contract.
/// @param _orderHash The hash of the Order to check.
/// @param _signature The signature to verify.
function isValidSignature(
bytes32 _orderHash,
bytes calldata _signature
) external view returns (bytes4) {
(GPv2Order.Data memory _order, bytes memory _userSignature) = abi.decode(
_signature,
(GPv2Order.Data, bytes)
);
require(
IBaseAdapterFactory(FACTORY).verifyOrderSignature(owner, _order, _userSignature),
InvalidOrderSignature()
);
bytes32 _rebuiltOrderHash = _order.hash(ISettlement(SETTLEMENT_CONTRACT).domainSeparator());
require(_orderHash == _rebuiltOrderHash, OrderHashMismatch());
require(_order.validTo == _validTo, InvalidOrderExpiry());
require(block.timestamp <= _order.validTo, OrderExpired());
require(_order.receiver == address(this), InvalidOrderReceiver());
require(_order.kind == _kind, InvalidOrderKind());
require(!_order.partiallyFillable, OrderPartiallyFillable());
require(address(_order.sellToken) == address(_sellToken), InvalidSellToken());
require(address(_order.buyToken) == address(_buyToken), InvalidBuyToken());
require(_order.sellAmount == _sellAmount, InvalidSellAmount());
require(_order.buyAmount == _buyAmount, InvalidBuyAmount());
require(_order.feeAmount == 0, OrderFeeNotNull());
require(_order.sellTokenBalance == GPv2Order.BALANCE_ERC20, InvalidOrderTokenBalancer());
require(_order.buyTokenBalance == GPv2Order.BALANCE_ERC20, InvalidOrderTokenBalancer());
return this.isValidSignature.selector;
}
/// @dev Executes the Credit Delegation via signature for the debt asset.
/// @param aavePool The Aave Pool contract.
/// @param asset The asset to borrow.
/// @param user The user to borrow from.
/// @param creditDelegationSig The credit delegation signature signed data.
function _tryCreditDelegationWithSig(
IPool aavePool,
address asset,
address user,
DataTypes.CreditDelegationSig calldata creditDelegationSig
) internal {
try
ICreditDelegationToken(_getVariableDebtToken(aavePool, asset)).delegationWithSig(
user,
address(this),
creditDelegationSig.amount,
creditDelegationSig.deadline,
creditDelegationSig.v,
creditDelegationSig.r,
creditDelegationSig.s
)
{} catch {}
}
/// @dev Supplies assets to the pool on behalf of a given user.
/// @param asset The asset to supply.
/// @param receiver The address receiving the supply.
/// @param supplyAmount The amount to supply.
/// @param orderAmount The amount passed in the Order.
function _supply(
address asset,
address receiver,
uint256 supplyAmount,
uint256 orderAmount
) internal {
IPool aavePool = IPool(AAVE_POOL);
// Check that this contract received the correct amount of assets
uint256 currentBalance = _getCurrentBalance(asset, address(this));
require(currentBalance >= orderAmount, InvalidBalance());
// And supply the full balance, including any excess over the order amount, to avoid any leftover
if (currentBalance > supplyAmount) {
supplyAmount = currentBalance;
}
// Deposit on behalf of the receiver
IERC20(asset).forceApprove(address(aavePool), supplyAmount);
aavePool.supply(asset, supplyAmount, receiver, REFERRAL_CODE);
}
/// @dev Withdraws assets pulled from a specified user.
/// @param asset The asset to withdraw.
/// @param user The user to withdraw from.
/// @param withdrawAmount The amount to withdraw.
/// @param orderAmount The amount passed in the Order.
/// @param receiver The address receiving the withdrawn assets.
/// @param erc20Permit The permit data for the aToken transfer, if needed.
function _withdraw(
address asset,
address user,
uint256 withdrawAmount,
uint256 orderAmount,
address receiver,
DataTypes.Permit calldata erc20Permit
) internal {
IPool aavePool = IPool(AAVE_POOL);
address aToken = _getAToken(aavePool, asset);
uint256 withdrawable = IERC20(aToken).balanceOf(user);
// If the given amount is meant for a max withdraw
if (withdrawAmount > withdrawable) {
withdrawAmount = withdrawable;
}
require(orderAmount <= withdrawAmount, InvalidAmount());
// Execute the permit if needed.
if (erc20Permit.deadline != 0) {
try
IERC20WithPermit(aToken).permit(
user,
address(this),
erc20Permit.amount,
erc20Permit.deadline,
erc20Permit.v,
erc20Permit.r,
erc20Permit.s
)
{} catch {}
}
// Pull the aToken from the user in this contract.
IERC20(aToken).safeTransferFrom(user, address(this), withdrawAmount);
// Withdraw the aToken to receive the asset.
uint256 received = aavePool.withdraw(asset, withdrawAmount, receiver);
require(received == withdrawAmount, InvalidWithdraw());
}
/// @dev Borrows assets using the given user credit delegation.
/// @param asset The asset to borrow.
/// @param user The user to borrow from.
/// @param borrowAmount The amount to borrow.
/// @param orderAmount The amount passed in the Order.
/// @param receiver The address receiving the borrowed assets.
/// @param creditDelegationSig The credit delegation signature data, if needed.
function _borrow(
address asset,
address user,
uint256 borrowAmount,
uint256 orderAmount,
address receiver,
DataTypes.CreditDelegationSig calldata creditDelegationSig
) internal {
IPool aavePool = IPool(AAVE_POOL);
require(orderAmount <= borrowAmount, InvalidAmount());
// Execute the Credit Delegation if needed.
if (creditDelegationSig.deadline != 0) {
_tryCreditDelegationWithSig(aavePool, asset, user, creditDelegationSig);
}
uint256 initialBalance = IERC20(asset).balanceOf(address(this));
// Borrow on the user position, to receive the asset in this contract.
aavePool.borrow(asset, borrowAmount, BORROW_VARIABLE_RATE, REFERRAL_CODE, user);
uint256 received = _getCurrentBalance(asset, address(this)) - initialBalance;
require(received == borrowAmount, InvalidBorrow());
// Send the borrowed assets to the specified receiver.
IERC20(asset).safeTransfer(receiver, received);
}
/// @dev Repay the asset debt for a given user.
/// @param asset The asset to repay.
/// @param user The user to repay for.
/// @param repayAmount The amount to repay.
/// @param orderAmount The amount passed as output in the Order.
function _repay(address asset, address user, uint256 repayAmount, uint256 orderAmount) internal {
IPool aavePool = IPool(AAVE_POOL);
// Check that this contract recevied the correct amount of assets and has enough
// to supply the specified amount.
uint256 currentBalance = _getCurrentBalance(asset, address(this));
uint256 currentDebt = _getCurrentDebt(aavePool, asset, user);
require(currentBalance >= orderAmount, InvalidBalance());
// If the specified amount is higher than the balance, only repay up to the current balance.
if (repayAmount > currentBalance) {
repayAmount = currentBalance;
}
// If the specified amount is higher than the current debt, only repay the current debt.
if (repayAmount > currentDebt) {
repayAmount = currentDebt;
}
// Repay the debt on behalf of the specified user.
IERC20(asset).forceApprove(address(aavePool), repayAmount);
aavePool.repay(asset, repayAmount, BORROW_VARIABLE_RATE, user);
}
/// @dev Starts the flash loan repayment process by notifying the AaveV3AdapterFactory and setting the allowance for the asset to be pulled.
function _repayFlashLoan(address asset, uint256 amount) internal {
IERC20(asset).forceApprove(FACTORY, amount);
IBaseAdapterFactory(FACTORY).notifyRepayFlashLoan();
}
/// @dev Sweeps any leftover of the asset in the contract.
function _sweepDust(address asset) internal {
uint256 balance = IERC20(asset).balanceOf(address(this));
if (balance > 0) {
IERC20(asset).safeTransfer(owner, balance);
}
}
function _getHookData() internal view returns (DataTypes.HookOrderData memory data) {
return
DataTypes.HookOrderData({
owner: owner,
receiver: address(this),
sellToken: _sellToken,
buyToken: _buyToken,
sellAmount: _sellAmount,
buyAmount: _buyAmount,
kind: _kind,
validTo: _validTo,
flashLoanAmount: _flashLoanAmount,
flashLoanFeeAmount: _flashLoanFeeAmount,
hookSellTokenAmount: _hookSellTokenAmount,
hookBuyTokenAmount: _hookBuyTokenAmount
});
}
/// @dev Returns the aToken for a given asset.
function _getAToken(IPool aavePool, address asset) internal view returns (address) {
return aavePool.getReserveAToken(asset);
}
/// @dev Returns the debt token for a given asset.
function _getVariableDebtToken(IPool aavePool, address asset) internal view returns (address) {
return aavePool.getReserveVariableDebtToken(asset);
}
/// @dev Returns the current balance of a given address for a given asset.
function _getCurrentBalance(address asset, address user) internal view returns (uint256) {
return IERC20(asset).balanceOf(user);
}
/// @dev Returns the current debt balance of a given address for a given asset.
function _getCurrentDebt(
IPool aavePool,
address asset,
address user
) internal view returns (uint256) {
return IERC20(_getVariableDebtToken(aavePool, asset)).balanceOf(user);
}
}// SPDX-License-Identifier: UNLICENSED
// Copyright (c) 2025 Aave Labs
pragma solidity ^0.8.0;
import {DataTypes} from 'src/libraries/DataTypes.sol';
import {IAaveBaseAdapter} from 'src/interfaces/IAaveBaseAdapter.sol';
/// @notice Interface for the RepayWithCollateralAaveV3Adapter.
/// @author Aave Labs.
interface IRepayWithCollateralAaveV3Adapter is IAaveBaseAdapter {
/// @notice PostHook to repay user debt with its collateral.
/// @dev Uses a flashloan & swap to repay the user debt and withdraw the user's collateral to repay the Flashloan.
/// @param erc20Permit The permit data for the aToken to pull and withdraw.
function repayDebtWithFlashLoan(DataTypes.Permit calldata erc20Permit) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title ICreditDelegationToken
* @author Aave
* @notice Defines the basic interface for a token supporting credit delegation.
*/
interface ICreditDelegationToken {
/**
* @dev Emitted on `approveDelegation` and `borrowAllowance
* @param fromUser The address of the delegator
* @param toUser The address of the delegatee
* @param asset The address of the delegated asset
* @param amount The amount being delegated
*/
event BorrowAllowanceDelegated(
address indexed fromUser,
address indexed toUser,
address indexed asset,
uint256 amount
);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in borrowing.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error InsufficientBorrowAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @notice Delegates borrowing power to a user on the specific debt token.
* Delegation will still respect the liquidation constraints (even if delegated, a
* delegatee cannot force a delegator HF to go below 1)
* @param delegatee The address receiving the delegated borrowing power
* @param amount The maximum amount being delegated.
*/
function approveDelegation(address delegatee, uint256 amount) external;
/**
* @notice Returns the borrow allowance of the user
* @param fromUser The user to giving allowance
* @param toUser The user to give allowance to
* @return The current allowance of `toUser`
*/
function borrowAllowance(address fromUser, address toUser) external view returns (uint256);
/**
* @notice Delegates borrowing power to a user on the specific debt token via ERC712 signature
* @param delegator The delegator of the credit
* @param delegatee The delegatee that can use the credit
* @param value The amount to be delegated
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v The V signature param
* @param s The S signature param
* @param r The R signature param
*/
function delegationWithSig(
address delegator,
address delegatee,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
/**
* @title IERC20WithPermit
* @author Aave
* @notice Interface for the permit function (EIP-2612)
*/
interface IERC20WithPermit is IERC20 {
/**
* @notice Allow passing a signed message to approve spending
* @dev implements the permit function as for
* https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md
* @param owner The owner of the funds
* @param spender The spender
* @param value The amount
* @param deadline The deadline timestamp, type(uint256).max for max deadline
* @param v Signature param
* @param s Signature param
* @param r Signature param
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
}// SPDX-License-Identifier: MIT
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 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: 2 for Variable, 1 is deprecated (changed on v3.2.0)
* @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 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 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 (Deprecated on v3.2.0), 2 for Variable
* @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 @note deprecated on v3.2.0
* @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 deficit of a reserve is covered.
* @param reserve The address of the underlying asset of the reserve
* @param caller The caller that triggered the DeficitCovered event
* @param amountCovered The amount of deficit covered
*/
event DeficitCovered(address indexed reserve, address caller, uint256 amountCovered);
/**
* @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);
/**
* @dev Emitted when deficit is realized on a liquidation.
* @param user The user address where the bad debt will be burned
* @param debtAsset The address of the underlying borrowed asset to be burned
* @param amountCreated The amount of deficit created
*/
event DeficitCreated(address indexed user, address indexed debtAsset, uint256 amountCreated);
/**
* @dev Emitted when a position manager is approved by the user.
* @param user The user address
* @param positionManager The address of the position manager
*/
event PositionManagerApproved(address indexed user, address indexed positionManager);
/**
* @dev Emitted when a position manager is revoked by the user.
* @param user The user address
* @param positionManager The address of the position manager
*/
event PositionManagerRevoked(address indexed user, address indexed positionManager);
/**
* @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 VariableDebtToken
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* and 100 variable debt tokens
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode 2 for Variable, 1 is deprecated on v3.2.0
* @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 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 2 for Variable, 1 is deprecated on v3.2.0
* @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 2 for Variable, 1 is deprecated on v3.2.0
* @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 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 DEPRECATED in v3.2.0
* @return The final amount repaid
*/
function repayWithATokens(
address asset,
uint256 amount,
uint256 interestRateMode
) external returns (uint256);
/**
* @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 borrower 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 borrower,
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 -> Deprecated on v3.2.0
* 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 2 on `modes`
* @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
* @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 variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve
*/
function initReserve(address asset, address aTokenAddress, address variableDebtAddress) external;
/**
* @notice Drop a reserve
* @dev Only callable by the PoolConfigurator contract
* @dev Does not reset eMode flags, which must be considered when reusing the same reserve id for a different reserve.
* @param asset The address of the underlying asset of the reserve
*/
function dropReserve(address asset) external;
/**
* @notice Accumulates interest to all indexes of the reserve
* @dev Only callable by the PoolConfigurator contract
* @dev To be used when required by the configurator, for example when updating interest rates strategy data
* @param asset The address of the underlying asset of the reserve
*/
function syncIndexesState(address asset) external;
/**
* @notice Updates interest rates on the reserve data
* @dev Only callable by the PoolConfigurator contract
* @dev To be used when required by the configurator, for example when updating interest rates strategy data
* @param asset The address of the underlying asset of the reserve
*/
function syncRatesState(address asset) 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.ReserveDataLegacy memory);
/**
* @notice Returns the virtual underlying balance of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve virtual underlying balance
*/
function getVirtualUnderlyingBalance(address asset) external view returns (uint128);
/**
* @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 scaledAmount The scaled amount being transferred/withdrawn
* @param scaledBalanceFromBefore The aToken scaled balance of the `from` user before the transfer
* @param scaledBalanceToBefore The aToken scaled balance of the `to` user before the transfer
*/
function finalizeTransfer(
address asset,
address from,
address to,
uint256 scaledAmount,
uint256 scaledBalanceFromBefore,
uint256 scaledBalanceToBefore
) 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 number of initialized reserves
* @dev It includes dropped reserves
* @return The count
*/
function getReservesCount() external view returns (uint256);
/**
* @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 Returns the ReserveInterestRateStrategy connected to all the reserves
* @return The address of the ReserveInterestRateStrategy contract
*/
function RESERVE_INTEREST_RATE_STRATEGY() external view returns (address);
/**
* @notice Updates flash loan premium. All this premium is collected by the protocol treasury.
* @dev The premium is calculated on the total borrowed amount
* @dev Only callable by the PoolConfigurator contract
* @param flashLoanPremium The flash loan premium, expressed in bps
*/
function updateFlashloanPremium(uint128 flashLoanPremium) external;
/**
* @notice Configures a new or alters an existing collateral configuration of an 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.EModeCategoryBaseConfiguration memory config
) external;
/**
* @notice Replaces the current eMode collateralBitmap.
* @param id The id of the category
* @param collateralBitmap The collateralBitmap of the category
*/
function configureEModeCategoryCollateralBitmap(uint8 id, uint128 collateralBitmap) external;
/**
* @notice Replaces the current eMode borrowableBitmap.
* @param id The id of the category
* @param borrowableBitmap The borrowableBitmap of the category
*/
function configureEModeCategoryBorrowableBitmap(uint8 id, uint128 borrowableBitmap) external;
/**
* @notice Returns the data of an eMode category
* @dev DEPRECATED use independent getters instead
* @param id The id of the category
* @return The configuration data of the category
*/
function getEModeCategoryData(
uint8 id
) external view returns (DataTypes.EModeCategoryLegacy memory);
/**
* @notice Returns the label of an eMode category
* @param id The id of the category
* @return The label of the category
*/
function getEModeCategoryLabel(uint8 id) external view returns (string memory);
/**
* @notice Returns the collateral config of an eMode category
* @param id The id of the category
* @return The ltv,lt,lb of the category
*/
function getEModeCategoryCollateralConfig(
uint8 id
) external view returns (DataTypes.CollateralConfig memory);
/**
* @notice Returns the collateralBitmap of an eMode category
* @param id The id of the category
* @return The collateralBitmap of the category
*/
function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128);
/**
* @notice Returns the borrowableBitmap of an eMode category
* @param id The id of the category
* @return The borrowableBitmap of the category
*/
function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128);
/**
* @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 Sets the liquidation grace period of the given asset
* @dev To enable a liquidation grace period, a timestamp in the future should be set,
* To disable a liquidation grace period, any timestamp in the past works, like 0
* @param asset The address of the underlying asset to set the liquidationGracePeriod
* @param until Timestamp when the liquidation grace period will end
**/
function setLiquidationGracePeriod(address asset, uint40 until) external;
/**
* @notice Returns the liquidation grace period of the given asset
* @param asset The address of the underlying asset
* @return Timestamp when the liquidation grace period will end
**/
function getLiquidationGracePeriod(address asset) external view returns (uint40);
/**
* @notice Returns the total fee on flash loans.
* @dev From v3.4 all flashloan fees will be send to the treasury.
* @return The total fee on flashloans
*/
function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);
/**
* @notice Returns the part of the flashloan fees sent to protocol
* @dev From v3.4 all flashloan fees will be send to the treasury and this value
* is always 100_00.
* @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;
/**
* @notice It covers the deficit of a specified reserve by burning the equivalent aToken `amount` for assets
* @dev The deficit of a reserve can occur due to situations where borrowed assets are not repaid, leading to bad debt.
* @param asset The address of the underlying asset to cover the deficit.
* @param amount The amount to be covered, in aToken
* @return The amount of tokens burned
*/
function eliminateReserveDeficit(address asset, uint256 amount) external returns (uint256);
/**
* @notice Approves or disapproves a position manager. This position manager will be able
* to call the `setUserUseReserveAsCollateralOnBehalfOf` and the
* `setUserEModeOnBehalfOf` function on behalf of the user.
* @param positionManager The address of the position manager
* @param approve True if the position manager should be approved, false otherwise
*/
function approvePositionManager(address positionManager, bool approve) external;
/**
* @notice Renounces a position manager role for a given user.
* @param user The address of the user
*/
function renouncePositionManagerRole(address user) external;
/**
* @notice Sets the use as collateral flag for the user on the specific reserve on behalf of the user.
* @param asset The address of the underlying asset of the reserve
* @param useAsCollateral True if the user wants to use the reserve as collateral, false otherwise
* @param onBehalfOf The address of the user
*/
function setUserUseReserveAsCollateralOnBehalfOf(
address asset,
bool useAsCollateral,
address onBehalfOf
) external;
/**
* @notice Sets the eMode category for the user on the specific reserve on behalf of the user.
* @param categoryId The id of the category
* @param onBehalfOf The address of the user
*/
function setUserEModeOnBehalfOf(uint8 categoryId, address onBehalfOf) external;
/*
* @notice Returns true if the `positionManager` address is approved to use the position manager role on behalf of the user.
* @param user The address of the user
* @param positionManager The address of the position manager
* @return True if the user is approved to use the position manager, false otherwise
*/
function isApprovedPositionManager(
address user,
address positionManager
) external view returns (bool);
/**
* @notice Returns the current deficit of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The current deficit of the reserve
*/
function getReserveDeficit(address asset) external view returns (uint256);
/**
* @notice Returns the aToken address of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The address of the aToken
*/
function getReserveAToken(address asset) external view returns (address);
/**
* @notice Returns the variableDebtToken address of a reserve.
* @param asset The address of the underlying asset of the reserve
* @return The address of the variableDebtToken
*/
function getReserveVariableDebtToken(address asset) external view returns (address);
/**
* @notice Gets the address of the external FlashLoanLogic
*/
function getFlashLoanLogic() external view returns (address);
/**
* @notice Gets the address of the external BorrowLogic
*/
function getBorrowLogic() external view returns (address);
/**
* @notice Gets the address of the external EModeLogic
*/
function getEModeLogic() external view returns (address);
/**
* @notice Gets the address of the external LiquidationLogic
*/
function getLiquidationLogic() external view returns (address);
/**
* @notice Gets the address of the external PoolLogic
*/
function getPoolLogic() external view returns (address);
/**
* @notice Gets the address of the external SupplyLogic
*/
function getSupplyLogic() external view returns (address);
}// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;
import "../interfaces/IERC20.sol";
/// @title Gnosis Protocol v2 Order Library
/// @author Gnosis Developers
library GPv2Order {
/// @dev The complete data for a Gnosis Protocol order. This struct contains
/// all order parameters that are signed for submitting to GP.
struct Data {
IERC20 sellToken;
IERC20 buyToken;
address receiver;
uint256 sellAmount;
uint256 buyAmount;
uint32 validTo;
bytes32 appData;
uint256 feeAmount;
bytes32 kind;
bool partiallyFillable;
bytes32 sellTokenBalance;
bytes32 buyTokenBalance;
}
/// @dev The order EIP-712 type hash for the [`GPv2Order.Data`] struct.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256(
/// "Order(" +
/// "address sellToken," +
/// "address buyToken," +
/// "address receiver," +
/// "uint256 sellAmount," +
/// "uint256 buyAmount," +
/// "uint32 validTo," +
/// "bytes32 appData," +
/// "uint256 feeAmount," +
/// "string kind," +
/// "bool partiallyFillable," +
/// "string sellTokenBalance," +
/// "string buyTokenBalance" +
/// ")"
/// )
/// ```
bytes32 internal constant TYPE_HASH =
hex"d5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e489";
/// @dev The marker value for a sell order for computing the order struct
/// hash. This allows the EIP-712 compatible wallets to display a
/// descriptive string for the order kind (instead of 0 or 1).
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("sell")
/// ```
bytes32 internal constant KIND_SELL =
hex"f3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee346775";
/// @dev The OrderKind marker value for a buy order for computing the order
/// struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("buy")
/// ```
bytes32 internal constant KIND_BUY =
hex"6ed88e868af0a1983e3886d5f3e95a2fafbd6c3450bc229e27342283dc429ccc";
/// @dev The TokenBalance marker value for using direct ERC20 balances for
/// computing the order struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("erc20")
/// ```
bytes32 internal constant BALANCE_ERC20 =
hex"5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9";
/// @dev The TokenBalance marker value for using Balancer Vault external
/// balances (in order to re-use Vault ERC20 approvals) for computing the
/// order struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("external")
/// ```
bytes32 internal constant BALANCE_EXTERNAL =
hex"abee3b73373acd583a130924aad6dc38cfdc44ba0555ba94ce2ff63980ea0632";
/// @dev The TokenBalance marker value for using Balancer Vault internal
/// balances for computing the order struct hash.
///
/// This value is pre-computed from the following expression:
/// ```
/// keccak256("internal")
/// ```
bytes32 internal constant BALANCE_INTERNAL =
hex"4ac99ace14ee0a5ef932dc609df0943ab7ac16b7583634612f8dc35a4289a6ce";
/// @dev Marker address used to indicate that the receiver of the trade
/// proceeds should the owner of the order.
///
/// This is chosen to be `address(0)` for gas efficiency as it is expected
/// to be the most common case.
address internal constant RECEIVER_SAME_AS_OWNER = address(0);
/// @dev The byte length of an order unique identifier.
uint256 internal constant UID_LENGTH = 56;
/// @dev Returns the actual receiver for an order. This function checks
/// whether or not the [`receiver`] field uses the marker value to indicate
/// it is the same as the order owner.
///
/// @return receiver The actual receiver of trade proceeds.
function actualReceiver(
Data memory order,
address owner
) internal pure returns (address receiver) {
if (order.receiver == RECEIVER_SAME_AS_OWNER) {
receiver = owner;
} else {
receiver = order.receiver;
}
}
/// @dev Return the EIP-712 signing hash for the specified order.
///
/// @param order The order to compute the EIP-712 signing hash for.
/// @param domainSeparator The EIP-712 domain separator to use.
/// @return orderDigest The 32 byte EIP-712 struct hash.
function hash(
Data memory order,
bytes32 domainSeparator
) internal pure returns (bytes32 orderDigest) {
bytes32 structHash;
// NOTE: Compute the EIP-712 order struct hash in place. As suggested
// in the EIP proposal, noting that the order struct has 12 fields, and
// prefixing the type hash `(1 + 12) * 32 = 416` bytes to hash.
// <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#rationale-for-encodedata>
// solhint-disable-next-line no-inline-assembly
assembly {
let dataStart := sub(order, 32)
let temp := mload(dataStart)
mstore(dataStart, TYPE_HASH)
structHash := keccak256(dataStart, 416)
mstore(dataStart, temp)
}
// NOTE: Now that we have the struct hash, compute the EIP-712 signing
// hash using scratch memory past the free memory pointer. The signing
// hash is computed from `"\x19\x01" || domainSeparator || structHash`.
// <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory>
// <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification>
// solhint-disable-next-line no-inline-assembly
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, "\x19\x01")
mstore(add(freeMemoryPointer, 2), domainSeparator)
mstore(add(freeMemoryPointer, 34), structHash)
orderDigest := keccak256(freeMemoryPointer, 66)
}
}
/// @dev Packs order UID parameters into the specified memory location. The
/// result is equivalent to `abi.encodePacked(...)` with the difference that
/// it allows re-using the memory for packing the order UID.
///
/// This function reverts if the order UID buffer is not the correct size.
///
/// @param orderUid The buffer pack the order UID parameters into.
/// @param orderDigest The EIP-712 struct digest derived from the order
/// parameters.
/// @param owner The address of the user who owns this order.
/// @param validTo The epoch time at which the order will stop being valid.
function packOrderUidParams(
bytes memory orderUid,
bytes32 orderDigest,
address owner,
uint32 validTo
) internal pure {
require(orderUid.length == UID_LENGTH, "GPv2: uid buffer overflow");
// NOTE: Write the order UID to the allocated memory buffer. The order
// parameters are written to memory in **reverse order** as memory
// operations write 32-bytes at a time and we want to use a packed
// encoding. This means, for example, that after writing the value of
// `owner` to bytes `20:52`, writing the `orderDigest` to bytes `0:32`
// will **overwrite** bytes `20:32`. This is desirable as addresses are
// only 20 bytes and `20:32` should be `0`s:
//
// | 1111111111222222222233333333334444444444555555
// byte | 01234567890123456789012345678901234567890123456789012345
// -------+---------------------------------------------------------
// field | [.........orderDigest..........][......owner.......][vT]
// -------+---------------------------------------------------------
// mstore | [000000000000000000000000000.vT]
// | [00000000000.......owner.......]
// | [.........orderDigest..........]
//
// Additionally, since Solidity `bytes memory` are length prefixed,
// 32 needs to be added to all the offsets.
//
// solhint-disable-next-line no-inline-assembly
assembly {
mstore(add(orderUid, 56), validTo)
mstore(add(orderUid, 52), owner)
mstore(add(orderUid, 32), orderDigest)
}
}
/// @dev Extracts specific order information from the standardized unique
/// order id of the protocol.
///
/// @param orderUid The unique identifier used to represent an order in
/// the protocol. This uid is the packed concatenation of the order digest,
/// the validTo order parameter and the address of the user who created the
/// order. It is used by the user to interface with the contract directly,
/// and not by calls that are triggered by the solvers.
/// @return orderDigest The EIP-712 signing digest derived from the order
/// parameters.
/// @return owner The address of the user who owns this order.
/// @return validTo The epoch time at which the order will stop being valid.
function extractOrderUidParams(
bytes calldata orderUid
)
internal
pure
returns (bytes32 orderDigest, address owner, uint32 validTo)
{
require(orderUid.length == UID_LENGTH, "GPv2: invalid uid");
// Use assembly to efficiently decode packed calldata.
// solhint-disable-next-line no-inline-assembly
assembly {
orderDigest := calldataload(orderUid.offset)
owner := shr(96, calldataload(add(orderUid.offset, 32)))
validTo := shr(224, calldataload(add(orderUid.offset, 52)))
}
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
/// @title ISettlement
/// @notice External interface of CoW Protocol's SolutionSettler contract.
interface ISettlement {
/// @return domainSeparator The domain separator for IERC1271 signature.
/// @dev Immutable value, would not change on chain forks.
function domainSeparator() external view returns (bytes32 domainSeparator);
/// @return vaultRelayer The address that'll use the pool liquidity in CoWprotocol swaps.
/// @dev Address that will transfer and transferFrom the pool. Has an infinite allowance.
function vaultRelayer() external view returns (address vaultRelayer);
}// SPDX-License-Identifier: UNLICENSED
// Copyright (c) 2025 Aave Labs
pragma solidity ^0.8.10;
/// @notice Data types used in the Adapter Hooks & Factory.
/// @author Aave Labs.
library DataTypes {
struct Permit {
uint256 amount;
uint256 deadline;
uint8 v;
bytes32 r;
bytes32 s;
}
struct CreditDelegationSig {
uint256 amount;
uint256 deadline;
uint8 v;
bytes32 r;
bytes32 s;
}
// keccak256('AdapterOrderSig(address instance,address sellToken,address buyToken,uint256 sellAmount,uint256 buyAmount,bytes32 kind,uint32 validTo,bytes32 appData)')
bytes32 public constant ADAPTER_ORDER_TYPEHASH =
0x1ca15395c04ac473d5b42656e3782ae1fce1a113fdb5432b57f8fb0870fa3178;
struct AdapterOrderSig {
address instance;
address sellToken;
address buyToken;
uint256 sellAmount;
uint256 buyAmount;
bytes32 kind;
uint32 validTo;
bytes32 appData;
}
/// @dev Data needed by the AdapterHook for the postHook execution.
struct HookOrderData {
// Owner of the AdapterHook Instance (the user signing the Order)
address owner;
// Address of the Instance to be receiver of the Order (as specified in the GPv2Order.Data)
address receiver;
// The asset being sold (as specified in the GPv2Order.Data)
address sellToken;
// The asset being bought (as specified in the GPv2Order.Data)
address buyToken;
// The amount to sell (as specified in the GPv2Order.Data)
uint256 sellAmount;
// The amount to buy (as specified in the GPv2Order.Data)
uint256 buyAmount;
// The kind of swap (as specified in the GPv2Order.Data)
bytes32 kind;
// The expiry date of the Order (as specified in the GPv2Order.Data)
uint256 validTo;
// The amount taken as Flashloan
uint256 flashLoanAmount;
// The fee amount to be repaid on top of the flashLoanAmount
uint256 flashLoanFeeAmount;
// The amount of sell token given as parameter for the postHook
uint256 hookSellTokenAmount;
// The amount of buy token given as parameter for the postHook
uint256 hookBuyTokenAmount;
}
struct HookAmounts {
// The amount taken as Flashloan
uint256 flashLoanAmount;
// The fee amount to be repaid on top of the flashLoanAmount
uint256 flashLoanFeeAmount;
// The amount of sell token given as parameter for the postHook
uint256 sellTokenAmount;
// The amount of buy token given as parameter for the postHook
uint256 buyTokenAmount;
}
struct OpenFlashLoan {
// Whether the AdapterHook Instance that took the Flashloan is active
bool instanceActive;
// The asset being lent
address asset;
// The total amount of the flashloan (principal + fees)
uint256 totalAmount;
}
}// SPDX-License-Identifier: UNLICENSED
// Copyright (c) 2025 Aave Labs
pragma solidity ^0.8.0;
import {DataTypes} from 'src/libraries/DataTypes.sol';
/// @notice Base interface for all Adapter Hooks.
/// @author Aave Labs.
interface IAaveBaseAdapter {
/// @notice Thrown when the Instance is already initialized.
error AlreadyInitialized();
/// @notice Thrown when the caller is not the Instance owner.
error CallerNotInstanceOwner();
/// @notice Thrown when the withdrawn amount is not the expected one.
error InvalidWithdraw();
/// @notice Thrown when the borrowed amount is not the expected one.
error InvalidBorrow();
/// @notice Thrown when the specified amount is invalid.
error InvalidAmount();
/// @notice Thrown when the specified `HookSellAmount` is invalid.
error InvalidHookSellAmount();
/// @notice Thrown when the current Instance balance is not the amount expected.
error InvalidBalance();
/// @notice Thrown when the specified amount is zero.
error InvalidZeroAmount();
/// @notice Thrown when the specified address is the zero address.
error InvalidZeroAddress();
/// @notice Thrown when the given Order signature is invalid.
error InvalidOrderSignature();
/// @notice Thrown when the given Order hash does not match the computed one.
error OrderHashMismatch();
/// @notice Thrown when the given Order buyToken is not the expected one.
error InvalidBuyToken();
/// @notice Thrown when the given Order sellToken is not the expected one.
error InvalidSellToken();
/// @notice Thrown when the given Order expiry is invalid.
error InvalidOrderExpiry();
/// @notice Thrown when the Order is expired.
error OrderExpired();
/// @notice Thrown when the given Order is a "partially fillable" one.
error OrderPartiallyFillable();
/// @notice Thrown when the given Order sellAmount is invalid.
error InvalidSellAmount();
/// @notice Thrown when the given Order buyAmount is invalid.
error InvalidBuyAmount();
/// @notice Thrown when the given Order kind is invalid.
error InvalidOrderKind();
/// @notice Thrown when the given Order receiver is invalid.
error InvalidOrderReceiver();
/// @notice Thrown when the given Order fee is not null.
error OrderFeeNotNull();
/// @notice Thrown when the given Order sellTokenBalance or buyTokenBalance is not null.
error InvalidOrderTokenBalancer();
/// @notice Sets the parameters of an Instance.
/// @param hookData_ The HookOrderData struct containing the order details & postHook parameters.
function setParameters(DataTypes.HookOrderData calldata hookData_) external;
/// @notice Returns the stored HookOrderData struct.
/// @return The stored HookOrderData struct.
function getHookData() external view returns (DataTypes.HookOrderData memory);
/// @notice AaveV3AdapterFactory contract.
function FACTORY() external view returns (address);
/// @notice Settlement contract.
function SETTLEMENT_CONTRACT() external view returns (address);
/// @notice Aave Pool contract.
function AAVE_POOL() external view returns (address);
}// SPDX-License-Identifier: UNLICENSED
// Copyright (c) 2025 Aave Labs
pragma solidity ^0.8.0;
import {IFlashLoanRouter} from 'cowprotocol/flash-loan-router/interface/IFlashLoanRouter.sol';
import {ICowSettlement} from 'cowprotocol/flash-loan-router/interface/ICowSettlement.sol';
import {GPv2Order} from 'cowprotocol/contracts/libraries/GPv2Order.sol';
import {DataTypes} from 'src/libraries/DataTypes.sol';
/// @notice Adapter Factory Base interface.
/// @author Aave Labs.
interface IBaseAdapterFactory {
/// @notice Thrown when the caller is not an Instance deployed by the Factory.
error CallerNotInstance();
/// @notice Thrown when the caller is not the Router.
error CallerNotRouter();
/// @notice Thrown when the specified amount is null.
error InvalidZeroAmount();
/// @notice Thrown when the specified address is the zero address.
error InvalidZeroAddress();
/// @notice Thrown when the specified implementation is already listed.
error ImplementationAlreadyListed();
/// @notice Thrown when the specified implementation is not active.
error ImplementationNotActive();
/// @notice Thrown when the Instance is not initialized.
error InstanceNotInitialized();
/// @notice Thrown when the Instance is already deployed.
error InstanceAlreadyDeployed();
/// @notice Thrown when the order receiver is invalid.
error InvalidOrderReceiver();
/// @notice Thrown when the specified lender is not the valid one for the Factory.
error InvalidLender();
/// @notice Thrown when the calling Instance has nothing to repay.
error NothingToRepay();
/// @notice Thrown when the order has been cancelled by the user.
error InstanceCancelled();
/// @notice Emitted when an AdapterHook Implementations status is updated.
event SetAdapterImplementation(address indexed adapterImplementation, bool active);
/// @notice Emitted when an Instance owner cancels it.
event CancelInstance(address indexed user, address indexed instanceAddress);
/// @notice Settlement contract.
function SETTLEMENT_CONTRACT() external view returns (ICowSettlement);
/// @notice FlashLoanRouter contract.
function ROUTER() external view returns (IFlashLoanRouter);
/// @notice Returns the domain separator used in the EIP712 encoding of the AdapterOrderSig struct.
/// @return The domain separator.
function DOMAIN_SEPARATOR() external view returns (bytes32);
/// @notice Notifies the AdapterFactory that a FlashLoan is ready to be repaid.
function notifyRepayFlashLoan() external;
/// @notice Deploys an Adapter Instance and transfers the FlashLoaned assets to it (must have been initiated before).
/// @param adapterImplementation The address of the Adapter Instance implementation to clone.
/// @param hookData The HookOrderData struct containing the order details & postHook parameters.
function deployAndTransferFlashLoan(
address adapterImplementation,
DataTypes.HookOrderData memory hookData
) external;
/// @notice Cancels an Adapter Instance to be deployed by the Factory.
/// @dev This is used to cancel a pending EIP-1271 Order before it is executed, by blocking the deployment of the Instance.
/// @param instance The address of the Adapter Instance to cancel.
function cancelInstance(address instance) external;
/// @notice Returns the determined address of an Adapter Instance to clone based on a specific Order.
/// @param adapterImplementation The address of the Adapter Implementation to clone.
/// @param hookData The HookOrderData struct containing the order details & postHook parameters.
/// @return The determined address of the Adapter Instance.
function getInstanceDeterministicAddress(
address adapterImplementation,
DataTypes.HookOrderData memory hookData
) external view returns (address);
/// @notice Verifies that the signature provided for an Order using an Adapter is valid.
/// @param orderOwner The address of the owner of the Order.
/// @param order The Order data to verify.
/// @param signature The signature to verify.
/// @return True if the signature is valid, false otherwise.
function verifyOrderSignature(
address orderOwner,
GPv2Order.Data memory order,
bytes memory signature
) external view returns (bool);
/// @notice Sets the status of an AdapterHook Implementation.
/// @param adapterImplementation The address of the Adapter Implementation.
/// @param active True to activate, false to deactivate.
function setAdapterImplementation(address adapterImplementation, bool active) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
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;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library DataTypes {
/**
* This exists specifically to maintain the `getReserveData()` interface, since the new, internal
* `ReserveData` struct includes the reserve's `virtualUnderlyingBalance`.
*/
struct ReserveDataLegacy {
//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;
// DEPRECATED on v3.2.0
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;
// DEPRECATED on v3.2.0
address stableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
// DEPRECATED on v3.4.0, should use the `RESERVE_INTEREST_RATE_STRATEGY` variable from the Pool contract
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
// DEPRECATED on v3.4.0
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
}
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;
/// @notice reused `__deprecatedStableBorrowRate` storage from pre 3.2
// the current accumulate deficit in underlying tokens
uint128 deficit;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//timestamp until when liquidations are not allowed on the reserve, if set to past liquidations will be allowed
uint40 liquidationGracePeriodUntil;
//aToken address
address aTokenAddress;
// DEPRECATED on v3.2.0
address __deprecatedStableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
// DEPRECATED on v3.4.0, should use the `RESERVE_INTEREST_RATE_STRATEGY` variable from the Pool contract
address __deprecatedInterestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
// In aave 3.3.0 this storage slot contained the `unbacked`
uint128 virtualUnderlyingBalance;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
//the amount of underlying accounted for by the protocol
// DEPRECATED on v3.4.0. Moved into the same slot as accruedToTreasury for optimized storage access.
uint128 __deprecatedVirtualUnderlyingBalance;
}
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: DEPRECATED: 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: DEPRECATED: eMode category
//bit 176-211: DEPRECATED: unbacked mint cap
//bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
//bit 252: DEPRECATED: virtual accounting is enabled for the reserve
//bit 253-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;
}
// DEPRECATED: kept for backwards compatibility, might be removed in a future version
struct EModeCategoryLegacy {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
// DEPRECATED
address priceSource;
string label;
}
struct CollateralConfig {
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
}
struct EModeCategoryBaseConfiguration {
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
string label;
}
struct EModeCategory {
// each eMode category has a custom ltv and liquidation threshold
uint16 ltv;
uint16 liquidationThreshold;
uint16 liquidationBonus;
uint128 collateralBitmap;
string label;
uint128 borrowableBitmap;
}
enum InterestRateMode {
NONE,
__DEPRECATED,
VARIABLE
}
struct ReserveCache {
uint256 currScaledVariableDebt;
uint256 nextScaledVariableDebt;
uint256 currLiquidityIndex;
uint256 nextLiquidityIndex;
uint256 currVariableBorrowIndex;
uint256 nextVariableBorrowIndex;
uint256 currLiquidityRate;
uint256 currVariableBorrowRate;
uint256 reserveFactor;
ReserveConfigurationMap reserveConfiguration;
address aTokenAddress;
address variableDebtTokenAddress;
uint40 reserveLastUpdateTimestamp;
}
struct ExecuteLiquidationCallParams {
address liquidator;
uint256 debtToCover;
address collateralAsset;
address debtAsset;
address borrower;
bool receiveAToken;
address priceOracle;
uint8 borrowerEModeCategory;
address priceOracleSentinel;
address interestRateStrategyAddress;
}
struct ExecuteSupplyParams {
address user;
address asset;
address interestRateStrategyAddress;
uint256 amount;
address onBehalfOf;
uint16 referralCode;
}
struct ExecuteBorrowParams {
address asset;
address user;
address onBehalfOf;
address interestRateStrategyAddress;
uint256 amount;
InterestRateMode interestRateMode;
uint16 referralCode;
bool releaseUnderlying;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ExecuteRepayParams {
address asset;
address user;
address interestRateStrategyAddress;
uint256 amount;
InterestRateMode interestRateMode;
address onBehalfOf;
bool useATokens;
address oracle;
uint8 userEModeCategory;
}
struct ExecuteWithdrawParams {
address user;
address asset;
address interestRateStrategyAddress;
uint256 amount;
address to;
address oracle;
uint8 userEModeCategory;
}
struct ExecuteEliminateDeficitParams {
address user;
address asset;
address interestRateStrategyAddress;
uint256 amount;
}
struct FinalizeTransferParams {
address asset;
address from;
address to;
uint256 scaledAmount;
uint256 scaledBalanceFromBefore;
uint256 scaledBalanceToBefore;
address oracle;
uint8 fromEModeCategory;
}
struct FlashloanParams {
address user;
address receiverAddress;
address[] assets;
uint256[] amounts;
uint256[] interestRateModes;
address interestRateStrategyAddress;
address onBehalfOf;
bytes params;
uint16 referralCode;
uint256 flashLoanPremium;
address addressesProvider;
address pool;
uint8 userEModeCategory;
bool isAuthorizedFlashBorrower;
}
struct FlashloanSimpleParams {
address user;
address receiverAddress;
address asset;
address interestRateStrategyAddress;
uint256 amount;
bytes params;
uint16 referralCode;
uint256 flashLoanPremium;
}
struct FlashLoanRepaymentParams {
address user;
uint256 amount;
uint256 totalPremium;
address asset;
address interestRateStrategyAddress;
address receiverAddress;
uint16 referralCode;
}
struct CalculateUserAccountDataParams {
UserConfigurationMap userConfig;
address user;
address oracle;
uint8 userEModeCategory;
}
struct ValidateBorrowParams {
ReserveCache reserveCache;
UserConfigurationMap userConfig;
address asset;
address userAddress;
uint256 amountScaled;
InterestRateMode interestRateMode;
address oracle;
uint8 userEModeCategory;
address priceOracleSentinel;
}
struct ValidateLiquidationCallParams {
ReserveCache debtReserveCache;
uint256 totalDebt;
uint256 healthFactor;
address priceOracleSentinel;
address borrower;
address liquidator;
}
struct CalculateInterestRatesParams {
uint256 unbacked;
uint256 liquidityAdded;
uint256 liquidityTaken;
uint256 totalDebt;
uint256 reserveFactor;
address reserve;
// @notice DEPRECATED in 3.4, but kept for backwards compatibility
bool usingVirtualBalance;
uint256 virtualUnderlyingBalance;
}
struct InitReserveParams {
address asset;
address aTokenAddress;
address variableDebtAddress;
uint16 reservesCount;
uint16 maxNumberReserves;
}
}// SPDX-License-Identifier: MIT
// Vendored from OpenZeppelin contracts with minor modifications:
// - Modified Solidity version
// - Formatted code
// - Added `name`, `symbol` and `decimals` function declarations
// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC20/IERC20.sol>
pragma solidity >=0.7.6 <0.9.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the number of decimals the token uses.
*/
function decimals() external view returns (uint8);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(
address owner,
address spender
) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8;
import {Loan} from "../library/Loan.sol";
import {ICowAuthentication} from "../vendored/ICowAuthentication.sol";
import {ICowSettlement} from "./ICowSettlement.sol";
/// @title Flash-loan Router Interface
/// @author CoW DAO developers
/// @notice Interface describing the functions available for interacting with
/// the flash-loan router.
/// @dev The flash loan router is intended to be a solver for CoW Protocol.
interface IFlashLoanRouter {
/// @notice Request all flash loan specified in the input and, after that,
/// executes the specified settlement.
/// @dev It's the solver's responsibility to make sure the loan is specified
/// correctly. The router contract offers no validation of the fact that
/// the flash loan proceeds are available for spending.
///
/// The repayment of a flash loan is different based on the protocol. For
/// example, some expect to retrieve the funds from this borrower contract
/// through `transferFrom`, while other check the lender balance is as
/// expected after the flash loan has been processed. The executed
/// settlement must be built to cater to the needs of the specified lender.
///
/// A settlement can be executed at most once in a call. The settlement
/// data cannot change during execution. Only the settle function can be
/// called. All of this is also the case if the lender is untrusted.
/// @param loans The list of flash loans to be requested before the
/// settlement is executed. The loans will be requested in the specified
/// order.
/// @param settlement The ABI-encoded bytes for a call to `settle()` (as
/// in `abi.encodeCall`).
function flashLoanAndSettle(Loan.Data[] calldata loans, bytes calldata settlement) external;
/// @notice Once a borrower has received the proceeds of a flash loan, it
/// calls back the router through this function.
/// @param encodedLoansWithSettlement The data the borrower received when
/// it was called, without any modification.
function borrowerCallBack(bytes calldata encodedLoansWithSettlement) external;
/// @notice The settlement contract supported by this router. This is the
/// contract that will be called when the settlement is executed.
function settlementContract() external view returns (ICowSettlement);
/// @notice The settlement authenticator contract for CoW Protocol. This
/// contract determines who the solvers for CoW Protocol are.
function settlementAuthentication() external view returns (ICowAuthentication);
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8;
/// @notice An interface for CoW Protocol's settlement contract that only
/// enumerates the functions and types needed for this project.
/// For more information, see the project's repository:
/// <https://github.com/cowprotocol/contracts/blob/9c1984b864d0a6703a877a088be6dac56450808c/src/contracts/GPv2Settlement.sol>
/// The code and comments have been mostly copied from the linked resources.
interface ICowSettlement {
/// @notice A struct representing a trade to be executed as part a batch
/// settlement.
/// @dev See <https://github.com/cowprotocol/contracts/blob/9c1984b864d0a6703a877a088be6dac56450808c/src/contracts/libraries/GPv2Trade.sol#L14-L28>.
struct Trade {
uint256 sellTokenIndex;
uint256 buyTokenIndex;
address receiver;
uint256 sellAmount;
uint256 buyAmount;
uint32 validTo;
bytes32 appData;
uint256 feeAmount;
uint256 flags;
uint256 executedAmount;
bytes signature;
}
/// @notice Interaction data for performing arbitrary contract interactions.
/// Submitted to [`GPv2Settlement.settle`] for code execution.
/// @dev See <https://github.com/cowprotocol/contracts/blob/9c1984b864d0a6703a877a088be6dac56450808c/src/contracts/libraries/GPv2Interaction.sol#L7-L13>.
struct Interaction {
address target;
uint256 value;
bytes callData;
}
/// @notice The authenticator is used to determine who can call the settle
/// function. That is, only authorized solvers have the ability to invoke
/// settlements. Any valid authenticator implements an isSolver method
/// called by the onlySolver modifier below.
/// @dev See <https://github.com/cowprotocol/contracts/blob/9c1984b864d0a6703a877a088be6dac56450808c/src/contracts/GPv2Settlement.sol#L28-L32>.
function authenticator() external view returns (address);
/// @notice Settle the specified orders at a clearing price. Note that it is
/// the responsibility of the caller to ensure that all GPv2 invariants are
/// upheld for the input settlement, otherwise this call will revert.
/// Namely:
/// - All orders are valid and signed
/// - Accounts have sufficient balance and approval.
/// - Settlement contract has sufficient balance to execute trades. Note
/// this implies that the accumulated fees held in the contract can also
/// be used for settlement. This is OK since:
/// - Solvers need to be authorized
/// - Misbehaving solvers will be slashed for abusing accumulated fees for
/// settlement
/// - Critically, user orders are entirely protected
///
/// @param tokens An array of ERC20 tokens to be traded in the settlement.
/// Trades encode tokens as indices into this array.
/// @param clearingPrices An array of clearing prices where the `i`-th price
/// is for the `i`-th token in the [`tokens`] array.
/// @param trades Trades for signed orders.
/// @param interactions Smart contract interactions split into three
/// separate lists to be run before the settlement, during the settlement
/// and after the settlement respectively.
/// @dev See <https://github.com/cowprotocol/contracts/blob/9c1984b864d0a6703a877a088be6dac56450808c/src/contracts/GPv2Settlement.sol#L99-L126>.
function settle(
address[] calldata tokens,
uint256[] calldata clearingPrices,
Trade[] calldata trades,
Interaction[][3] calldata interactions
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8;
import {IBorrower} from "../interface/IBorrower.sol";
import {IERC20} from "../vendored/IERC20.sol";
/// @title Loan Library
/// @author CoW DAO developers
/// @notice A library describing a flash-loan request by the flash-loan router
/// and providing related utility functions.
library Loan {
/// @notice The representation of a flash-loan request by the flash-loan
/// router.
struct Data {
/// @notice The amount of funds requested from the lender.
uint256 amount;
/// @notice The contract that directly requests the flash loan from the
/// lender and eventually calls back the router.
IBorrower borrower;
/// @notice The contract that loans out the funds to the borrower.
address lender;
/// @notice The token that is requested in the flash loan.
IERC20 token;
}
/// @notice A type that wraps a pointer to raw data in memory.
/// @dev A loan is expected to be encoded in memory as follows:
///
/// Content: |-- amount --||-- borrower --||-- lender --||-- token --|
/// Length: |<--32 bytes-->||<--20 bytes-->||<--20 bytes-->||<--20 bytes-->|
type EncodedData is uint256;
// This is a list of offsets to add to the memory pointer to get the memory
// location of the respective loan parameter. Note: -12 because addresses
// are zero-padded to the left and mload/mstore work on groups of 32 bytes.
uint256 private constant OFFSET_BORROWER = 32 - 12;
uint256 private constant OFFSET_LENDER = 32 + 1 * 20 - 12;
uint256 private constant OFFSET_TOKEN = 32 + 2 * 20 - 12;
/// @notice The number of sequential bytes required to encode a loan in
/// memory.
uint256 internal constant ENCODED_LOAN_BYTE_SIZE = 32 + 3 * 20;
/// @notice Write the input loan to the memory location pointed to by the
/// input encodedLoan.
/// @param encodedLoan The memory location from which to start writing the
/// byte representation of the loan. It is assumed to have at least
/// `ENCODED_LOAN_BYTE_SIZE` available from that point it in memory.
/// @param loan The loan to store.
function store(EncodedData encodedLoan, Data calldata loan) internal pure {
uint256 amount = loan.amount;
IBorrower borrower = loan.borrower;
address lender = loan.lender;
IERC20 token = loan.token;
// Note: addresses are right-aligned, memory is written to starting
// from the end and overwriting the address left-side padding.
assembly ("memory-safe") {
// Unchecked: we assume that the input value isn't at the end of the
// memory array. This does not happen with Solidity standard memory
// allocation.
mstore(add(encodedLoan, OFFSET_TOKEN), token)
mstore(add(encodedLoan, OFFSET_LENDER), lender)
mstore(add(encodedLoan, OFFSET_BORROWER), borrower)
// offset is zero
mstore(encodedLoan, amount)
}
}
/// @notice Reads the loan parameter from the input location in memory.
/// @param loan The memory location from which to read the loan.
/// @return amount The amount to be borrowed (see `Loan.Data`).
/// @return borrower The address of the borrower contract (see `Loan.Data`).
/// @return lender The lender address (see `Loan.Data`).
/// @return token The token to borrow (see `Loan.Data`).
function decode(EncodedData loan)
internal
pure
returns (uint256 amount, IBorrower borrower, address lender, IERC20 token)
{
assembly ("memory-safe") {
// Note: the values don't need to be masked since masking occurs
// when the value is accessed and not when stored.
// <https://docs.soliditylang.org/en/v0.8.28/assembly.html#access-to-external-variables-functions-and-libraries>
amount := mload(loan)
borrower := mload(add(loan, OFFSET_BORROWER))
lender := mload(add(loan, OFFSET_LENDER))
token := mload(add(loan, OFFSET_TOKEN))
}
}
}// SPDX-License-Identifier: LGPL-3.0-or-later
// Vendored from CoW DAO contracts with minor modifications:
// - Formatted code
// - Changed contract name
// <https://github.com/cowprotocol/contracts/blob/9c1984b864d0a6703a877a088be6dac56450808c/src/contracts/interfaces/GPv2Authentication.sol>
pragma solidity >=0.7.6 <0.9.0;
/// @title Gnosis Protocol v2 Authentication Interface
/// @author Gnosis Developers
interface ICowAuthentication {
/// @dev determines whether the provided address is an authenticated solver.
/// @param prospectiveSolver the address of prospective solver.
/// @return true when prospectiveSolver is an authenticated solver, otherwise false.
function isSolver(address prospectiveSolver) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8;
import {IERC20} from "../vendored/IERC20.sol";
import {ICowSettlement} from "./ICowSettlement.sol";
import {IFlashLoanRouter} from "./IFlashLoanRouter.sol";
/// @title Flash-loan Borrower
/// @author CoW DAO developers
/// @notice The CoW Protocol flash-loan router uses the flash-loan borrower
/// contract as the intermediary that requests funds through a flash loan.
/// Different flash-loan protocols have different logic for flash loans:
/// usually, the call-back function name and parameters are different. Each
/// flash-loan protocol must have a dedicated Borrower contract to be supported
/// by the flash-loan router.
/// A concrete borrower implementation generally calls a dedicated flash-loan
/// function on the lender and then awaits for a callback from it. The borrower
/// then calls back the router for further processing.
interface IBorrower {
/// @notice Requests a flash loan with the specified parameters from the
/// lender and, once the funds have been received, call back the router
/// while passing through the specified custom data. The flash-loan
/// repayment is expected to take place during the final settlement in the
/// router.
/// @param lender The address of the flash-loan lender from which to borrow.
/// @param token The token that is requested in the flash loan.
/// @param amount The amount of funds requested from the lender.
/// @param callBackData The data to send back when calling the router once
/// the loan is received.
function flashLoanAndCallBack(address lender, IERC20 token, uint256 amount, bytes calldata callBackData) external;
/// @notice Approves the target address to spend the specified token on
/// behalf of the Borrower up to the specified amount.
/// @dev In general, the only way to transfer funds out of this contract is
/// through a call to this function and a subsequent call to `transferFrom`.
/// This approval is expected to work similarly to an ERC-20 approval (in
/// particular, the allowance doesn't reset once the call is terminated).
/// @param token The token to approve for transferring.
/// @param target The address that will be allowed to spend the token.
/// @param amount The amount of tokens to set as the allowance.
function approve(IERC20 token, address target, uint256 amount) external;
/// @notice The settlement contract supported by this contract.
function settlementContract() external view returns (ICowSettlement);
/// @notice The router contract that manages this borrower contract. It will
/// be called back once the flash-loan proceeds are received and is the only
/// address that can trigger a flash loan request.
function router() external view returns (IFlashLoanRouter);
}// SPDX-License-Identifier: MIT
// Vendored from OpenZeppelin contracts with minor modifications:
// - Formatted code
// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v5.2/contracts/token/ERC20/IERC20.sol>
// Note: v5.2 points to commit acd4ff74de833399287ed6b31b4debf6b2b35527.
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"solidity-utils/=lib/aave-v3-origin/lib/solidity-utils/src/contracts/",
"aave-v3-origin/=lib/aave-v3-origin/src/",
"aave-address-book/=lib/aave-address-book/src/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"cowprotocol/flash-loan-router/=lib/flash-loan-router/src/",
"cowprotocol/contracts/=lib/contracts/src/contracts/",
"cowprotocol/test/=lib/contracts/test/",
"@openzeppelin/contracts-upgradeable/=lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"contracts/=lib/contracts/src/",
"ds-test/=lib/aave-v3-origin/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"flash-loan-router/=lib/flash-loan-router/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/aave-v3-origin/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 999999
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"factory_","type":"address"},{"internalType":"address","name":"aavePool_","type":"address"},{"internalType":"address","name":"settlement_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"CallerNotInstanceOwner","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidBalance","type":"error"},{"inputs":[],"name":"InvalidBorrow","type":"error"},{"inputs":[],"name":"InvalidBuyAmount","type":"error"},{"inputs":[],"name":"InvalidBuyToken","type":"error"},{"inputs":[],"name":"InvalidHookSellAmount","type":"error"},{"inputs":[],"name":"InvalidOrderExpiry","type":"error"},{"inputs":[],"name":"InvalidOrderKind","type":"error"},{"inputs":[],"name":"InvalidOrderReceiver","type":"error"},{"inputs":[],"name":"InvalidOrderSignature","type":"error"},{"inputs":[],"name":"InvalidOrderTokenBalancer","type":"error"},{"inputs":[],"name":"InvalidSellAmount","type":"error"},{"inputs":[],"name":"InvalidSellToken","type":"error"},{"inputs":[],"name":"InvalidWithdraw","type":"error"},{"inputs":[],"name":"InvalidZeroAddress","type":"error"},{"inputs":[],"name":"InvalidZeroAmount","type":"error"},{"inputs":[],"name":"OrderExpired","type":"error"},{"inputs":[],"name":"OrderFeeNotNull","type":"error"},{"inputs":[],"name":"OrderHashMismatch","type":"error"},{"inputs":[],"name":"OrderPartiallyFillable","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"AAVE_POOL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FACTORY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SETTLEMENT_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHookData","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"sellToken","type":"address"},{"internalType":"address","name":"buyToken","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"bytes32","name":"kind","type":"bytes32"},{"internalType":"uint256","name":"validTo","type":"uint256"},{"internalType":"uint256","name":"flashLoanAmount","type":"uint256"},{"internalType":"uint256","name":"flashLoanFeeAmount","type":"uint256"},{"internalType":"uint256","name":"hookSellTokenAmount","type":"uint256"},{"internalType":"uint256","name":"hookBuyTokenAmount","type":"uint256"}],"internalType":"struct DataTypes.HookOrderData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_orderHash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct DataTypes.Permit","name":"erc20Permit","type":"tuple"}],"name":"repayDebtWithFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"sellToken","type":"address"},{"internalType":"address","name":"buyToken","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"bytes32","name":"kind","type":"bytes32"},{"internalType":"uint256","name":"validTo","type":"uint256"},{"internalType":"uint256","name":"flashLoanAmount","type":"uint256"},{"internalType":"uint256","name":"flashLoanFeeAmount","type":"uint256"},{"internalType":"uint256","name":"hookSellTokenAmount","type":"uint256"},{"internalType":"uint256","name":"hookBuyTokenAmount","type":"uint256"}],"internalType":"struct DataTypes.HookOrderData","name":"hookData_","type":"tuple"}],"name":"setParameters","outputs":[],"stateMutability":"nonpayable","type":"function"}]Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.