Contract Overview
Balance:
0 Ether
EtherValue:
$0.00
More Info
Txn Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x5ace0fdd7524533c7afe02def6a8e307ba70a9221929839b3d5c2bc8372f1989 | Swap Exact Token... | 16056870 | 62 days 5 hrs ago | 0xabbb9eb2512904123f9d372f26e2390a190d8550 | IN | 0xa333c87f4e61aa6e08c7e65ac59d2fbad0033646 | 0 Ether | 0.00256282 | |
0x602f45c442dc007204980ab07db26af91e719ac4ac7bb82ddc2df47236a2910f | Swap Exact Token... | 15976536 | 73 days 10 hrs ago | 0x43faf3f8bef053d901c572edc32f055c20efb764 | IN | 0xa333c87f4e61aa6e08c7e65ac59d2fbad0033646 | 0 Ether | 0.00691708 | |
0xe755072b1a54db8b05780095fbdf7626e6a0ed0e54a32919d119b15ba6c65cc5 | Swap Exact Token... | 15862495 | 89 days 8 hrs ago | 0xb0e2061b34171edc2b3c34e86b0b1f05ec7eeffc | IN | 0xa333c87f4e61aa6e08c7e65ac59d2fbad0033646 | 0 Ether | 0.00200844 | |
0x7e3921553968c4d7cfdc99158b0140682761c3ce862b272930c0693d22f81800 | 0x60e06040 | 15833486 | 93 days 10 hrs ago | Gearbox Protocol: Deployer | IN | Contract Creation | 0 Ether | 0.05343831 |
[ Download CSV Export ]
View more zero value Internal Transactions in Advanced View mode
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0xe426619cBbdFF6EDb381b800683085c14A915dA9
Contract Name:
UniswapV2Adapter
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import { AbstractAdapter } from "@gearbox-protocol/core-v2/contracts/adapters/AbstractAdapter.sol"; import { IUniswapV2Router02 } from "../../integrations/uniswap/IUniswapV2Router02.sol"; import { IUniswapV2Adapter } from "../../interfaces/uniswap/IUniswapV2Adapter.sol"; import { IAdapter, AdapterType } from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; import { RAY } from "@gearbox-protocol/core-v2/contracts/libraries/Constants.sol"; // EXCEPTIONS import { NotImplementedException } from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; /// @title UniswapV2 Router adapter contract UniswapV2Adapter is AbstractAdapter, IUniswapV2Adapter, ReentrancyGuard { AdapterType public constant _gearboxAdapterType = AdapterType.UNISWAP_V2_ROUTER; uint16 public constant _gearboxAdapterVersion = 2; /// @dev Constructor /// @param _creditManager Address Credit manager /// @param _router Address of IUniswapV2Router02 constructor(address _creditManager, address _router) AbstractAdapter(_creditManager, _router) {} /** * @dev Sends an order to swap tokens to exact tokens using a Uniswap-compatible protocol * - Makes a max allowance fast check call to target, replacing the `to` parameter with the CA address * @param amountOut The amount of output tokens to receive. * @param amountInMax The maximum amount of input tokens that can be required before the transaction reverts. * @param path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of * addresses must exist and have liquidity. * @param deadline Unix timestamp after which the transaction will revert. * for more information, see: https://uniswap.org/docs/v2/smart-contracts/router02/ * @notice `to` is ignored, since it is forbidden to transfer funds from a CA * @notice Fast check parameters: * Input token: First token in the path * Output token: Last token in the path * Input token is allowed, since the target does a transferFrom for the input token * The input token does not need to be disabled, because this does not spend the entire * balance, generally */ function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address, uint256 deadline ) external override nonReentrant returns (uint256[] memory amounts) { address creditAccount = creditManager.getCreditAccountOrRevert( msg.sender ); // F:[AUV2-1] address tokenIn = path[0]; // F:[AUV2-2] address tokenOut = path[path.length - 1]; // F:[AUV2-2] amounts = abi.decode( _executeMaxAllowanceFastCheck( creditAccount, tokenIn, tokenOut, abi.encodeWithSelector( IUniswapV2Router02.swapTokensForExactTokens.selector, amountOut, amountInMax, path, creditAccount, deadline ), true, false ), (uint256[]) ); // F:[AUV2-2] } /** * @dev Sends an order to swap an exact amount of token to another token using a Uniswap-compatible protocol * - Makes a max allowance fast check call to target, replacing the `to` parameter with the CA address * @param amountIn The amount of input tokens to send. * @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert. * @param path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of * addresses must exist and have liquidity. * @param deadline Unix timestamp after which the transaction will revert. * for more information, see: https://uniswap.org/docs/v2/smart-contracts/router02/ * @notice `to` is ignored, since it is forbidden to transfer funds from a CA * @notice Fast check parameters: * Input token: First token in the path * Output token: Last token in the path * Input token is allowed, since the target does a transferFrom for the input token * The input token does not need to be disabled, because this does not spend the entire * balance, generally */ function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address, uint256 deadline ) external override nonReentrant returns (uint256[] memory amounts) { address creditAccount = creditManager.getCreditAccountOrRevert( msg.sender ); // F:[AUV2-1] address tokenIn = path[0]; // F:[AUV2-3] address tokenOut = path[path.length - 1]; // F:[AUV2-3] amounts = abi.decode( _executeMaxAllowanceFastCheck( creditAccount, tokenIn, tokenOut, abi.encodeWithSelector( IUniswapV2Router02.swapExactTokensForTokens.selector, amountIn, amountOutMin, path, creditAccount, deadline ), true, false ), (uint256[]) ); // F:[AUV2-3] } /** * @dev Sends an order to swap the entire token balance to another token using a Uniswap-compatible protocol * - Makes a max allowance fast check call to target, replacing the `to` parameter with the CA address * @param rateMinRAY The minimal exchange rate between the input and the output tokens. * @param path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of * addresses must exist and have liquidity. * @param deadline Unix timestamp after which the transaction will revert. * for more information, see: https://uniswap.org/docs/v2/smart-contracts/router02/ * @notice Under the hood, calls swapExactTokensForTokens, passing balance minus 1 as the amount * @notice Fast check parameters: * Input token: First token in the path * Output token: Last token in the path * Input token is allowed, since the target does a transferFrom for the input token * The input token does need to be disabled, because this spends the entire balance */ function swapAllTokensForTokens( uint256 rateMinRAY, address[] calldata path, uint256 deadline ) external override nonReentrant returns (uint256[] memory amounts) { address creditAccount = creditManager.getCreditAccountOrRevert( msg.sender ); // F:[AUV2-1] address tokenIn = path[0]; // F:[AUV2-4] address tokenOut = path[path.length - 1]; // F:[AUV2-4] uint256 balanceInBefore = IERC20(tokenIn).balanceOf(creditAccount); // F:[AUV2-4] if (balanceInBefore > 1) { unchecked { balanceInBefore--; } amounts = abi.decode( _executeMaxAllowanceFastCheck( creditAccount, tokenIn, tokenOut, abi.encodeWithSelector( IUniswapV2Router02.swapExactTokensForTokens.selector, balanceInBefore, (balanceInBefore * rateMinRAY) / RAY, path, creditAccount, deadline ), true, true ), (uint256[]) ); // F:[AUV2-4] } } /// @dev Not implemented, as native ETH is not supported function removeLiquidityETHSupportingFeeOnTransferTokens( address, // token, uint256, // liquidity, uint256, // amountTokenMin, uint256, // amountETHMin, address, // to, uint256 // deadline ) external pure override returns (uint256) { revert NotImplementedException(); } /// @dev Not implemented, as native ETH is not supported function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address, // token, uint256, // liquidity, uint256, // amountTokenMin, uint256, // amountETHMin, address, // to, uint256, // deadline, bool, // approveMax, uint8, // v, bytes32, // r, bytes32 // s ) external pure override returns (uint256) { revert NotImplementedException(); } /// @dev Not implemented, as FeeOnTransfer tokens are not supported by Gearbox function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256, // amountIn, uint256, // amountOutMin, address[] calldata, // path, address, // to, uint256 // deadline ) external pure override { revert NotImplementedException(); } /// @dev Not implemented, as FeeOnTransfer tokens are not supported by Gearbox function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256, // amountOutMin, address[] calldata, // path, address, // to, uint256 // deadline ) external payable override { revert NotImplementedException(); } /// @dev Not implemented, as FeeOnTransfer tokens are not supported by Gearbox function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256, // amountIn, uint256, // amountOutMin, address[] calldata, // path, address, // to, uint256 // deadline ) external pure override { revert NotImplementedException(); } /// @dev Returns the address of the Uniswap pool factory function factory() external view override returns (address) { return IUniswapV2Router02(targetContract).factory(); } /// @dev Returns the address of WETH function WETH() external view override returns (address) { return IUniswapV2Router02(targetContract).WETH(); } /// @dev Not implemented, as Uniswap liquidity provision is not yet supported function addLiquidity( address, // tokenA, address, // tokenB, uint256, // amountADesired, uint256, // amountBDesired, uint256, // amountAMin, uint256, // amountBMin, address, // to, uint256 // deadline ) external pure override returns ( uint256, uint256, uint256 ) { revert NotImplementedException(); } /// @dev Not implemented, as Uniswap liquidity provision is not yet supported function addLiquidityETH( address, // token, uint256, // amountTokenDesired, uint256, // amountTokenMin, uint256, // amountETHMin, address, // to, uint256 // deadline ) external payable override returns ( uint256, uint256, uint256 ) { revert NotImplementedException(); } /// @dev Not implemented, as Uniswap liquidity provision is not yet supported function removeLiquidity( address, // tokenA, address, // tokenB, uint256, // liquidity, uint256, // amountAMin, uint256, // amountBMin, address, // to, uint256 // deadline ) external pure override returns (uint256, uint256) { revert NotImplementedException(); } /// @dev Not implemented, as Uniswap liquidity provision is not yet supported function removeLiquidityETH( address, // token, uint256, // liquidity, uint256, // amountTokenMin, uint256, // amountETHMin, address, // to, uint256 // deadline ) external pure override returns (uint256, uint256) { revert NotImplementedException(); } /// @dev Not implemented, as Uniswap liquidity provision is not yet supported function removeLiquidityWithPermit( address, // tokenA, address, // tokenB, uint256, // liquidity, uint256, // amountAMin, uint256, // amountBMin, address, // to, uint256, // deadline, bool, // approveMax, uint8, // v, bytes32, // r, bytes32 // s ) external pure override returns (uint256, uint256) { revert NotImplementedException(); } /// @dev Not implemented, as Uniswap liquidity provision is not yet supported function removeLiquidityETHWithPermit( address, // token, uint256, // liquidity, uint256, // amountTokenMin, uint256, // amountETHMin, address, // to, uint256, // deadline, bool, // approveMax, uint8, // v, bytes32, // r, bytes32 // s ) external pure override returns (uint256, uint256) { revert NotImplementedException(); } /// @dev Not implemented, as native ETH is not supported function swapExactETHForTokens( uint256, // amountOutMin, address[] calldata, // path, address, // to, uint256 // deadline ) external payable override returns (uint256[] memory) { revert NotImplementedException(); } /// @dev Not implemented, as native ETH is not supported function swapTokensForExactETH( uint256, // amountOut, uint256, // amountInMax, address[] calldata, // path, address, // to, uint256 // deadline ) external pure override returns (uint256[] memory) { revert NotImplementedException(); } /// @dev Not implemented, as native ETH is not supported function swapExactTokensForETH( uint256, // amountIn, uint256, //amountOutMin, address[] calldata, // path, address, // to, uint256 // deadline ) external pure override returns (uint256[] memory) { revert NotImplementedException(); } /// @dev Not implemented, as native ETH is not supported function swapETHForExactTokens( uint256, // amountOut, address[] calldata, // path, address, // to, uint256 // deadline ) external payable override returns (uint256[] memory) { revert NotImplementedException(); } /// @dev Returns the amount of token B that is equivalent /// to a specifed amount of token A, not accounting for fees /// @param amountA The amount of the input token being swapped /// @param reserveA Size of the input token reserve /// @param reserveB Size of the output token reserve function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external view override returns (uint256 amountB) { return IUniswapV2Router02(targetContract).quote( amountA, reserveA, reserveB ); // F:[AUV2-5] } /// @dev Returns the amount of the output token received when swapping /// a specific amount of the input token /// @param amountIn The amount of input token being swapped /// @param reserveIn Size of the input token reserve /// @param reserveOut Size of the output token reserve function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external view override returns (uint256 amountOut) { return IUniswapV2Router02(targetContract).getAmountOut( amountIn, reserveIn, reserveOut ); // F:[AUV2-6] } /// @dev Returns the amount of the input token required to /// receive a specified amount of the output token /// @param amountOut The desired amount of output token /// @param reserveIn Size of the input token reserve /// @param reserveOut Size of the output token reserve function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external view override returns (uint256 amountIn) { return IUniswapV2Router02(targetContract).getAmountIn( amountOut, reserveIn, reserveOut ); // F:[AUV2-7] } /// @dev Returns the amount of tokens received for each token along the path /// receive a specified amount of the output token /// @param amountIn The amount of input token being swapped /// @param path An array of token addresses function getAmountsOut(uint256 amountIn, address[] calldata path) external view override returns (uint256[] memory amounts) { return IUniswapV2Router02(targetContract).getAmountsOut(amountIn, path); // F:[AUV2-8] } /// @dev Returns the amount of tokens required for each token in the path, /// in order to receive the spcified amount /// receive a specified amount of the output token /// @param amountOut The desired amount of output token /// @param path An array of token addresses function getAmountsIn(uint256 amountOut, address[] calldata path) external view override returns (uint256[] memory amounts) { return IUniswapV2Router02(targetContract).getAmountsIn(amountOut, path); // F:[AUV2-9] } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: GPL-2.0-or-later // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; // Denominations uint256 constant WAD = 1e18; uint256 constant RAY = 1e27; // 25% of type(uint256).max uint256 constant ALLOWANCE_THRESHOLD = type(uint96).max >> 3; // FEE = 50% uint16 constant DEFAULT_FEE_INTEREST = 50_00; // 50% // LIQUIDATION_FEE 1.5% uint16 constant DEFAULT_FEE_LIQUIDATION = 1_50; // 1.5% // LIQUIDATION PREMIUM 4% uint16 constant DEFAULT_LIQUIDATION_PREMIUM = 4_00; // 4% // LIQUIDATION_FEE_EXPIRED 2% uint16 constant DEFAULT_FEE_LIQUIDATION_EXPIRED = 1_00; // 2% // LIQUIDATION PREMIUM EXPIRED 2% uint16 constant DEFAULT_LIQUIDATION_PREMIUM_EXPIRED = 2_00; // 2% // DEFAULT PROPORTION OF MAX BORROWED PER BLOCK TO MAX BORROWED PER ACCOUNT uint16 constant DEFAULT_LIMIT_PER_BLOCK_MULTIPLIER = 2; // Seconds in a year uint256 constant SECONDS_PER_YEAR = 365 days; uint256 constant SECONDS_PER_ONE_AND_HALF_YEAR = (SECONDS_PER_YEAR * 3) / 2; // OPERATIONS // Leverage decimals - 100 is equal to 2x leverage (100% * collateral amount + 100% * borrowed amount) uint8 constant LEVERAGE_DECIMALS = 100; // Maximum withdraw fee for pool in PERCENTAGE_FACTOR format uint8 constant MAX_WITHDRAW_FEE = 100; uint256 constant EXACT_INPUT = 1; uint256 constant EXACT_OUTPUT = 2; address constant UNIVERSAL_CONTRACT = 0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC;
// SPDX-License-Identifier: GPL-2.0-or-later // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ICreditManagerV2 } from "../interfaces/ICreditManagerV2.sol"; import { IAdapter } from "../interfaces/adapters/IAdapter.sol"; import { ZeroAddressException } from "../interfaces/IErrors.sol"; abstract contract AbstractAdapter is IAdapter { using Address for address; ICreditManagerV2 public immutable override creditManager; address public immutable override creditFacade; address public immutable override targetContract; constructor(address _creditManager, address _targetContract) { if (_creditManager == address(0) || _targetContract == address(0)) revert ZeroAddressException(); // F:[AA-2] creditManager = ICreditManagerV2(_creditManager); // F:[AA-1] creditFacade = ICreditManagerV2(_creditManager).creditFacade(); // F:[AA-1] targetContract = _targetContract; // F:[AA-1] } /// @dev Approves a token from the Credit Account to the target contract /// @param token Token to be approved /// @param amount Amount to be approved function _approveToken(address token, uint256 amount) internal { creditManager.approveCreditAccount( msg.sender, targetContract, token, amount ); } /// @dev Sends CallData to call the target contract from the Credit Account /// @param callData Data to be sent to the target contract function _execute(bytes memory callData) internal returns (bytes memory result) { result = creditManager.executeOrder( msg.sender, targetContract, callData ); } /// @dev Calls a target contract with maximal allowance and performs a fast check after /// @param creditAccount A credit account from which a call is made /// @param tokenIn The token that the interaction is expected to spend /// @param tokenOut The token that the interaction is expected to produce /// @param callData Data to call targetContract with /// @param allowTokenIn Whether the input token must be approved beforehand /// @param disableTokenIn Whether the input token should be disable afterwards (for interaction that spend the entire balance) /// @notice Must only be used for highly secure and immutable protocols, such as Uniswap & Curve function _executeMaxAllowanceFastCheck( address creditAccount, address tokenIn, address tokenOut, bytes memory callData, bool allowTokenIn, bool disableTokenIn ) internal returns (bytes memory result) { uint256 balanceInBefore; uint256 balanceOutBefore; if (msg.sender != creditFacade) { balanceInBefore = IERC20(tokenIn).balanceOf(creditAccount); // F:[AA-4A] balanceOutBefore = IERC20(tokenOut).balanceOf(creditAccount); // F:[AA-4A] } if (allowTokenIn) { _approveToken(tokenIn, type(uint256).max); } result = creditManager.executeOrder( msg.sender, targetContract, callData ); if (allowTokenIn) { _approveToken(tokenIn, type(uint256).max); } _fastCheck( creditAccount, tokenIn, tokenOut, balanceInBefore, balanceOutBefore, disableTokenIn ); } /// @dev Wrapper for _executeMaxAllowanceFastCheck that computes the Credit Account on the spot /// See params and other details above function _executeMaxAllowanceFastCheck( address tokenIn, address tokenOut, bytes memory callData, bool allowTokenIn, bool disableTokenIn ) internal returns (bytes memory result) { address creditAccount = creditManager.getCreditAccountOrRevert( msg.sender ); // F:[AA-3] result = _executeMaxAllowanceFastCheck( creditAccount, tokenIn, tokenOut, callData, allowTokenIn, disableTokenIn ); } /// @dev Calls a target contract with maximal allowance, then sets allowance to 1 and performs a fast check /// @param creditAccount A credit account from which a call is made /// @param tokenIn The token that the interaction is expected to spend /// @param tokenOut The token that the interaction is expected to produce /// @param callData Data to call targetContract with /// @param allowTokenIn Whether the input token must be approved beforehand /// @param disableTokenIn Whether the input token should be disable afterwards (for interaction that spend the entire balance) function _safeExecuteFastCheck( address creditAccount, address tokenIn, address tokenOut, bytes memory callData, bool allowTokenIn, bool disableTokenIn ) internal returns (bytes memory result) { uint256 balanceInBefore; uint256 balanceOutBefore; if (msg.sender != creditFacade) { balanceInBefore = IERC20(tokenIn).balanceOf(creditAccount); balanceOutBefore = IERC20(tokenOut).balanceOf(creditAccount); // F:[AA-4A] } if (allowTokenIn) { _approveToken(tokenIn, type(uint256).max); } result = creditManager.executeOrder( msg.sender, targetContract, callData ); if (allowTokenIn) { _approveToken(tokenIn, 1); } _fastCheck( creditAccount, tokenIn, tokenOut, balanceInBefore, balanceOutBefore, disableTokenIn ); } /// @dev Wrapper for _safeExecuteFastCheck that computes the Credit Account on the spot /// See params and other details above function _safeExecuteFastCheck( address tokenIn, address tokenOut, bytes memory callData, bool allowTokenIn, bool disableTokenIn ) internal returns (bytes memory result) { address creditAccount = creditManager.getCreditAccountOrRevert( msg.sender ); result = _safeExecuteFastCheck( creditAccount, tokenIn, tokenOut, callData, allowTokenIn, disableTokenIn ); } // // HEALTH CHECK FUNCTIONS // /// @dev Performs a fast check during ordinary adapter call, or skips /// it for multicalls (since a full collateral check is always performed after a multicall) /// @param creditAccount Credit Account for which the fast check is performed /// @param tokenIn Token that is spent by the operation /// @param tokenOut Token that is received as a result of operation /// @param balanceInBefore Balance of tokenIn before the operation /// @param balanceOutBefore Balance of tokenOut before the operation /// @param disableTokenIn Whether tokenIn needs to be disabled (required for multicalls, where the fast check is skipped) function _fastCheck( address creditAccount, address tokenIn, address tokenOut, uint256 balanceInBefore, uint256 balanceOutBefore, bool disableTokenIn ) private { if (msg.sender != creditFacade) { creditManager.fastCollateralCheck( creditAccount, tokenIn, tokenOut, balanceInBefore, balanceOutBefore ); } else { if (disableTokenIn) creditManager.disableToken(creditAccount, tokenIn); creditManager.checkAndEnableToken(creditAccount, tokenOut); } } /// @dev Performs a full collateral check during ordinary adapter call, or skips /// it for multicalls (since a full collateral check is always performed after a multicall) /// @param creditAccount Credit Account for which the full check is performed function _fullCheck(address creditAccount) internal { if (msg.sender != creditFacade) { creditManager.fullCollateralCheck(creditAccount); } } /// @dev Performs a enabled token optimization on account or skips /// it for multicalls (since a full collateral check is always performed after a multicall, /// and includes enabled token optimization by default) /// @param creditAccount Credit Account for which the full check is performed /// @notice Used when new tokens are added on an account but no tokens are subtracted /// (e.g., claiming rewards) function _checkAndOptimizeEnabledTokens(address creditAccount) internal { if (msg.sender != creditFacade) { creditManager.checkAndOptimizeEnabledTokens(creditAccount); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) 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 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { ICreditManagerV2 } from "../ICreditManagerV2.sol"; enum AdapterType { ABSTRACT, UNISWAP_V2_ROUTER, UNISWAP_V3_ROUTER, CURVE_V1_EXCHANGE_ONLY, YEARN_V2, CURVE_V1_2ASSETS, CURVE_V1_3ASSETS, CURVE_V1_4ASSETS, CURVE_V1_STECRV_POOL, CURVE_V1_WRAPPER, CONVEX_V1_BASE_REWARD_POOL, CONVEX_V1_BOOSTER, CONVEX_V1_CLAIM_ZAP, LIDO_V1, UNIVERSAL, LIDO_WSTETH_V1 } interface IAdapterExceptions { /// @dev Thrown when the adapter attempts to use a token /// that is not recognized as collateral in the connected /// Credit Manager error TokenIsNotInAllowedList(address); } interface IAdapter is IAdapterExceptions { /// @dev Returns the Credit Manager connected to the adapter function creditManager() external view returns (ICreditManagerV2); /// @dev Returns the Credit Facade connected to the adapter's Credit Manager function creditFacade() external view returns (address); /// @dev Returns the address of the contract the adapter is interacting with function targetContract() external view returns (address); /// @dev Returns the adapter type function _gearboxAdapterType() external pure returns (AdapterType); /// @dev Returns the adapter version function _gearboxAdapterVersion() external pure returns (uint16); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.2; import "./IUniswapV2Router01.sol"; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function factory() external view override returns (address); function WETH() external view override returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external override returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable override returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external override returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external override returns (uint256 amountToken, uint256 amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external override returns (uint256 amountA, uint256 amountB); function removeLiquidityETHWithPermit( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external override returns (uint256 amountToken, uint256 amountETH); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external override returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external override returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable override returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external override returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external override returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable override returns (uint256[] memory amounts); function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external view override returns (uint256 amountB); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external view override returns (uint256 amountOut); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external view override returns (uint256 amountIn); function getAmountsOut(uint256 amountIn, address[] calldata path) external view override returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view override returns (uint256[] memory amounts); }
// SPDX-License-Identifier: GPL-2.0-or-later // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { IAdapter } from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; import { IUniswapV2Router02 } from "../../integrations/uniswap/IUniswapV2Router02.sol"; interface IUniswapV2Adapter is IAdapter, IUniswapV2Router02 { /// @dev Sends an order to swap the entire token balance to another token using a Uniswap-compatible protocol /// @param rateMinRAY The minimal exchange rate between the input and the output tokens. //// @param path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of /// addresses must exist and have liquidity. /// @param deadline Unix timestamp after which the transaction will revert. /// @return amounts amountsOut, in the order of swaps in the path function swapAllTokensForTokens( uint256 rateMinRAY, address[] calldata path, uint256 deadline ) external returns (uint256[] memory amounts); }
// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; /// @dev Common contract exceptions /// @dev Thrown on attempting to set an important address to zero address error ZeroAddressException(); /// @dev Thrown on attempting to call a non-implemented function error NotImplementedException(); /// @dev Thrown on attempting to set an EOA as an important contract in the system error AddressIsNotContractException(address); /// @dev Thrown on attempting to use a non-ERC20 contract or an EOA as a token error IncorrectTokenContractException(); /// @dev Thrown on attempting to set a token price feed to an address that is not a /// correct price feed error IncorrectPriceFeedException(); /// @dev Thrown on attempting to call an access restricted function as a non-Configurator error CallerNotConfiguratorException(); /// @dev Thrown on attempting to pause a contract as a non-Pausable admin error CallerNotPausableAdminException(); /// @dev Thrown on attempting to pause a contract as a non-Unpausable admin error CallerNotUnPausableAdminException(); error TokenIsNotAddedToCreditManagerException(address token);
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { IPriceOracleV2 } from "./IPriceOracle.sol"; import { IVersion } from "./IVersion.sol"; enum ClosureAction { CLOSE_ACCOUNT, LIQUIDATE_ACCOUNT, LIQUIDATE_EXPIRED_ACCOUNT, LIQUIDATE_PAUSED } interface ICreditManagerV2Events { /// @dev Emits when a call to an external contract is made through the Credit Manager event ExecuteOrder(address indexed borrower, address indexed target); /// @dev Emits when a configurator is upgraded event NewConfigurator(address indexed newConfigurator); } interface ICreditManagerV2Exceptions { /// @dev Thrown if an access-restricted function is called by an address that is not /// the connected Credit Facade, or an allowed adapter error AdaptersOrCreditFacadeOnlyException(); /// @dev Thrown if an access-restricted function is called by an address that is not /// the connected Credit Facade error CreditFacadeOnlyException(); /// @dev Thrown if an access-restricted function is called by an address that is not /// the connected Credit Configurator error CreditConfiguratorOnlyException(); /// @dev Thrown on attempting to open a Credit Account for or transfer a Credit Account /// to the zero address or an address that already owns a Credit Account error ZeroAddressOrUserAlreadyHasAccountException(); /// @dev Thrown on attempting to execute an order to an address that is not an allowed /// target contract error TargetContractNotAllowedException(); /// @dev Thrown on failing a full collateral check after an operation error NotEnoughCollateralException(); /// @dev Thrown on attempting to receive a token that is not a collateral token /// or was forbidden error TokenNotAllowedException(); /// @dev Thrown if an attempt to approve a collateral token to a target contract failed error AllowanceFailedException(); /// @dev Thrown on attempting to perform an action for an address that owns no Credit Account error HasNoOpenedAccountException(); /// @dev Thrown on attempting to add a token that is already in a collateral list error TokenAlreadyAddedException(); /// @dev Thrown on configurator attempting to add more than 256 collateral tokens error TooManyTokensException(); /// @dev Thrown if more than the maximal number of tokens were enabled on a Credit Account, /// and there are not enough unused token to disable error TooManyEnabledTokensException(); /// @dev Thrown when a reentrancy into the contract is attempted error ReentrancyLockException(); } /// @notice All Credit Manager functions are access-restricted and can only be called /// by the Credit Facade or allowed adapters. Users are not allowed to /// interact with the Credit Manager directly interface ICreditManagerV2 is ICreditManagerV2Events, ICreditManagerV2Exceptions, IVersion { // // CREDIT ACCOUNT MANAGEMENT // /// @dev Opens credit account and borrows funds from the pool. /// - Takes Credit Account from the factory; /// - Requests the pool to lend underlying to the Credit Account /// /// @param borrowedAmount Amount to be borrowed by the Credit Account /// @param onBehalfOf The owner of the newly opened Credit Account function openCreditAccount(uint256 borrowedAmount, address onBehalfOf) external returns (address); /// @dev Closes a Credit Account - covers both normal closure and liquidation /// - Checks whether the contract is paused, and, if so, if the payer is an emergency liquidator. /// Only emergency liquidators are able to liquidate account while the CM is paused. /// Emergency liquidations do not pay a liquidator premium or liquidation fees. /// - Calculates payments to various recipients on closure: /// + Computes amountToPool, which is the amount to be sent back to the pool. /// This includes the principal, interest and fees, but can't be more than /// total position value /// + Computes remainingFunds during liquidations - these are leftover funds /// after paying the pool and the liquidator, and are sent to the borrower /// + Computes protocol profit, which includes interest and liquidation fees /// + Computes loss if the totalValue is less than borrow amount + interest /// - Checks the underlying token balance: /// + if it is larger than amountToPool, then the pool is paid fully from funds on the Credit Account /// + else tries to transfer the shortfall from the payer - either the borrower during closure, or liquidator during liquidation /// - Send assets to the "to" address, as long as they are not included into skipTokenMask /// - If convertWETH is true, the function converts WETH into ETH before sending /// - Returns the Credit Account back to factory /// /// @param borrower Borrower address /// @param closureActionType Whether the account is closed, liquidated or liquidated due to expiry /// @param totalValue Portfolio value for liqution, 0 for ordinary closure /// @param payer Address which would be charged if credit account has not enough funds to cover amountToPool /// @param to Address to which the leftover funds will be sent /// @param skipTokenMask Tokenmask contains 1 for tokens which needed to be skipped for sending /// @param convertWETH If true converts WETH to ETH function closeCreditAccount( address borrower, ClosureAction closureActionType, uint256 totalValue, address payer, address to, uint256 skipTokenMask, bool convertWETH ) external returns (uint256 remainingFunds); /// @dev Manages debt size for borrower: /// /// - Increase debt: /// + Increases debt by transferring funds from the pool to the credit account /// + Updates the cumulative index to keep interest the same. Since interest /// is always computed dynamically as borrowedAmount * (cumulativeIndexNew / cumulativeIndexOpen - 1), /// cumulativeIndexOpen needs to be updated, as the borrow amount has changed /// /// - Decrease debt: /// + Repays debt partially + all interest and fees accrued thus far /// + Updates cunulativeIndex to cumulativeIndex now /// /// @param creditAccount Address of the Credit Account to change debt for /// @param amount Amount to increase / decrease the principal by /// @param increase True to increase principal, false to decrease /// @return newBorrowedAmount The new debt principal function manageDebt( address creditAccount, uint256 amount, bool increase ) external returns (uint256 newBorrowedAmount); /// @dev Adds collateral to borrower's credit account /// @param payer Address of the account which will be charged to provide additional collateral /// @param creditAccount Address of the Credit Account /// @param token Collateral token to add /// @param amount Amount to add function addCollateral( address payer, address creditAccount, address token, uint256 amount ) external; /// @dev Transfers Credit Account ownership to another address /// @param from Address of previous owner /// @param to Address of new owner function transferAccountOwnership(address from, address to) external; /// @dev Requests the Credit Account to approve a collateral token to another contract. /// @param borrower Borrower's address /// @param targetContract Spender to change allowance for /// @param token Collateral token to approve /// @param amount New allowance amount function approveCreditAccount( address borrower, address targetContract, address token, uint256 amount ) external; /// @dev Requests a Credit Account to make a low-level call with provided data /// This is the intended pathway for state-changing interactions with 3rd-party protocols /// @param borrower Borrower's address /// @param targetContract Contract to be called /// @param data Data to pass with the call function executeOrder( address borrower, address targetContract, bytes memory data ) external returns (bytes memory); // // COLLATERAL VALIDITY AND ACCOUNT HEALTH CHECKS // /// @dev Enables a token on a Credit Account, including it /// into account health and total value calculations /// @param creditAccount Address of a Credit Account to enable the token for /// @param token Address of the token to be enabled function checkAndEnableToken(address creditAccount, address token) external; /// @dev Optimized health check for individual swap-like operations. /// @notice Fast health check assumes that only two tokens (input and output) /// participate in the operation and computes a % change in weighted value between /// inbound and outbound collateral. The cumulative negative change across several /// swaps in sequence cannot be larger than feeLiquidation (a fee that the /// protocol is ready to waive if needed). Since this records a % change /// between just two tokens, the corresponding % change in TWV will always be smaller, /// which makes this check safe. /// More details at https://dev.gearbox.fi/docs/documentation/risk/fast-collateral-check#fast-check-protection /// @param creditAccount Address of the Credit Account /// @param tokenIn Address of the token spent by the swap /// @param tokenOut Address of the token received from the swap /// @param balanceInBefore Balance of tokenIn before the operation /// @param balanceOutBefore Balance of tokenOut before the operation function fastCollateralCheck( address creditAccount, address tokenIn, address tokenOut, uint256 balanceInBefore, uint256 balanceOutBefore ) external; /// @dev Performs a full health check on an account, summing up /// value of all enabled collateral tokens /// @param creditAccount Address of the Credit Account to check function fullCollateralCheck(address creditAccount) external; /// @dev Checks that the number of enabled tokens on a Credit Account /// does not violate the maximal enabled token limit and tries /// to disable unused tokens if it does /// @param creditAccount Account to check enabled tokens for function checkAndOptimizeEnabledTokens(address creditAccount) external; /// @dev Disables a token on a credit account /// @notice Usually called by adapters to disable spent tokens during a multicall, /// but can also be called separately from the Credit Facade to remove /// unwanted tokens /// @return True if token mask was change otherwise False function disableToken(address creditAccount, address token) external returns (bool); // // GETTERS // /// @dev Returns the address of a borrower's Credit Account, or reverts if there is none. /// @param borrower Borrower's address function getCreditAccountOrRevert(address borrower) external view returns (address); /// @dev Computes amounts that must be sent to various addresses before closing an account /// @param totalValue Credit Accounts total value in underlying /// @param closureActionType Type of account closure /// * CLOSE_ACCOUNT: The account is healthy and is closed normally /// * LIQUIDATE_ACCOUNT: The account is unhealthy and is being liquidated to avoid bad debt /// * LIQUIDATE_EXPIRED_ACCOUNT: The account has expired and is being liquidated (lowered liquidation premium) /// * LIQUIDATE_PAUSED: The account is liquidated while the system is paused due to emergency (no liquidation premium) /// @param borrowedAmount Credit Account's debt principal /// @param borrowedAmountWithInterest Credit Account's debt principal + interest /// @return amountToPool Amount of underlying to be sent to the pool /// @return remainingFunds Amount of underlying to be sent to the borrower (only applicable to liquidations) /// @return profit Protocol's profit from fees (if any) /// @return loss Protocol's loss from bad debt (if any) function calcClosePayments( uint256 totalValue, ClosureAction closureActionType, uint256 borrowedAmount, uint256 borrowedAmountWithInterest ) external view returns ( uint256 amountToPool, uint256 remainingFunds, uint256 profit, uint256 loss ); /// @dev Calculates the debt accrued by a Credit Account /// @param creditAccount Address of the Credit Account /// @return borrowedAmount The debt principal /// @return borrowedAmountWithInterest The debt principal + accrued interest /// @return borrowedAmountWithInterestAndFees The debt principal + accrued interest and protocol fees function calcCreditAccountAccruedInterest(address creditAccount) external view returns ( uint256 borrowedAmount, uint256 borrowedAmountWithInterest, uint256 borrowedAmountWithInterestAndFees ); /// @dev Maps Credit Accounts to bit masks encoding their enabled token sets /// Only enabled tokens are counted as collateral for the Credit Account /// @notice An enabled token mask encodes an enabled token by setting /// the bit at the position equal to token's index to 1 function enabledTokensMap(address creditAccount) external view returns (uint256); /// @dev Maps the Credit Account to its current percentage drop across all swaps since /// the last full check, in RAY format function cumulativeDropAtFastCheckRAY(address creditAccount) external view returns (uint256); /// @dev Returns the collateral token at requested index and its liquidation threshold /// @param id The index of token to return function collateralTokens(uint256 id) external view returns (address token, uint16 liquidationThreshold); /// @dev Returns the collateral token with requested mask and its liquidationThreshold /// @param tokenMask Token mask corresponding to the token function collateralTokensByMask(uint256 tokenMask) external view returns (address token, uint16 liquidationThreshold); /// @dev Total number of known collateral tokens. function collateralTokensCount() external view returns (uint256); /// @dev Returns the mask for the provided token /// @param token Token to returns the mask for function tokenMasksMap(address token) external view returns (uint256); /// @dev Bit mask encoding a set of forbidden tokens function forbiddenTokenMask() external view returns (uint256); /// @dev Maps allowed adapters to their respective target contracts. function adapterToContract(address adapter) external view returns (address); /// @dev Maps 3rd party contracts to their respective adapters function contractToAdapter(address targetContract) external view returns (address); /// @dev Address of the underlying asset function underlying() external view returns (address); /// @dev Address of the connected pool function pool() external view returns (address); /// @dev Address of the connected pool /// @notice [DEPRECATED]: use pool() instead. function poolService() external view returns (address); /// @dev A map from borrower addresses to Credit Account addresses function creditAccounts(address borrower) external view returns (address); /// @dev Address of the connected Credit Configurator function creditConfigurator() external view returns (address); /// @dev Address of WETH function wethAddress() external view returns (address); /// @dev Returns the liquidation threshold for the provided token /// @param token Token to retrieve the LT for function liquidationThresholds(address token) external view returns (uint16); /// @dev The maximal number of enabled tokens on a single Credit Account function maxAllowedEnabledTokenLength() external view returns (uint8); /// @dev Maps addresses to their status as emergency liquidator. /// @notice Emergency liquidators are trusted addresses /// that are able to liquidate positions while the contracts are paused, /// e.g. when there is a risk of bad debt while an exploit is being patched. /// In the interest of fairness, emergency liquidators do not receive a premium /// And are compensated by the Gearbox DAO separately. function canLiquidateWhilePaused(address) external view returns (bool); /// @dev Returns the fee parameters of the Credit Manager /// @return feeInterest Percentage of interest taken by the protocol as profit /// @return feeLiquidation Percentage of account value taken by the protocol as profit /// during unhealthy account liquidations /// @return liquidationDiscount Multiplier that reduces the effective totalValue during unhealthy account liquidations, /// allowing the liquidator to take the unaccounted for remainder as premium. Equal to (1 - liquidationPremium) /// @return feeLiquidationExpired Percentage of account value taken by the protocol as profit /// during expired account liquidations /// @return liquidationDiscountExpired Multiplier that reduces the effective totalValue during expired account liquidations, /// allowing the liquidator to take the unaccounted for remainder as premium. Equal to (1 - liquidationPremiumExpired) function fees() external view returns ( uint16 feeInterest, uint16 feeLiquidation, uint16 liquidationDiscount, uint16 feeLiquidationExpired, uint16 liquidationDiscountExpired ); /// @dev Address of the connected Credit Facade function creditFacade() external view returns (address); /// @dev Address of the connected Price Oracle function priceOracle() external view returns (IPriceOracleV2); /// @dev Address of the universal adapter function universalAdapter() external view returns (address); /// @dev Contract's version function version() external view returns (uint256); /// @dev Paused() state function checkEmergencyPausable(address caller, bool state) external returns (bool); }
// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { IVersion } from "./IVersion.sol"; interface IPriceOracleV2Events { /// @dev Emits when a new price feed is added event NewPriceFeed(address indexed token, address indexed priceFeed); } interface IPriceOracleV2Exceptions { /// @dev Thrown if a price feed returns 0 error ZeroPriceException(); /// @dev Thrown if the last recorded result was not updated in the last round error ChainPriceStaleException(); /// @dev Thrown on attempting to get a result for a token that does not have a price feed error PriceOracleNotExistsException(); } /// @title Price oracle interface interface IPriceOracleV2 is IPriceOracleV2Events, IPriceOracleV2Exceptions, IVersion { /// @dev Converts a quantity of an asset to USD (decimals = 8). /// @param amount Amount to convert /// @param token Address of the token to be converted function convertToUSD(uint256 amount, address token) external view returns (uint256); /// @dev Converts a quantity of USD (decimals = 8) to an equivalent amount of an asset /// @param amount Amount to convert /// @param token Address of the token converted to function convertFromUSD(uint256 amount, address token) external view returns (uint256); /// @dev Converts one asset into another /// /// @param amount Amount to convert /// @param tokenFrom Address of the token to convert from /// @param tokenTo Address of the token to convert to function convert( uint256 amount, address tokenFrom, address tokenTo ) external view returns (uint256); /// @dev Returns collateral values for two tokens, required for a fast check /// @param amountFrom Amount of the outbound token /// @param tokenFrom Address of the outbound token /// @param amountTo Amount of the inbound token /// @param tokenTo Address of the inbound token /// @return collateralFrom Value of the outbound token amount in USD /// @return collateralTo Value of the inbound token amount in USD function fastCheck( uint256 amountFrom, address tokenFrom, uint256 amountTo, address tokenTo ) external view returns (uint256 collateralFrom, uint256 collateralTo); /// @dev Returns token's price in USD (8 decimals) /// @param token The token to compute the price for function getPrice(address token) external view returns (uint256); /// @dev Returns the price feed address for the passed token /// @param token Token to get the price feed for function priceFeeds(address token) external view returns (address priceFeed); /// @dev Returns the price feed for the passed token, /// with additional parameters /// @param token Token to get the price feed for function priceFeedsWithFlags(address token) external view returns ( address priceFeed, bool skipCheck, uint256 decimals ); } interface IPriceOracleV2Ext is IPriceOracleV2 { /// @dev Sets a price feed if it doesn't exist, or updates an existing one /// @param token Address of the token to set the price feed for /// @param priceFeed Address of a USD price feed adhering to Chainlink's interface function addPriceFeed(address token, address priceFeed) external; }
// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; /// @title IVersion /// @dev Declares a version function which returns the contract's version interface IVersion { /// @dev Returns contract version function version() external view returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external view returns (address); function WETH() external view returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountToken, uint256 amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETHWithPermit( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external view returns (uint256 amountB); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external view returns (uint256 amountOut); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external view returns (uint256 amountIn); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_creditManager","type":"address"},{"internalType":"address","name":"_router","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotImplementedException","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"TokenIsNotInAllowedList","type":"error"},{"inputs":[],"name":"ZeroAddressException","type":"error"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_gearboxAdapterType","outputs":[{"internalType":"enum AdapterType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_gearboxAdapterVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"creditFacade","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creditManager","outputs":[{"internalType":"contract ICreditManagerV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"rateMinRAY","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapAllTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"targetContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b506040516200247f3803806200247f833981016040819052620000349162000121565b81816001600160a01b03821615806200005457506001600160a01b038116155b156200007357604051635919af9760e11b815260040160405180910390fd5b6001600160a01b038216608081905260408051632f7a188160e01b81529051632f7a1881916004808201926020929091908290030181865afa158015620000be573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e4919062000159565b6001600160a01b0390811660a0521660c05250506001600055506200017e565b80516001600160a01b03811681146200011c57600080fd5b919050565b600080604083850312156200013557600080fd5b620001408362000104565b9150620001506020840162000104565b90509250929050565b6000602082840312156200016c57600080fd5b620001778262000104565b9392505050565b60805160a05160c05161224c620002336000396000818161045e015281816106040152818161070101528181610aa401528181610c9c01528181610d6e015281816110dd01528181611186015281816113fb01526115190152600081816102b40152818161121301526115c80152600081816104b20152818161084601528181610b8c01528181610e56015281816113cc01528181611550015281816116500152818161170401526117c0015261224c6000f3fe6080604052600436106101cd5760003560e01c8063ad5c4648116100f7578063c12c21c011610095578063ded9382a11610064578063ded9382a1461052b578063e8e3370014610546578063f305d71914610581578063fb3bdb411461038557600080fd5b8063c12c21c0146104a0578063c45a0155146104d4578063ce30bbdb146104e9578063d06ca61f1461050b57600080fd5b8063b6f9de95116100d1578063b6f9de9514610423578063baa2abde14610431578063bd90df701461044c578063bdbeaa311461048057600080fd5b8063ad5c4648146103d3578063ad615dec146103e8578063af2979eb1461040857600080fd5b80634a25d94a1161016f578063791ac9471161013e578063791ac9471461033b5780637ff36ab51461038557806385f8c259146103935780638803dbee146103b357600080fd5b80634a25d94a1461023a5780635b0d59841461031b5780635c11d7951461033b57806378aa73a41461035d57600080fd5b80631f00ca74116101ab5780631f00ca74146102675780632195995c146102875780632f7a1881146102a257806338ed1739146102fb57600080fd5b806302751cec146101d2578063054d50d41461020c57806318cbafe51461023a575b600080fd5b3480156101de57600080fd5b506101f26101ed366004611849565b61058f565b604080519283526020830191909152015b60405180910390f35b34801561021857600080fd5b5061022c6102273660046118a7565b6105c4565b604051908152602001610203565b34801561024657600080fd5b5061025a61025536600461191f565b61068d565b6040516102039190611992565b34801561027357600080fd5b5061025a6102823660046119d6565b6106c1565b34801561029357600080fd5b506101f26101ed366004611a46565b3480156102ae57600080fd5b506102d67f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b34801561030757600080fd5b5061025a61031636600461191f565b61079d565b34801561032757600080fd5b5061022c610336366004611af0565b6109fe565b34801561034757600080fd5b5061035b61035636600461191f565b610a32565b005b34801561036957600080fd5b50610372600281565b60405161ffff9091168152602001610203565b61025a610255366004611b86565b34801561039f57600080fd5b5061022c6103ae3660046118a7565b610a64565b3480156103bf57600080fd5b5061025a6103ce36600461191f565b610ae8565b3480156103df57600080fd5b506102d6610c98565b3480156103f457600080fd5b5061022c6104033660046118a7565b610d2e565b34801561041457600080fd5b5061022c610336366004611849565b61035b610356366004611b86565b34801561043d57600080fd5b506101f26101ed366004611bed565b34801561045857600080fd5b506102d67f000000000000000000000000000000000000000000000000000000000000000081565b34801561048c57600080fd5b5061025a61049b366004611c5f565b610db2565b3480156104ac57600080fd5b506102d67f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e057600080fd5b506102d66110d9565b3480156104f557600080fd5b506104fe600181565b6040516102039190611cb2565b34801561051757600080fd5b5061025a6105263660046119d6565b611146565b34801561053757600080fd5b506101f26101ed366004611af0565b34801561055257600080fd5b50610566610561366004611cf3565b6111bf565b60408051938452602084019290925290820152606001610203565b610566610561366004611849565b6000806040517f24e46f7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f054d50d40000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063054d50d4906064015b602060405180830381865afa158015610661573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106859190611d6f565b949350505050565b60606040517f24e46f7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f1f00ca7400000000000000000000000000000000000000000000000000000000815260609073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690631f00ca749061073a90879087908790600401611dde565b600060405180830381865afa158015610757573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106859190810190611e7f565b606060026000541415610811576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260009081556040517fe958b7040000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e958b70490602401602060405180830381865afa1580156108a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c69190611f25565b90506000868660008181106108dd576108dd611f49565b90506020020160208101906108f29190611f78565b905060008787610903600182611fc4565b81811061091257610912611f49565b90506020020160208101906109279190611f78565b90506109d88383836338ed173960e01b8e8e8e8e8b8e60405160240161095296959493929190611fdb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600160006111f6565b8060200190518101906109eb9190611e7f565b60016000559a9950505050505050505050565b60006040517f24e46f7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f24e46f7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f85f8c2590000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906385f8c25990606401610644565b606060026000541415610b57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610808565b600260009081556040517fe958b7040000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e958b70490602401602060405180830381865afa158015610be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0c9190611f25565b9050600086866000818110610c2357610c23611f49565b9050602002016020810190610c389190611f78565b905060008787610c49600182611fc4565b818110610c5857610c58611f49565b9050602002016020810190610c6d9190611f78565b90506109d8838383638803dbee60e01b8e8e8e8e8b8e60405160240161095296959493929190611fdb565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d299190611f25565b905090565b6040517fad615dec0000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063ad615dec90606401610644565b606060026000541415610e21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610808565b600260009081556040517fe958b7040000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063e958b70490602401602060405180830381865afa158015610eb2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed69190611f25565b9050600085856000818110610eed57610eed611f49565b9050602002016020810190610f029190611f78565b905060008686610f13600182611fc4565b818110610f2257610f22611f49565b9050602002016020810190610f379190611f78565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301529192506000918416906370a0823190602401602060405180830381865afa158015610fa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcd9190611d6f565b905060018111156110c7578080600190039150506110b18484846338ed173960e01b856b033b2e3c9fd0803ce80000008f886110099190612026565b6110139190612063565b8e8e8c8f60405160240161102c96959493929190611fdb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001806111f6565b8060200190518101906110c49190611e7f565b94505b50506001600055509095945050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d05573d6000803e3d6000fd5b6040517fd06ca61f00000000000000000000000000000000000000000000000000000000815260609073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063d06ca61f9061073a90879087908790600401611dde565b60008060006040517f24e46f7000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60606000803373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461135f576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301528916906370a0823190602401602060405180830381865afa1580156112a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c89190611d6f565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152919350908816906370a0823190602401602060405180830381865afa158015611338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061135c9190611d6f565b90505b841561138f5761138f887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6114d6565b6040517f6ce4074a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690636ce4074a906114259033907f0000000000000000000000000000000000000000000000000000000000000000908b906004016120ce565b6000604051808303816000875af1158015611444573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261148a9190810190612147565b925084156114bc576114bc887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6114d6565b6114ca8989898585896115b0565b50509695505050505050565b6040517f46fb371d00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248301528381166044830152606482018390527f000000000000000000000000000000000000000000000000000000000000000016906346fb371d90608401600060405180830381600087803b15801561159457600080fd5b505af11580156115a8573d6000803e3d6000fd5b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146116b1576040517f654a9eda00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152858116604483015260648201859052608482018490527f0000000000000000000000000000000000000000000000000000000000000000169063654a9eda9060a401600060405180830381600087803b15801561169457600080fd5b505af11580156116a8573d6000803e3d6000fd5b505050506115a8565b8015611773576040517f0d8f9cee00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015286811660248301527f00000000000000000000000000000000000000000000000000000000000000001690630d8f9cee906044016020604051808303816000875af115801561174d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177191906121f9565b505b6040517f51e3f16000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015285811660248301527f000000000000000000000000000000000000000000000000000000000000000016906351e3f16090604401600060405180830381600087803b15801561180457600080fd5b505af1158015611818573d6000803e3d6000fd5b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461184657600080fd5b50565b60008060008060008060c0878903121561186257600080fd5b863561186d81611824565b9550602087013594506040870135935060608701359250608087013561189281611824565b8092505060a087013590509295509295509295565b6000806000606084860312156118bc57600080fd5b505081359360208301359350604090920135919050565b60008083601f8401126118e557600080fd5b50813567ffffffffffffffff8111156118fd57600080fd5b6020830191508360208260051b850101111561191857600080fd5b9250929050565b60008060008060008060a0878903121561193857600080fd5b8635955060208701359450604087013567ffffffffffffffff81111561195d57600080fd5b61196989828a016118d3565b909550935050606087013561197d81611824565b80925050608087013590509295509295509295565b6020808252825182820181905260009190848201906040850190845b818110156119ca578351835292840192918401916001016119ae565b50909695505050505050565b6000806000604084860312156119eb57600080fd5b83359250602084013567ffffffffffffffff811115611a0957600080fd5b611a15868287016118d3565b9497909650939450505050565b801515811461184657600080fd5b803560ff81168114611a4157600080fd5b919050565b60008060008060008060008060008060006101608c8e031215611a6857600080fd5b8b35611a7381611824565b9a5060208c0135611a8381611824565b995060408c0135985060608c0135975060808c0135965060a08c0135611aa881611824565b955060c08c0135945060e08c0135611abf81611a22565b9350611ace6101008d01611a30565b92506101208c013591506101408c013590509295989b509295989b9093969950565b6000806000806000806000806000806101408b8d031215611b1057600080fd5b8a35611b1b81611824565b995060208b0135985060408b0135975060608b0135965060808b0135611b4081611824565b955060a08b0135945060c08b0135611b5781611a22565b9350611b6560e08c01611a30565b92506101008b013591506101208b013590509295989b9194979a5092959850565b600080600080600060808688031215611b9e57600080fd5b85359450602086013567ffffffffffffffff811115611bbc57600080fd5b611bc8888289016118d3565b9095509350506040860135611bdc81611824565b949793965091946060013592915050565b600080600080600080600060e0888a031215611c0857600080fd5b8735611c1381611824565b96506020880135611c2381611824565b955060408801359450606088013593506080880135925060a0880135611c4881611824565b8092505060c0880135905092959891949750929550565b60008060008060608587031215611c7557600080fd5b84359350602085013567ffffffffffffffff811115611c9357600080fd5b611c9f878288016118d3565b9598909750949560400135949350505050565b6020810160108310611ced577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b600080600080600080600080610100898b031215611d1057600080fd5b8835611d1b81611824565b97506020890135611d2b81611824565b965060408901359550606089013594506080890135935060a0890135925060c0890135611d5781611824565b8092505060e089013590509295985092959890939650565b600060208284031215611d8157600080fd5b5051919050565b8183526000602080850194508260005b85811015611dd3578135611dab81611824565b73ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611d98565b509495945050505050565b838152604060208201526000611df8604083018486611d88565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e7757611e77611e01565b604052919050565b60006020808385031215611e9257600080fd5b825167ffffffffffffffff80821115611eaa57600080fd5b818501915085601f830112611ebe57600080fd5b815181811115611ed057611ed0611e01565b8060051b9150611ee1848301611e30565b8181529183018401918481019088841115611efb57600080fd5b938501935b83851015611f1957845182529385019390850190611f00565b98975050505050505050565b600060208284031215611f3757600080fd5b8151611f4281611824565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215611f8a57600080fd5b8135611f4281611824565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611fd657611fd6611f95565b500390565b86815285602082015260a060408201526000611ffb60a083018688611d88565b73ffffffffffffffffffffffffffffffffffffffff9490941660608301525060800152949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561205e5761205e611f95565b500290565b600082612099577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60005b838110156120b95781810151838201526020016120a1565b838111156120c8576000848401525b50505050565b600073ffffffffffffffffffffffffffffffffffffffff808616835280851660208401525060606040830152825180606084015261211381608085016020870161209e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691909101608001949350505050565b60006020828403121561215957600080fd5b815167ffffffffffffffff8082111561217157600080fd5b818401915084601f83011261218557600080fd5b81518181111561219757612197611e01565b6121c860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611e30565b91508082528560208285010111156121df57600080fd5b6121f081602084016020860161209e565b50949350505050565b60006020828403121561220b57600080fd5b8151611f4281611a2256fea2646970667358221220ba3e37cd13ac26134b2cee5f3408d6779dc5adf560696043529a0c038dcade4a64736f6c634300080a003300000000000000000000000095357303f995e184a7998da6c6ea35cc728a19000000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
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.