Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
||||
---|---|---|---|---|---|---|---|
21883463 | 32 hrs ago | 0 ETH | |||||
21883463 | 32 hrs ago | 0 ETH | |||||
21883463 | 32 hrs ago | 0 ETH | |||||
21883463 | 32 hrs ago | 0 ETH | |||||
21883463 | 32 hrs ago | 0 ETH | |||||
21883463 | 32 hrs ago | 0 ETH | |||||
21881147 | 40 hrs ago | 0 ETH | |||||
21881147 | 40 hrs ago | 0 ETH | |||||
21881147 | 40 hrs ago | 0 ETH | |||||
21881147 | 40 hrs ago | 0 ETH | |||||
21881147 | 40 hrs ago | 0 ETH | |||||
21881147 | 40 hrs ago | 0 ETH | |||||
21862840 | 4 days ago | 0 ETH | |||||
21862840 | 4 days ago | 0 ETH | |||||
21862840 | 4 days ago | 0 ETH | |||||
21862840 | 4 days ago | 0 ETH | |||||
21862840 | 4 days ago | 0 ETH | |||||
21862840 | 4 days ago | 0 ETH | |||||
21862808 | 4 days ago | 0 ETH | |||||
21862808 | 4 days ago | 0 ETH | |||||
21862808 | 4 days ago | 0 ETH | |||||
21862808 | 4 days ago | 0 ETH | |||||
21862808 | 4 days ago | 0 ETH | |||||
21862808 | 4 days ago | 0 ETH | |||||
21859308 | 4 days ago | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Flashlender
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 100 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IFlashlender, IERC3156FlashBorrower, ICreditFlashBorrower} from "./interfaces/IFlashlender.sol"; import {IPoolV3} from "./interfaces/IPoolV3.sol"; import {wmul, wdiv, WAD} from "./utils/Math.sol"; /// @title Flashlender /// @notice `Flashlender` enables flashlender minting / borrowing of Stablecoin and internal Credit /// Uses DssFlash.sol from DSS (MakerDAO) as a blueprint contract Flashlender is IFlashlender, ReentrancyGuard { /*////////////////////////////////////////////////////////////// CONSTANTS //////////////////////////////////////////////////////////////*/ // ERC3156 Callbacks bytes32 public constant CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan"); bytes32 public constant CALLBACK_SUCCESS_CREDIT = keccak256("CreditFlashBorrower.onCreditFlashLoan"); /// @notice The Pool contract IPoolV3 public immutable pool; /// @notice The flash loan fee, where WAD is 100% uint256 public immutable protocolFee; /// @notice The underlying token IERC20 public immutable underlyingToken; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event FlashLoan(address indexed receiver, address token, uint256 amount, uint256 fee); event CreditFlashLoan(address indexed receiver, uint256 amount, uint256 fee); /*////////////////////////////////////////////////////////////// ERRORS //////////////////////////////////////////////////////////////*/ error Flash__flashFee_unsupportedToken(); error Flash__flashLoan_callbackFailed(); error Flash__creditFlashLoan_callbackFailed(); error Flash__creditFlashLoan_unsupportedToken(); /*////////////////////////////////////////////////////////////// INITIALIZATION //////////////////////////////////////////////////////////////*/ constructor(IPoolV3 pool_, uint256 protocolFee_) { pool = pool_; underlyingToken = IERC20(pool.underlyingToken()); protocolFee = protocolFee_; } /*////////////////////////////////////////////////////////////// FLASHLOAN //////////////////////////////////////////////////////////////*/ /// @notice Returns the maximum borrowable amount for `token` /// @dev If `token` is not Stablecoin then 0 is returned /// @param token Address of the token to borrow (has to be the address of Stablecoin) /// @return max maximum borrowable amount [wad] function maxFlashLoan(address token) external view override returns (uint256 max) { if (token == address(underlyingToken)) { max = wdiv(pool.creditManagerBorrowable(address(this)), WAD + protocolFee); } } /// @notice Returns the current borrow fee for borrowing `amount` of `token` /// @dev If `token` is not Stablecoin then this method will revert /// @param token Address of the token to borrow (has to be the address of Stablecoin) /// @param *amount Amount to borrow [wad] /// @return fee to borrow `amount` of `token` function flashFee(address token, uint256 amount) external view override returns (uint256) { if (token != address(underlyingToken)) revert Flash__flashFee_unsupportedToken(); return wmul(amount, protocolFee); } /// @notice Flashlender lends `token` to `receiver` /// @dev Reverts if `Flashlender` gets reentered in the same transaction or if token is not Stablecoin /// @param receiver Address of the receiver of the flash loan /// @param token Address of the token to borrow (has to be the address of Stablecoin) /// @param amount Amount of `token` to borrow [wad] /// @param data Arbitrary data structure, intended to contain user-defined parameters /// @return true if flash loan function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external override nonReentrant returns (bool) { uint256 fee = wmul(amount, protocolFee); uint256 total = amount + fee; pool.lendCreditAccount(amount, address(receiver)); emit FlashLoan(address(receiver), token, amount, fee); if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS) revert Flash__flashLoan_callbackFailed(); // reverts if not enough Stablecoin have been send back underlyingToken.transferFrom(address(receiver), address(pool), total); pool.repayCreditAccount(total - fee, 0, 0); pool.mintProfit(fee); return true; } /// @notice Flashlender lends ICreditFlashBorrower Credit to `receiver` /// @dev Reverts if `Flashlender` gets reentered in the same transaction /// @param receiver Address of the receiver of the flash loan [ICreditFlashBorrower] /// @param amount Amount of `token` to borrow [wad] /// @param data Arbitrary data structure, intended to contain user-defined parameters /// @return true if flash loan function creditFlashLoan( ICreditFlashBorrower receiver, uint256 amount, bytes calldata data ) external override nonReentrant returns (bool) { uint256 fee = wmul(amount, protocolFee); uint256 total = amount + fee; pool.lendCreditAccount(amount, address(receiver)); emit CreditFlashLoan(address(receiver), amount, fee); if (receiver.onCreditFlashLoan(msg.sender, amount, fee, data) != CALLBACK_SUCCESS_CREDIT) revert Flash__creditFlashLoan_callbackFailed(); // reverts if not enough Stablecoin have been send back underlyingToken.transferFrom(address(receiver), address(pool), total); pool.repayCreditAccount(total - fee, 0, 0); pool.mintProfit(fee); return true; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.19; import {IPoolV3} from "./IPoolV3.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IERC3156FlashBorrower { /// @dev Receive `amount` of `token` from the flash lender /// @param initiator The initiator of the loan /// @param token The loan currency /// @param amount The amount of tokens lent /// @param fee The additional amount of tokens to repay /// @param data Arbitrary data structure, intended to contain user-defined parameters /// @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan" function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); } interface IERC3156FlashLender { /// @dev The amount of currency available to be lent /// @param token The loan currency /// @return The amount of `token` that can be borrowed function maxFlashLoan(address token) external view returns (uint256); /// @dev The fee to be charged for a given loan /// @param token The loan currency /// @param amount The amount of tokens lent /// @return The amount of `token` to be charged for the loan, on top of the returned principal function flashFee(address token, uint256 amount) external view returns (uint256); /// @dev Initiate a flash loan /// @param receiver The receiver of the tokens in the loan, and the receiver of the callback /// @param token The loan currency /// @param amount The amount of tokens lent /// @param data Arbitrary data structure, intended to contain user-defined parameters function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); } interface ICreditFlashBorrower { /// @dev Receives `amount` of internal Credit from the Credit flash lender /// @param initiator The initiator of the loan /// @param amount The amount of tokens lent [wad] /// @param fee The additional amount of tokens to repay [wad] /// @param data Arbitrary data structure, intended to contain user-defined parameters. /// @return The keccak256 hash of "ICreditFlashLoanReceiver.onCreditFlashLoan" function onCreditFlashLoan( address initiator, uint256 amount, uint256 fee, bytes calldata data ) external returns (bytes32); } interface ICreditFlashLender { /// @notice Flashlender lends internal Credit to `receiver` /// @dev Reverts if `Flashlender` gets reentered in the same transaction /// @param receiver Address of the receiver of the flash loan [ICreditFlashBorrower] /// @param amount Amount of `token` to borrow [wad] /// @param data Arbitrary data structure, intended to contain user-defined parameters /// @return true if flash loan function creditFlashLoan( ICreditFlashBorrower receiver, uint256 amount, bytes calldata data ) external returns (bool); } interface IFlashlender is IERC3156FlashLender, ICreditFlashLender { function pool() external view returns (IPoolV3); function underlyingToken() external view returns (IERC20); function CALLBACK_SUCCESS() external view returns (bytes32); function CALLBACK_SUCCESS_CREDIT() external view returns (bytes32); function maxFlashLoan(address token) external view override returns (uint256); function flashFee(address token, uint256 amount) external view override returns (uint256); function flashLoan( IERC3156FlashBorrower receiver, address token, uint256 amount, bytes calldata data ) external returns (bool); function creditFlashLoan( ICreditFlashBorrower receiver, uint256 amount, bytes calldata data ) external returns (bool); } abstract contract FlashLoanReceiverBase is ICreditFlashBorrower, IERC3156FlashBorrower { IFlashlender public immutable flashlender; bytes32 public constant CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan"); bytes32 public constant CALLBACK_SUCCESS_CREDIT = keccak256("CreditFlashBorrower.onCreditFlashLoan"); constructor(address flashlender_) { flashlender = IFlashlender(flashlender_); } function approvePayback(uint256 amount) internal { // Lender takes back the Stablecoin as per ERC3156 spec flashlender.underlyingToken().approve(address(flashlender), amount); } }
// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Foundation, 2023. pragma solidity ^0.8.17; pragma abicoder v1; import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol"; import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; import {IVersion} from "@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol"; interface IPoolV3Events { /// @notice Emitted when depositing liquidity with referral code event Refer(address indexed onBehalfOf, uint256 indexed referralCode, uint256 amount); /// @notice Emitted when credit account borrows funds from the pool event Borrow(address indexed creditManager, address indexed creditAccount, uint256 amount); /// @notice Emitted when credit account's debt is repaid to the pool event Repay(address indexed creditManager, uint256 borrowedAmount, uint256 profit, uint256 loss); /// @notice Emitted when incurred loss can't be fully covered by burning treasury's shares event IncurUncoveredLoss(address indexed creditManager, uint256 loss); /// @notice Emitted when new interest rate model contract is set event SetInterestRateModel(address indexed newInterestRateModel); /// @notice Emitted when new pool quota keeper contract is set event SetPoolQuotaKeeper(address indexed newPoolQuotaKeeper); /// @notice Emitted when new total debt limit is set event SetTotalDebtLimit(uint256 limit); /// @notice Emitted when new credit manager is connected to the pool event AddCreditManager(address indexed creditManager); /// @notice Emitted when new debt limit is set for a credit manager event SetCreditManagerDebtLimit(address indexed creditManager, uint256 newLimit); /// @notice Emitted when new withdrawal fee is set event SetWithdrawFee(uint256 fee); } /// @title Pool V3 interface interface IPoolV3 is IVersion, IPoolV3Events, IERC4626, IERC20Permit { function addressProvider() external view returns (address); function underlyingToken() external view returns (address); function treasury() external view returns (address); function withdrawFee() external view returns (uint16); function creditManagers() external view returns (address[] memory); function availableLiquidity() external view returns (uint256); function expectedLiquidity() external view returns (uint256); function expectedLiquidityLU() external view returns (uint256); // ---------------- // // ERC-4626 LENDING // // ---------------- // function depositWithReferral( uint256 assets, address receiver, uint256 referralCode ) external returns (uint256 shares); function mintWithReferral(uint256 shares, address receiver, uint256 referralCode) external returns (uint256 assets); // --------- // // BORROWING // // --------- // function totalBorrowed() external view returns (uint256); function totalDebtLimit() external view returns (uint256); function creditManagerBorrowed(address creditManager) external view returns (uint256); function creditManagerDebtLimit(address creditManager) external view returns (uint256); function creditManagerBorrowable(address creditManager) external view returns (uint256 borrowable); function lendCreditAccount(uint256 borrowedAmount, address creditAccount) external; function repayCreditAccount(uint256 repaidAmount, uint256 profit, uint256 loss) external; // ------------- // // INTEREST RATE // // ------------- // function interestRateModel() external view returns (address); function baseInterestRate() external view returns (uint256); function supplyRate() external view returns (uint256); function baseInterestIndex() external view returns (uint256); function baseInterestIndexLU() external view returns (uint256); function lastBaseInterestUpdate() external view returns (uint40); // ------ // // QUOTAS // // ------ // function poolQuotaKeeper() external view returns (address); function quotaRevenue() external view returns (uint256); function lastQuotaRevenueUpdate() external view returns (uint40); function updateQuotaRevenue(int256 quotaRevenueDelta) external; function setQuotaRevenue(uint256 newQuotaRevenue) external; // ------------- // // CONFIGURATION // // ------------- // function setInterestRateModel(address newInterestRateModel) external; function setPoolQuotaKeeper(address newPoolQuotaKeeper) external; function setTreasury(address treasury_) external; function setTotalDebtLimit(uint256 newLimit) external; function setCreditManagerDebtLimit(address creditManager, uint256 newLimit) external; function setWithdrawFee(uint256 newWithdrawFee) external; function mintProfit(uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; /* solhint-disable func-visibility, no-inline-assembly */ error Math__toInt256_overflow(); error Math__toUint64_overflow(); error Math__add_overflow_signed(); error Math__sub_overflow_signed(); error Math__mul_overflow_signed(); error Math__mul_overflow(); error Math__div_overflow(); uint256 constant WAD = 1e18; /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/SafeCastLib.sol#L367 function toInt256(uint256 x) pure returns (int256) { if (x >= 1 << 255) revert Math__toInt256_overflow(); return int256(x); } /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/SafeCastLib.sol#L53 function toUint64(uint256 x) pure returns (uint64) { if (x >= 1 << 64) revert Math__toUint64_overflow(); return uint64(x); } /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/FixedPointMathLib.sol#L602 function abs(int256 x) pure returns (uint256 z) { assembly ("memory-safe") { let mask := sub(0, shr(255, x)) z := xor(mask, add(mask, x)) } } /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/FixedPointMathLib.sol#L620 function min(uint256 x, uint256 y) pure returns (uint256 z) { assembly ("memory-safe") { z := xor(x, mul(xor(x, y), lt(y, x))) } } /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/FixedPointMathLib.sol#L628 function min(int256 x, int256 y) pure returns (int256 z) { assembly ("memory-safe") { z := xor(x, mul(xor(x, y), slt(y, x))) } } /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/FixedPointMathLib.sol#L636 function max(uint256 x, uint256 y) pure returns (uint256 z) { assembly ("memory-safe") { z := xor(x, mul(xor(x, y), gt(y, x))) } } /// @dev Taken from https://github.com/makerdao/dss/blob/fa4f6630afb0624d04a003e920b0d71a00331d98/src/vat.sol#L74 function add(uint256 x, int256 y) pure returns (uint256 z) { assembly ("memory-safe") { z := add(x, y) } if ((y > 0 && z < x) || (y < 0 && z > x)) revert Math__add_overflow_signed(); } /// @dev Taken from https://github.com/makerdao/dss/blob/fa4f6630afb0624d04a003e920b0d71a00331d98/src/vat.sol#L79 function sub(uint256 x, int256 y) pure returns (uint256 z) { assembly ("memory-safe") { z := sub(x, y) } if ((y > 0 && z > x) || (y < 0 && z < x)) revert Math__sub_overflow_signed(); } /// @dev Taken from https://github.com/makerdao/dss/blob/fa4f6630afb0624d04a003e920b0d71a00331d98/src/vat.sol#L84 function mul(uint256 x, int256 y) pure returns (int256 z) { unchecked { z = int256(x) * y; if (int256(x) < 0 || (y != 0 && z / y != int256(x))) revert Math__mul_overflow_signed(); } } /// @dev Equivalent to `(x * y) / WAD` rounded down. /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/FixedPointMathLib.sol#L54 function wmul(uint256 x, uint256 y) pure returns (uint256 z) { assembly ("memory-safe") { // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`. if mul(y, gt(x, div(not(0), y))) { // Store the function selector of `Math__mul_overflow()`. mstore(0x00, 0xc4c5d7f5) // Revert with (offset, size). revert(0x1c, 0x04) } z := div(mul(x, y), WAD) } } function wmul(uint256 x, int256 y) pure returns (int256 z) { unchecked { z = mul(x, y) / int256(WAD); } } /// @dev Equivalent to `(x * y) / WAD` rounded up. /// @dev Taken from https://github.com/Vectorized/solady/blob/969a78905274b32cdb7907398c443f7ea212e4f4/src/utils/FixedPointMathLib.sol#L69C22-L69C22 function wmulUp(uint256 x, uint256 y) pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`. if mul(y, gt(x, div(not(0), y))) { // Store the function selector of `Math__mul_overflow()`. mstore(0x00, 0xc4c5d7f5) // Revert with (offset, size). revert(0x1c, 0x04) } z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD)) } } /// @dev Equivalent to `(x * WAD) / y` rounded down. /// @dev Taken from https://github.com/Vectorized/solady/blob/6d706e05ef43cbed234c648f83c55f3a4bb0a520/src/utils/FixedPointMathLib.sol#L84 function wdiv(uint256 x, uint256 y) pure returns (uint256 z) { assembly ("memory-safe") { // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`. if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) { // Store the function selector of `Math__div_overflow()`. mstore(0x00, 0xbcbede65) // Revert with (offset, size). revert(0x1c, 0x04) } z := div(mul(x, WAD), y) } } /// @dev Equivalent to `(x * WAD) / y` rounded up. /// @dev Taken from https://github.com/Vectorized/solady/blob/969a78905274b32cdb7907398c443f7ea212e4f4/src/utils/FixedPointMathLib.sol#L99 function wdivUp(uint256 x, uint256 y) pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`. if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) { // Store the function selector of `Math__div_overflow()`. mstore(0x00, 0xbcbede65) // Revert with (offset, size). revert(0x1c, 0x04) } z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y)) } } /// @dev Taken from https://github.com/makerdao/dss/blob/fa4f6630afb0624d04a003e920b0d71a00331d98/src/jug.sol#L62 function wpow(uint256 x, uint256 n, uint256 b) pure returns (uint256 z) { unchecked { assembly ("memory-safe") { switch n case 0 { z := b } default { switch x case 0 { z := 0 } default { switch mod(n, 2) case 0 { z := b } default { z := x } let half := div(b, 2) // for rounding. for { n := div(n, 2) } n { n := div(n, 2) } { let xx := mul(x, x) if shr(128, x) { revert(0, 0) } let xxRound := add(xx, half) if lt(xxRound, xx) { revert(0, 0) } x := div(xxRound, b) if mod(n, 2) { let zx := mul(z, x) if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) } let zxRound := add(zx, half) if lt(zxRound, zx) { revert(0, 0) } z := div(zxRound, b) } } } } } } } /// @dev Taken from https://github.com/Vectorized/solady/blob/cde0a5fb594da8655ba6bfcdc2e40a7c870c0cc0/src/utils/FixedPointMathLib.sol#L110 /// @dev Equivalent to `x` to the power of `y`. /// because `x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)`. function wpow(int256 x, int256 y) pure returns (int256) { // Using `ln(x)` means `x` must be greater than 0. return wexp((wln(x) * y) / int256(WAD)); } /// @dev Taken from https://github.com/Vectorized/solady/blob/cde0a5fb594da8655ba6bfcdc2e40a7c870c0cc0/src/utils/FixedPointMathLib.sol#L116 /// @dev Returns `exp(x)`, denominated in `WAD`. function wexp(int256 x) pure returns (int256 r) { unchecked { // When the result is < 0.5 we return zero. This happens when // x <= floor(log(0.5e18) * 1e18) ~ -42e18 if (x <= -42139678854452767551) return r; /// @solidity memory-safe-assembly assembly { // When the result is > (2**255 - 1) / 1e18 we can not represent it as an // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. if iszero(slt(x, 135305999368893231589)) { mstore(0x00, 0xa37bfec9) // `ExpOverflow()`. revert(0x1c, 0x04) } } // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 // for more intermediate precision and a binary basis. This base conversion // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. x = (x << 78) / 5 ** 18; // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers // of two such that exp(x) = exp(x') * 2**k, where k is an integer. // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >> 96; x = x - k * 54916777467707473351141471128; // k is in the range [-61, 195]. // Evaluate using a (6, 7)-term rational approximation. // p is made monic, we'll multiply by a scale factor later. int256 y = x + 1346386616545796478920950773328; y = ((y * x) >> 96) + 57155421227552351082224309758442; int256 p = y + x - 94201549194550492254356042504812; p = ((p * y) >> 96) + 28719021644029726153956944680412240; p = p * x + (4385272521454847904659076985693276 << 96); // We leave p in 2**192 basis so we don't need to scale it back up for the division. int256 q = x - 2855989394907223263936484059900; q = ((q * x) >> 96) + 50020603652535783019961831881945; q = ((q * x) >> 96) - 533845033583426703283633433725380; q = ((q * x) >> 96) + 3604857256930695427073651918091429; q = ((q * x) >> 96) - 14423608567350463180887372962807573; q = ((q * x) >> 96) + 26449188498355588339934803723976023; /// @solidity memory-safe-assembly assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial won't have zeros in the domain as all its roots are complex. // No scaling is necessary because p is already 2**96 too large. r := sdiv(p, q) } // r should be in the range (0.09, 0.25) * 2**96. // We now need to multiply r by: // * the scale factor s = ~6.031367120. // * the 2**k factor from the range reduction. // * the 1e18 / 2**96 factor for base conversion. // We do this all at once, with an intermediate result in 2**213 // basis, so the final right shift is always by a positive amount. r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)); } } /// @dev Taken from https://github.com/Vectorized/solady/blob/cde0a5fb594da8655ba6bfcdc2e40a7c870c0cc0/src/utils/FixedPointMathLib.sol#L184 /// @dev Returns `ln(x)`, denominated in `WAD`. function wln(int256 x) pure returns (int256 r) { unchecked { /// @solidity memory-safe-assembly assembly { if iszero(sgt(x, 0)) { mstore(0x00, 0x1615e638) // `LnWadUndefined()`. revert(0x1c, 0x04) } } // We want to convert x from 10**18 fixed point to 2**96 fixed point. // We do this by multiplying by 2**96 / 10**18. But since // ln(x * C) = ln(x) + ln(C), we can simply do nothing here // and add ln(2**96 / 10**18) at the end. // Compute k = log2(x) - 96, t = 159 - k = 255 - log2(x) = 255 ^ log2(x). int256 t; /// @solidity memory-safe-assembly assembly { t := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) t := or(t, shl(6, lt(0xffffffffffffffff, shr(t, x)))) t := or(t, shl(5, lt(0xffffffff, shr(t, x)))) t := or(t, shl(4, lt(0xffff, shr(t, x)))) t := or(t, shl(3, lt(0xff, shr(t, x)))) // forgefmt: disable-next-item t := xor( t, byte( and(0x1f, shr(shr(t, x), 0x8421084210842108cc6318c6db6d54be)), 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff ) ) } // Reduce range of x to (1, 2) * 2**96 // ln(2^k * x) = k * ln(2) + ln(x) x = int256(uint256(x << uint256(t)) >> 159); // Evaluate using a (8, 8)-term rational approximation. // p is made monic, we will multiply by a scale factor later. int256 p = x + 3273285459638523848632254066296; p = ((p * x) >> 96) + 24828157081833163892658089445524; p = ((p * x) >> 96) + 43456485725739037958740375743393; p = ((p * x) >> 96) - 11111509109440967052023855526967; p = ((p * x) >> 96) - 45023709667254063763336534515857; p = ((p * x) >> 96) - 14706773417378608786704636184526; p = p * x - (795164235651350426258249787498 << 96); // We leave p in 2**192 basis so we don't need to scale it back up for the division. // q is monic by convention. int256 q = x + 5573035233440673466300451813936; q = ((q * x) >> 96) + 71694874799317883764090561454958; q = ((q * x) >> 96) + 283447036172924575727196451306956; q = ((q * x) >> 96) + 401686690394027663651624208769553; q = ((q * x) >> 96) + 204048457590392012362485061816622; q = ((q * x) >> 96) + 31853899698501571402653359427138; q = ((q * x) >> 96) + 909429971244387300277376558375; /// @solidity memory-safe-assembly assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial is known not to have zeros in the domain. // No scaling required because p is already 2**96 too large. r := sdiv(p, q) } // r is in the range (0, 0.125) * 2**96 // Finalization, we need to: // * multiply by the scale factor s = 5.549… // * add ln(2**96 / 10**18) // * add k * ln(2) // * multiply by 10**18 / 2**96 = 5**18 >> 78 // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 r *= 1677202110996718588342820967067443963516166; // add ln(2) * k * 5e18 * 2**192 r += 16597577552685614221487285958193947469193820559219878177908093499208371 * (159 - t); // add ln(2**96 / 10**18) * 5e18 * 2**192 r += 600920179829731861736702779321621459595472258049074101567377883020018308; // base conversion: mul 2**18 / 2**192 r >>= 174; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol"; import "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. * * _Available since v4.7._ */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// 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: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "permit2/=lib/permit2/src/", "forge-std/=lib/forge-std/src/", "prb-proxy/=lib/prb-proxy/src/", "layerzerolabs/=lib/layerzerolabs/contracts/", "aave-address-book/=lib/aave-address-book/src/", "@gearbox-protocol/core-v3/contracts/=lib/core-v3/contracts/", "@gearbox-protocol/core-v2/contracts/=lib/core-v2/contracts/", "pendle/=lib/pendle/contracts/", "tranchess/=lib/contract-core/contracts/", "@1inch/=lib/core-v3/node_modules/@1inch/", "@aave/core-v3/=lib/aave-address-book/lib/aave-v3-core/", "@aave/periphery-v3/=lib/aave-address-book/lib/aave-v3-periphery/", "@chainlink/=lib/core-v3/node_modules/@chainlink/", "@prb/test/=lib/prb-proxy/lib/prb-test/src/", "aave-v3-core/=lib/aave-address-book/lib/aave-v3-core/", "aave-v3-periphery/=lib/aave-address-book/lib/aave-v3-periphery/", "core-v2/=lib/core-v2/contracts/", "core-v3/=lib/core-v3/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/", "hardhat-deploy/=node_modules/hardhat-deploy/", "hardhat/=node_modules/hardhat/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "prb-test/=lib/prb-proxy/lib/prb-test/src/", "solmate/=lib/permit2/lib/solmate/" ], "optimizer": { "enabled": true, "runs": 100 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IPoolV3","name":"pool_","type":"address"},{"internalType":"uint256","name":"protocolFee_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Flash__creditFlashLoan_callbackFailed","type":"error"},{"inputs":[],"name":"Flash__creditFlashLoan_unsupportedToken","type":"error"},{"inputs":[],"name":"Flash__flashFee_unsupportedToken","type":"error"},{"inputs":[],"name":"Flash__flashLoan_callbackFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"CreditFlashLoan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"FlashLoan","type":"event"},{"inputs":[],"name":"CALLBACK_SUCCESS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CALLBACK_SUCCESS_CREDIT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ICreditFlashBorrower","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"creditFlashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"flashFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC3156FlashBorrower","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashLoan","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"maxFlashLoan","outputs":[{"internalType":"uint256","name":"max","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract IPoolV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlyingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e060405234801561001057600080fd5b5060405161104f38038061104f83398101604081905261002f916100cf565b60016000556001600160a01b038216608081905260408051632495a59960e01b81529051632495a599916004808201926020929091908290030181865afa15801561007e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a291906100fd565b6001600160a01b031660c05260a05250610121565b6001600160a01b03811681146100cc57600080fd5b50565b600080604083850312156100e257600080fd5b82516100ed816100b7565b6020939093015192949293505050565b60006020828403121561010f57600080fd5b815161011a816100b7565b9392505050565b60805160a05160c051610e896101c660003960008181610106015281816103bc01528181610588015281816108670152610a3201526000818161019d015281816101e4015281816106500152818161069c0152610a8801526000818160c70152818161023f015281816103eb0152818161046301528181610505015281816105d8015281816106f7015281816108960152818161090e01526109b00152610e896000f3fe608060405234801561001057600080fd5b50600436106100835760003560e01c80630f13be2a1461008857806316f0115b146100c25780632495a599146101015780635cffe9de14610128578063613255ab1461014b5780637b644bad1461015e5780638237e53814610171578063b0e21e8a14610198578063d9d98ce4146101bf575b600080fd5b6100af7f24ea9631d6c6b69006fd9fa411bb9c8909638fd1d178dd2f1d231dca3e3e4d7981565b6040519081526020015b60405180910390f35b6100e97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100b9565b6100e97f000000000000000000000000000000000000000000000000000000000000000081565b61013b610136366004610bf0565b6101d2565b60405190151581526020016100b9565b6100af610159366004610c63565b610584565b61013b61016c366004610c87565b61068a565b6100af7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b6100af7f000000000000000000000000000000000000000000000000000000000000000081565b6100af6101cd366004610ce3565b610a2e565b60006101dc610ab5565b6000610208857f0000000000000000000000000000000000000000000000000000000000000000610b12565b905060006102168287610d25565b60405163bf28068b60e01b8152600481018890526001600160a01b038a811660248301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063bf28068b90604401600060405180830381600087803b15801561028557600080fd5b505af1158015610299573d6000803e3d6000fd5b5050604080516001600160a01b038b81168252602082018b9052918101869052908b1692507f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f0915060600160405180910390a26040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038a16906323e30c8b906103449033908c908c9089908d908d90600401610d61565b6020604051808303816000875af1158015610363573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103879190610da8565b146103a55760405163f56b9b8560e01b815260040160405180910390fd5b6040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd90610415908b907f0000000000000000000000000000000000000000000000000000000000000000908690600401610dc1565b6020604051808303816000875af1158015610434573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104589190610de5565b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663ca9505e46104928484610e07565b6040516001600160e01b031960e084901b16815260048101919091526000602482018190526044820152606401600060405180830381600087803b1580156104d957600080fd5b505af11580156104ed573d6000803e3d6000fd5b505060405163369a8cf560e21b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316925063da6a33d49150602401600060405180830381600087803b15801561055357600080fd5b505af1158015610567573d6000803e3d6000fd5b5050505060019250505061057b6001600055565b95945050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316036106855760405163136a683360e01b8152306004820152610682907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063136a683390602401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064b9190610da8565b61067d7f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a7640000610d25565b610b40565b90505b919050565b6000610694610ab5565b60006106c0857f0000000000000000000000000000000000000000000000000000000000000000610b12565b905060006106ce8287610d25565b60405163bf28068b60e01b8152600481018890526001600160a01b0389811660248301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063bf28068b90604401600060405180830381600087803b15801561073d57600080fd5b505af1158015610751573d6000803e3d6000fd5b505060408051898152602081018690526001600160a01b038b1693507f3a37ed9ae34244e957180e19eafe0fd564467b00dd73ed95a9c8bef37d2f42fe92500160405180910390a26040516316d8f16560e01b81527f24ea9631d6c6b69006fd9fa411bb9c8909638fd1d178dd2f1d231dca3e3e4d79906001600160a01b038916906316d8f165906107ef9033908b9088908c908c90600401610e1a565b6020604051808303816000875af115801561080e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108329190610da8565b14610850576040516359e30c5b60e01b815260040160405180910390fd5b6040516323b872dd60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906108c0908a907f0000000000000000000000000000000000000000000000000000000000000000908690600401610dc1565b6020604051808303816000875af11580156108df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109039190610de5565b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663ca9505e461093d8484610e07565b6040516001600160e01b031960e084901b16815260048101919091526000602482018190526044820152606401600060405180830381600087803b15801561098457600080fd5b505af1158015610998573d6000803e3d6000fd5b505060405163369a8cf560e21b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316925063da6a33d49150602401600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b50505050600192505050610a266001600055565b949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610a82576040516396183b1d60e01b815260040160405180910390fd5b610aac827f0000000000000000000000000000000000000000000000000000000000000000610b12565b90505b92915050565b600260005403610b0b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640160405180910390fd5b6002600055565b600081600019048311820215610b305763c4c5d7f56000526004601cfd5b50670de0b6b3a764000091020490565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202610b7d5763bcbede656000526004601cfd5b50670de0b6b3a7640000919091020490565b6001600160a01b0381168114610ba457600080fd5b50565b60008083601f840112610bb957600080fd5b50813567ffffffffffffffff811115610bd157600080fd5b602083019150836020828501011115610be957600080fd5b9250929050565b600080600080600060808688031215610c0857600080fd5b8535610c1381610b8f565b94506020860135610c2381610b8f565b935060408601359250606086013567ffffffffffffffff811115610c4657600080fd5b610c5288828901610ba7565b969995985093965092949392505050565b600060208284031215610c7557600080fd5b8135610c8081610b8f565b9392505050565b60008060008060608587031215610c9d57600080fd5b8435610ca881610b8f565b935060208501359250604085013567ffffffffffffffff811115610ccb57600080fd5b610cd787828801610ba7565b95989497509550505050565b60008060408385031215610cf657600080fd5b8235610d0181610b8f565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610aaf57610aaf610d0f565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03878116825286166020820152604081018590526060810184905260a060808201819052600090610d9c9083018486610d38565b98975050505050505050565b600060208284031215610dba57600080fd5b5051919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215610df757600080fd5b81518015158114610c8057600080fd5b81810381811115610aaf57610aaf610d0f565b60018060a01b0386168152846020820152836040820152608060608201526000610e48608083018486610d38565b97965050505050505056fea26469706673582212202011da7c97344a8fbf3d45d9e7b4bf61dcf8bd0abdceefc17d9a364904f9b70264736f6c63430008130033000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100835760003560e01c80630f13be2a1461008857806316f0115b146100c25780632495a599146101015780635cffe9de14610128578063613255ab1461014b5780637b644bad1461015e5780638237e53814610171578063b0e21e8a14610198578063d9d98ce4146101bf575b600080fd5b6100af7f24ea9631d6c6b69006fd9fa411bb9c8909638fd1d178dd2f1d231dca3e3e4d7981565b6040519081526020015b60405180910390f35b6100e97f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab81565b6040516001600160a01b0390911681526020016100b9565b6100e97f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b61013b610136366004610bf0565b6101d2565b60405190151581526020016100b9565b6100af610159366004610c63565b610584565b61013b61016c366004610c87565b61068a565b6100af7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b6100af7f000000000000000000000000000000000000000000000000000000000000000081565b6100af6101cd366004610ce3565b610a2e565b60006101dc610ab5565b6000610208857f0000000000000000000000000000000000000000000000000000000000000000610b12565b905060006102168287610d25565b60405163bf28068b60e01b8152600481018890526001600160a01b038a811660248301529192507f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab9091169063bf28068b90604401600060405180830381600087803b15801561028557600080fd5b505af1158015610299573d6000803e3d6000fd5b5050604080516001600160a01b038b81168252602082018b9052918101869052908b1692507f0d7d75e01ab95780d3cd1c8ec0dd6c2ce19e3a20427eec8bf53283b6fb8e95f0915060600160405180910390a26040516323e30c8b60e01b81527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd9906001600160a01b038a16906323e30c8b906103449033908c908c9089908d908d90600401610d61565b6020604051808303816000875af1158015610363573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103879190610da8565b146103a55760405163f56b9b8560e01b815260040160405180910390fd5b6040516323b872dd60e01b81526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906323b872dd90610415908b907f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab908690600401610dc1565b6020604051808303816000875af1158015610434573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104589190610de5565b506001600160a01b037f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab1663ca9505e46104928484610e07565b6040516001600160e01b031960e084901b16815260048101919091526000602482018190526044820152606401600060405180830381600087803b1580156104d957600080fd5b505af11580156104ed573d6000803e3d6000fd5b505060405163369a8cf560e21b8152600481018590527f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab6001600160a01b0316925063da6a33d49150602401600060405180830381600087803b15801561055357600080fd5b505af1158015610567573d6000803e3d6000fd5b5050505060019250505061057b6001600055565b95945050505050565b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316826001600160a01b0316036106855760405163136a683360e01b8152306004820152610682907f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab6001600160a01b03169063136a683390602401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064b9190610da8565b61067d7f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a7640000610d25565b610b40565b90505b919050565b6000610694610ab5565b60006106c0857f0000000000000000000000000000000000000000000000000000000000000000610b12565b905060006106ce8287610d25565b60405163bf28068b60e01b8152600481018890526001600160a01b0389811660248301529192507f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab9091169063bf28068b90604401600060405180830381600087803b15801561073d57600080fd5b505af1158015610751573d6000803e3d6000fd5b505060408051898152602081018690526001600160a01b038b1693507f3a37ed9ae34244e957180e19eafe0fd564467b00dd73ed95a9c8bef37d2f42fe92500160405180910390a26040516316d8f16560e01b81527f24ea9631d6c6b69006fd9fa411bb9c8909638fd1d178dd2f1d231dca3e3e4d79906001600160a01b038916906316d8f165906107ef9033908b9088908c908c90600401610e1a565b6020604051808303816000875af115801561080e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108329190610da8565b14610850576040516359e30c5b60e01b815260040160405180910390fd5b6040516323b872dd60e01b81526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906323b872dd906108c0908a907f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab908690600401610dc1565b6020604051808303816000875af11580156108df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109039190610de5565b506001600160a01b037f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab1663ca9505e461093d8484610e07565b6040516001600160e01b031960e084901b16815260048101919091526000602482018190526044820152606401600060405180830381600087803b15801561098457600080fd5b505af1158015610998573d6000803e3d6000fd5b505060405163369a8cf560e21b8152600481018590527f000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab6001600160a01b0316925063da6a33d49150602401600060405180830381600087803b1580156109fe57600080fd5b505af1158015610a12573d6000803e3d6000fd5b50505050600192505050610a266001600055565b949350505050565b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316836001600160a01b031614610a82576040516396183b1d60e01b815260040160405180910390fd5b610aac827f0000000000000000000000000000000000000000000000000000000000000000610b12565b90505b92915050565b600260005403610b0b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640160405180910390fd5b6002600055565b600081600019048311820215610b305763c4c5d7f56000526004601cfd5b50670de0b6b3a764000091020490565b60007812725dd1d243aba0e75fe645cc4873f9e65afe688c928e1f218311670de0b6b3a764000002158202610b7d5763bcbede656000526004601cfd5b50670de0b6b3a7640000919091020490565b6001600160a01b0381168114610ba457600080fd5b50565b60008083601f840112610bb957600080fd5b50813567ffffffffffffffff811115610bd157600080fd5b602083019150836020828501011115610be957600080fd5b9250929050565b600080600080600060808688031215610c0857600080fd5b8535610c1381610b8f565b94506020860135610c2381610b8f565b935060408601359250606086013567ffffffffffffffff811115610c4657600080fd5b610c5288828901610ba7565b969995985093965092949392505050565b600060208284031215610c7557600080fd5b8135610c8081610b8f565b9392505050565b60008060008060608587031215610c9d57600080fd5b8435610ca881610b8f565b935060208501359250604085013567ffffffffffffffff811115610ccb57600080fd5b610cd787828801610ba7565b95989497509550505050565b60008060408385031215610cf657600080fd5b8235610d0181610b8f565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610aaf57610aaf610d0f565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03878116825286166020820152604081018590526060810184905260a060808201819052600090610d9c9083018486610d38565b98975050505050505050565b600060208284031215610dba57600080fd5b5051919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215610df757600080fd5b81518015158114610c8057600080fd5b81810381811115610aaf57610aaf610d0f565b60018060a01b0386168152846020820152836040820152608060608201526000610e48608083018486610d38565b97965050505050505056fea26469706673582212202011da7c97344a8fbf3d45d9e7b4bf61dcf8bd0abdceefc17d9a364904f9b70264736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab0000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : pool_ (address): 0xa684EAf215ad323452e2B2bF6F817d4aa5C116ab
Arg [1] : protocolFee_ (uint256): 0
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a684eaf215ad323452e2b2bf6f817d4aa5c116ab
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.