Contract Overview
Balance:
0 Ether
EtherValue:
$0.00
More Info
Txn Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0x096d339a7e8ddefb299c1d374280cc5b0cf2495af2b66404f223efe98e58a773 | 0x61016060 | 15840228 | 92 days 11 hrs ago | Gearbox Protocol: Deployer | IN | Contract Creation | 0 Ether | 0.03830991 |
[ 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 0x711198f626C329CD2212f3100B59BD7dd2aD6697
Contract Name:
LidoV1Adapter
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: BUSL-1.1 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; pragma abicoder v1; 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"; // INTERFACES import { IAddressProvider } from "@gearbox-protocol/core-v2/contracts/interfaces/IAddressProvider.sol"; import { IstETH } from "../../integrations/lido/IstETH.sol"; import { IAdapter, AdapterType } from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol"; import { ICreditManagerV2 } from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditManagerV2.sol"; import { IPoolService } from "@gearbox-protocol/core-v2/contracts/interfaces/IPoolService.sol"; import { ILidoV1Adapter } from "../../interfaces/lido/ILidoV1Adapter.sol"; import { ACLTrait } from "@gearbox-protocol/core-v2/contracts/core/ACLTrait.sol"; import { LidoV1Gateway } from "./LidoV1_WETHGateway.sol"; uint256 constant LIDO_STETH_LIMIT = 20000 ether; /// @title LidoV1 adapter /// @dev Implements logic for interacting with the Lido contract through the gateway contract LidoV1Adapter is AbstractAdapter, ILidoV1Adapter, ACLTrait, ReentrancyGuard { /// @dev Address of the Lido contract address public immutable stETH; /// @dev Address of WETH address public immutable weth; /// @dev Address of Gearbox treasury address public immutable treasury; /// @dev The amount of WETH that can be deposited through this adapter uint256 public limit; AdapterType public constant _gearboxAdapterType = AdapterType.LIDO_V1; uint16 public constant _gearboxAdapterVersion = 1; /// @dev Constructor /// @param _creditManager Address of the Credit manager /// @param _lidoGateway Address of the Lido gateway constructor(address _creditManager, address _lidoGateway) ACLTrait( address( IPoolService(ICreditManagerV2(_creditManager).poolService()) .addressProvider() ) ) AbstractAdapter(_creditManager, _lidoGateway) { IAddressProvider ap = IPoolService( ICreditManagerV2(_creditManager).poolService() ).addressProvider(); stETH = address(LidoV1Gateway(payable(_lidoGateway)).stETH()); // F:[LDOV1-1] weth = ap.getWethToken(); // F:[LDOV1-1] treasury = ap.getTreasuryContract(); // F:[LDOV1-1] limit = LIDO_STETH_LIMIT; // F:[LDOV1-1] } /// @dev Sends an order to stake ETH in Lido and receive stETH (sending WETH through the gateway) /// - Checks that the transaction isn't over the limit and decreases the limit by the amount /// - Executes a safe allowance fast check call to gateway's `submit`, passing the Gearbox treasury as referral /// @param amount The amount of ETH to deposit in Lido /// @notice Fast check parameters: /// Input token: WETH /// Output token: stETH /// Input token is allowed, since the gateway does a transferFrom for WETH /// The input token does not need to be disabled, because this does not spend the entire /// balance, generally function submit(uint256 amount) external returns (uint256 result) { address creditAccount = creditManager.getCreditAccountOrRevert( msg.sender ); // F:[LDOV1-2] result = _submit(amount, creditAccount, false); // F:[LDOV1-3] } /// @dev Sends an order to stake ETH in Lido and receive stETH (sending all available WETH through the gateway) /// - Checks that the transaction isn't over the limit and decreases the limit by the amount /// - Executes a safe allowance fast check call to gateway's `submit`, passing the Gearbox treasury as referral /// @notice Fast check parameters: /// Input token: WETH /// Output token: stETH /// Input token is allowed, since the gateway does a transferFrom for WETH /// The input token does need to be disabled, because this spends the entire balance function submitAll() external returns (uint256 result) { address creditAccount = creditManager.getCreditAccountOrRevert( msg.sender ); // F:[LDOV1-2] uint256 amount = IERC20(weth).balanceOf(creditAccount); // F:[LDOV1-4] if (amount > 1) { unchecked { amount--; // F:[LDOV1-4] } result = _submit(amount, creditAccount, true); // F:[LDOV1-4] } } function _submit( uint256 amount, address creditAccount, bool disableTokenIn ) internal returns (uint256 result) { if (amount > limit) revert LimitIsOverException(); // F:[LDOV1-5] unchecked { limit -= amount; // F:[LDOV1-5] } result = abi.decode( _safeExecuteFastCheck( creditAccount, weth, stETH, abi.encodeWithSelector( LidoV1Gateway.submit.selector, amount, treasury ), true, disableTokenIn ), (uint256) ); // F:[LDOV1-3,4] } /// @dev Set a new deposit limit /// @param _limit New value for the limit function setLimit(uint256 _limit) external override configuratorOnly // F:[LDOV1-6] { limit = _limit; // F:[LDOV1-7] emit NewLimit(_limit); // F:[LDOV1-7] } /// @dev Get a number of shares corresponding to the specified ETH amount /// @param _ethAmount Amount of ETH to get shares for function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256) { return IstETH(targetContract).getSharesByPooledEth(_ethAmount); } /// @dev Get amount of ETH corresponding to the specified number of shares /// @param _sharesAmount Number of shares to get ETH amount for function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256) { return IstETH(targetContract).getPooledEthByShares(_sharesAmount); } /// @dev Get the total amount of ETH in Lido function getTotalPooledEther() external view returns (uint256) { return IstETH(targetContract).getTotalPooledEther(); } /// @dev Get the total amount of internal shares in the stETH contract function getTotalShares() external view returns (uint256) { return IstETH(targetContract).getTotalShares(); } /// @dev Get the fee taken from stETH revenue, in bp function getFee() external view returns (uint16) { return IstETH(targetContract).getFee(); } /// @dev Get the number of internal stETH shares belonging to a particular account /// @param _account Address to get the shares for function sharesOf(address _account) external view returns (uint256) { return IstETH(targetContract).sharesOf(_account); } /// @dev Get the ERC20 token name function name() external view returns (string memory) { return IstETH(targetContract).name(); } /// @dev Get the ERC20 token symbol function symbol() external view returns (string memory) { return IstETH(targetContract).symbol(); } /// @dev Get the ERC20 token decimals function decimals() external view returns (uint8) { return IstETH(targetContract).decimals(); } /// @dev Get ERC20 token balance for an account /// @param _account The address to get the balance for function balanceOf(address _account) external view returns (uint256) { return IstETH(targetContract).balanceOf(_account); } /// @dev Get ERC20 token allowance from owner to spender /// @param _owner The address allowing spending /// @param _spender The address allowed spending function allowance(address _owner, address _spender) external view returns (uint256) { return IstETH(targetContract).allowance(_owner, _spender); } /// @dev Get ERC20 token total supply function totalSupply() external view returns (uint256) { return IstETH(targetContract).totalSupply(); } }
// 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: 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 { IVersion } from "./IVersion.sol"; interface IAddressProviderEvents { /// @dev Emits when an address is set for a contract role event AddressSet(bytes32 indexed service, address indexed newAddress); } /// @title Optimised for front-end Address Provider interface interface IAddressProvider is IAddressProviderEvents, IVersion { /// @return Address of ACL contract function getACL() external view returns (address); /// @return Address of ContractsRegister function getContractsRegister() external view returns (address); /// @return Address of AccountFactory function getAccountFactory() external view returns (address); /// @return Address of DataCompressor function getDataCompressor() external view returns (address); /// @return Address of GEAR token function getGearToken() external view returns (address); /// @return Address of WETH token function getWethToken() external view returns (address); /// @return Address of WETH Gateway function getWETHGateway() external view returns (address); /// @return Address of PriceOracle function getPriceOracle() external view returns (address); /// @return Address of DAO Treasury Multisig function getTreasuryContract() external view returns (address); /// @return Address of PathFinder function getLeveragedActions() external view returns (address); }
// 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 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import "../core/AddressProvider.sol"; import { IVersion } from "./IVersion.sol"; interface IPoolServiceEvents { /// @dev Emits on new liquidity being added to the pool event AddLiquidity( address indexed sender, address indexed onBehalfOf, uint256 amount, uint256 referralCode ); /// @dev Emits on liquidity being removed to the pool event RemoveLiquidity( address indexed sender, address indexed to, uint256 amount ); /// @dev Emits on a Credit Manager borrowing funds for a Credit Account event Borrow( address indexed creditManager, address indexed creditAccount, uint256 amount ); /// @dev Emits on repayment of a Credit Account's debt event Repay( address indexed creditManager, uint256 borrowedAmount, uint256 profit, uint256 loss ); /// @dev Emits on updating the interest rate model event NewInterestRateModel(address indexed newInterestRateModel); /// @dev Emits on connecting a new Credit Manager event NewCreditManagerConnected(address indexed creditManager); /// @dev Emits when a Credit Manager is forbidden to borrow event BorrowForbidden(address indexed creditManager); /// @dev Emitted when loss is incurred that can't be covered by treasury funds event UncoveredLoss(address indexed creditManager, uint256 loss); /// @dev Emits when the liquidity limit is changed event NewExpectedLiquidityLimit(uint256 newLimit); /// @dev Emits when the withdrawal fee is changed event NewWithdrawFee(uint256 fee); } /// @title Pool Service Interface /// @notice Implements business logic: /// - Adding/removing pool liquidity /// - Managing diesel tokens & diesel rates /// - Taking/repaying Credit Manager debt /// More: https://dev.gearbox.fi/developers/pool/abstractpoolservice interface IPoolService is IPoolServiceEvents, IVersion { // // LIQUIDITY MANAGEMENT // /** * @dev Adds liquidity to pool * - transfers the underlying to the pool * - mints Diesel (LP) tokens to onBehalfOf * @param amount Amount of tokens to be deposited * @param onBehalfOf The address that will receive the dToken * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without a facilitator. */ function addLiquidity( uint256 amount, address onBehalfOf, uint256 referralCode ) external; /** * @dev Removes liquidity from pool * - burns LP's Diesel (LP) tokens * - returns the equivalent amount of underlying to 'to' * @param amount Amount of Diesel tokens to burn * @param to Address to transfer the underlying to */ function removeLiquidity(uint256 amount, address to) external returns (uint256); /** * @dev Lends pool funds to a Credit Account * @param borrowedAmount Credit Account's debt principal * @param creditAccount Credit Account's address */ function lendCreditAccount(uint256 borrowedAmount, address creditAccount) external; /** * @dev Repays the Credit Account's debt * @param borrowedAmount Amount of principal ro repay * @param profit The treasury profit from repayment * @param loss Amount of underlying that the CA wan't able to repay * @notice Assumes that the underlying (including principal + interest + fees) * was already transferred */ function repayCreditAccount( uint256 borrowedAmount, uint256 profit, uint256 loss ) external; // // GETTERS // /** * @dev Returns the total amount of liquidity in the pool, including borrowed and available funds */ function expectedLiquidity() external view returns (uint256); /** * @dev Returns the limit on total liquidity */ function expectedLiquidityLimit() external view returns (uint256); /** * @dev Returns the available liquidity, which is expectedLiquidity - totalBorrowed */ function availableLiquidity() external view returns (uint256); /** * @dev Calculates the current interest index, RAY format */ function calcLinearCumulative_RAY() external view returns (uint256); /** * @dev Calculates the current borrow rate, RAY format */ function borrowAPY_RAY() external view returns (uint256); /** * @dev Returns the total borrowed amount (includes principal only) */ function totalBorrowed() external view returns (uint256); /** * ç **/ function getDieselRate_RAY() external view returns (uint256); /** * @dev Returns the address of the underlying */ function underlyingToken() external view returns (address); /** * @dev Returns the address of the diesel token */ function dieselToken() external view returns (address); /** * @dev Returns the address of a Credit Manager by its id */ function creditManagers(uint256 id) external view returns (address); /** * @dev Returns the number of known Credit Managers */ function creditManagersCount() external view returns (uint256); /** * @dev Maps Credit Manager addresses to their status as a borrower. * Returns false if borrowing is not allowed. */ function creditManagersCanBorrow(address id) external view returns (bool); /// @dev Converts a quantity of the underlying to Diesel tokens function toDiesel(uint256 amount) external view returns (uint256); /// @dev Converts a quantity of Diesel tokens to the underlying function fromDiesel(uint256 amount) external view returns (uint256); /// @dev Returns the withdrawal fee function withdrawFee() external view returns (uint256); /// @dev Returns the timestamp of the pool's last update function _timestampLU() external view returns (uint256); /// @dev Returns the interest index at the last pool update function _cumulativeIndex_RAY() external view returns (uint256); /// @dev Returns the address provider function addressProvider() external view returns (AddressProvider); }
// SPDX-License-Identifier: BUSL-1.1 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { Pausable } from "@openzeppelin/contracts/security/Pausable.sol"; import { AddressProvider } from "./AddressProvider.sol"; import { IACL } from "../interfaces/IACL.sol"; import { ZeroAddressException, CallerNotConfiguratorException, CallerNotPausableAdminException, CallerNotUnPausableAdminException } from "../interfaces/IErrors.sol"; /// @title ACL Trait /// @notice Utility class for ACL consumers abstract contract ACLTrait is Pausable { // ACL contract to check rights IACL public immutable _acl; /// @dev constructor /// @param addressProvider Address of address repository constructor(address addressProvider) { if (addressProvider == address(0)) revert ZeroAddressException(); // F:[AA-2] _acl = IACL(AddressProvider(addressProvider).getACL()); } /// @dev Reverts if msg.sender is not configurator modifier configuratorOnly() { if (!_acl.isConfigurator(msg.sender)) revert CallerNotConfiguratorException(); _; } ///@dev Pause contract function pause() external { if (!_acl.isPausableAdmin(msg.sender)) revert CallerNotPausableAdminException(); _pause(); } /// @dev Unpause contract function unpause() external { if (!_acl.isUnpausableAdmin(msg.sender)) revert CallerNotUnPausableAdminException(); _unpause(); } }
// 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: 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-FileCopyrightText: 2020 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.10; import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; interface IstETHGetters is IERC20Metadata { function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); function getTotalPooledEther() external view returns (uint256); function getTotalShares() external view returns (uint256); function getFee() external view returns (uint16); function sharesOf(address _account) external view returns (uint256); } interface IstETH is IstETHGetters { function submit(address _referral) external payable returns (uint256); }
// SPDX-License-Identifier: MIT // 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"; interface ILidoV1AdapterEvents { event NewLimit(uint256 _limit); } interface ILidoV1AdapterExceptions { error LimitIsOverException(); } interface ILidoV1Adapter is IAdapter, ILidoV1AdapterEvents, ILidoV1AdapterExceptions { /// @dev Set a new deposit limit /// @param _limit New value for the limit function setLimit(uint256 _limit) external; /// @dev Sends an order to stake ETH in Lido and receive stETH (sending WETH through the gateway) /// @param amount The amount of ETH to deposit in Lido /// @notice Since Gearbox only uses WETH as collateral, the amount has to be passed explicitly /// unlike Lido. The referral address is always set to Gearbox treasury function submit(uint256 amount) external returns (uint256 result); /// @dev Sends an order to stake ETH in Lido and receive stETH (sending all available WETH through the gateway) function submitAll() external returns (uint256 result); // // Getters // /// @dev Get a number of shares corresponding to the specified ETH amount /// @param _ethAmount Amount of ETH to get shares for function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); /// @dev Get amount of ETH corresponding to the specified number of shares /// @param _sharesAmount Number of shares to get ETH amount for function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); /// @dev Get the total amount of ETH in Lido function getTotalPooledEther() external view returns (uint256); /// @dev Get the total amount of internal shares in the stETH contract function getTotalShares() external view returns (uint256); /// @dev Get the fee taken from stETH revenue, in bp function getFee() external view returns (uint16); /// @dev Get the number of internal stETH shares belonging to a particular account /// @param _account Address to get the shares for function sharesOf(address _account) external view returns (uint256); /// @dev Returns WETH (Lido adapter input token) function weth() external view returns (address); /// @dev Returns stETH (Lido adapter output token) function stETH() external view returns (address); // // ERC20 getters // /// @dev Get the ERC20 token name function name() external view returns (string memory); /// @dev Get the ERC20 token symbol function symbol() external view returns (string memory); /// @dev Get the ERC20 token decimals function decimals() external view returns (uint8); /// @dev Get ERC20 token balance for an account /// @param _account The address to get the balance for function balanceOf(address _account) external view returns (uint256); /// @dev Get ERC20 token allowance from owner to spender /// @param _owner The address allowing spending /// @param _spender The address allowed spending function allowance(address _owner, address _spender) external view returns (uint256); /// @dev Get ERC20 token total supply function totalSupply() external view returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; pragma abicoder v1; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IstETH } from "../../integrations/lido/IstETH.sol"; import { IWETH } from "@gearbox-protocol/core-v2/contracts/interfaces/external/IWETH.sol"; // EXCEPTIONS import { ZeroAddressException } from "@gearbox-protocol/core-v2/contracts/interfaces/IErrors.sol"; /// @title LidoV1 Gateway /// @dev Implements logic allowing CA to interact with Lido contracts, which use native ETH contract LidoV1Gateway { /// @dev The original Lido contract IstETH public immutable stETH; /// @dev The WETH contract IWETH public immutable weth; /// @dev Constructor /// @param _weth WETH token address /// @param _stETH Address of the Lido/stETH contract constructor(address _weth, address _stETH) { if (_weth == address(0) || _stETH == address(0)) revert ZeroAddressException(); stETH = IstETH(_stETH); weth = IWETH(_weth); } /// @dev Implements logic allowing CA's to call `submit` in Lido, which uses native ETH /// - Transfers WETH from senders and unwraps into ETH /// - Submits ETH to Lido /// - Sends resulting stETH back to sender /// @param amount The amount of WETH to unwrap into ETH and submit /// @param _referral The address of the referrer function submit(uint256 amount, address _referral) external returns (uint256 value) { IERC20(address(weth)).transferFrom(msg.sender, address(this), amount); weth.withdraw(amount); value = stETH.submit{ value: amount }(_referral); stETH.transfer(msg.sender, stETH.balanceOf(address(this))); } receive() external payable {} /// @dev Get a number of shares corresponding to the specified ETH amount /// @param _ethAmount Amount of ETH to get shares for function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256) { return stETH.getSharesByPooledEth(_ethAmount); } /// @dev Get amount of ETH corresponding to the specified number of shares /// @param _sharesAmount Number of shares to get ETH amount for function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256) { return stETH.getPooledEthByShares(_sharesAmount); } /// @dev Get the total amount of ETH in Lido function getTotalPooledEther() external view returns (uint256) { return stETH.getTotalPooledEther(); } /// @dev Get the total amount of internal shares in the stETH contract function getTotalShares() external view returns (uint256) { return stETH.getTotalShares(); } /// @dev Get the fee taken from stETH revenue, in bp function getFee() external view returns (uint16) { return stETH.getFee(); } /// @dev Get the number of internal stETH shares belonging to a particular account /// @param _account Address to get the shares for function sharesOf(address _account) external view returns (uint256) { return stETH.sharesOf(_account); } /// @dev Get the ERC20 token name function name() external view returns (string memory) { return stETH.name(); } /// @dev Get the ERC20 token symbol function symbol() external view returns (string memory) { return stETH.symbol(); } /// @dev Get the ERC20 token decimals function decimals() external view returns (uint8) { return stETH.decimals(); } /// @dev Get ERC20 token balance for an account /// @param _account The address to get the balance for function balanceOf(address _account) external view returns (uint256) { return stETH.balanceOf(_account); } /// @dev Get ERC20 token allowance from owner to spender /// @param _owner The address allowing spending /// @param _spender The address allowed spending function allowance(address _owner, address _spender) external view returns (uint256) { return stETH.allowance(_owner, _spender); } /// @dev Get ERC20 token total supply function totalSupply() external view returns (uint256) { return stETH.totalSupply(); } }
// 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 (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; /// @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 // 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: BUSL-1.1 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { IAddressProvider } from "../interfaces/IAddressProvider.sol"; import { Claimable } from "./access/Claimable.sol"; import { Errors } from "../libraries/Errors.sol"; // Repositories & services bytes32 constant CONTRACTS_REGISTER = "CONTRACTS_REGISTER"; bytes32 constant ACL = "ACL"; bytes32 constant PRICE_ORACLE = "PRICE_ORACLE"; bytes32 constant ACCOUNT_FACTORY = "ACCOUNT_FACTORY"; bytes32 constant DATA_COMPRESSOR = "DATA_COMPRESSOR"; bytes32 constant TREASURY_CONTRACT = "TREASURY_CONTRACT"; bytes32 constant GEAR_TOKEN = "GEAR_TOKEN"; bytes32 constant WETH_TOKEN = "WETH_TOKEN"; bytes32 constant WETH_GATEWAY = "WETH_GATEWAY"; bytes32 constant LEVERAGED_ACTIONS = "LEVERAGED_ACTIONS"; /// @title AddressRepository /// @notice Stores addresses of deployed contracts contract AddressProvider is Claimable, IAddressProvider { // Mapping from contract keys to respective addresses mapping(bytes32 => address) public addresses; // Contract version uint256 public constant version = 2; constructor() { // @dev Emits first event for contract discovery emit AddressSet("ADDRESS_PROVIDER", address(this)); } /// @return Address of ACL contract function getACL() external view returns (address) { return _getAddress(ACL); // F:[AP-3] } /// @dev Sets address of ACL contract /// @param _address Address of ACL contract function setACL(address _address) external onlyOwner // F:[AP-12] { _setAddress(ACL, _address); // F:[AP-3] } /// @return Address of ContractsRegister function getContractsRegister() external view returns (address) { return _getAddress(CONTRACTS_REGISTER); // F:[AP-4] } /// @dev Sets address of ContractsRegister /// @param _address Address of ContractsRegister function setContractsRegister(address _address) external onlyOwner // F:[AP-12] { _setAddress(CONTRACTS_REGISTER, _address); // F:[AP-4] } /// @return Address of PriceOracle function getPriceOracle() external view override returns (address) { return _getAddress(PRICE_ORACLE); // F:[AP-5] } /// @dev Sets address of PriceOracle /// @param _address Address of PriceOracle function setPriceOracle(address _address) external onlyOwner // F:[AP-12] { _setAddress(PRICE_ORACLE, _address); // F:[AP-5] } /// @return Address of AccountFactory function getAccountFactory() external view returns (address) { return _getAddress(ACCOUNT_FACTORY); // F:[AP-6] } /// @dev Sets address of AccountFactory /// @param _address Address of AccountFactory function setAccountFactory(address _address) external onlyOwner // F:[AP-12] { _setAddress(ACCOUNT_FACTORY, _address); // F:[AP-6] } /// @return Address of DataCompressor function getDataCompressor() external view override returns (address) { return _getAddress(DATA_COMPRESSOR); // F:[AP-7] } /// @dev Sets address of AccountFactory /// @param _address Address of AccountFactory function setDataCompressor(address _address) external onlyOwner // F:[AP-12] { _setAddress(DATA_COMPRESSOR, _address); // F:[AP-7] } /// @return Address of Treasury contract function getTreasuryContract() external view returns (address) { return _getAddress(TREASURY_CONTRACT); // F:[AP-8] } /// @dev Sets address of Treasury Contract /// @param _address Address of Treasury Contract function setTreasuryContract(address _address) external onlyOwner // F:[AP-12] { _setAddress(TREASURY_CONTRACT, _address); // F:[AP-8] } /// @return Address of GEAR token function getGearToken() external view override returns (address) { return _getAddress(GEAR_TOKEN); // F:[AP-9] } /// @dev Sets address of GEAR token /// @param _address Address of GEAR token function setGearToken(address _address) external onlyOwner // F:[AP-12] { _setAddress(GEAR_TOKEN, _address); // F:[AP-9] } /// @return Address of WETH token function getWethToken() external view override returns (address) { return _getAddress(WETH_TOKEN); // F:[AP-10] } /// @dev Sets address of WETH token /// @param _address Address of WETH token function setWethToken(address _address) external onlyOwner // F:[AP-12] { _setAddress(WETH_TOKEN, _address); // F:[AP-10] } /// @return Address of WETH token function getWETHGateway() external view override returns (address) { return _getAddress(WETH_GATEWAY); // F:[AP-11] } /// @dev Sets address of WETH token /// @param _address Address of WETH token function setWETHGateway(address _address) external onlyOwner // F:[AP-12] { _setAddress(WETH_GATEWAY, _address); // F:[AP-11] } /// @return Address of PathFinder function getLeveragedActions() external view returns (address) { return _getAddress(LEVERAGED_ACTIONS); // T:[AP-7] } /// @dev Sets address of PathFinder /// @param _address Address of PathFinder function setLeveragedActions(address _address) external onlyOwner // T:[AP-15] { _setAddress(LEVERAGED_ACTIONS, _address); // T:[AP-7] } /// @return Address of key, reverts if the key doesn't exist function _getAddress(bytes32 key) internal view returns (address) { address result = addresses[key]; require(result != address(0), Errors.AS_ADDRESS_NOT_FOUND); // F:[AP-1] return result; // F:[AP-3, 4, 5, 6, 7, 8, 9, 10, 11] } /// @dev Sets address to map by its key /// @param key Key in string format /// @param value Address function _setAddress(bytes32 key, address value) internal { addresses[key] = value; // F:[AP-3, 4, 5, 6, 7, 8, 9, 10, 11] emit AddressSet(key, value); // F:[AP-2] } }
// SPDX-License-Identifier: GPL-2.0-or-later // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; /// @title Errors library library Errors { // // COMMON // string public constant ZERO_ADDRESS_IS_NOT_ALLOWED = "Z0"; string public constant NOT_IMPLEMENTED = "NI"; string public constant INCORRECT_PATH_LENGTH = "PL"; string public constant INCORRECT_ARRAY_LENGTH = "CR"; string public constant REGISTERED_CREDIT_ACCOUNT_MANAGERS_ONLY = "CP"; string public constant REGISTERED_POOLS_ONLY = "RP"; string public constant INCORRECT_PARAMETER = "IP"; // // MATH // string public constant MATH_MULTIPLICATION_OVERFLOW = "M1"; string public constant MATH_ADDITION_OVERFLOW = "M2"; string public constant MATH_DIVISION_BY_ZERO = "M3"; // // POOL // string public constant POOL_CONNECTED_CREDIT_MANAGERS_ONLY = "PS0"; string public constant POOL_INCOMPATIBLE_CREDIT_ACCOUNT_MANAGER = "PS1"; string public constant POOL_MORE_THAN_EXPECTED_LIQUIDITY_LIMIT = "PS2"; string public constant POOL_INCORRECT_WITHDRAW_FEE = "PS3"; string public constant POOL_CANT_ADD_CREDIT_MANAGER_TWICE = "PS4"; // // ACCOUNT FACTORY // string public constant AF_CANT_CLOSE_CREDIT_ACCOUNT_IN_THE_SAME_BLOCK = "AF1"; string public constant AF_MINING_IS_FINISHED = "AF2"; string public constant AF_CREDIT_ACCOUNT_NOT_IN_STOCK = "AF3"; string public constant AF_EXTERNAL_ACCOUNTS_ARE_FORBIDDEN = "AF4"; // // ADDRESS PROVIDER // string public constant AS_ADDRESS_NOT_FOUND = "AP1"; // // CONTRACTS REGISTER // string public constant CR_POOL_ALREADY_ADDED = "CR1"; string public constant CR_CREDIT_MANAGER_ALREADY_ADDED = "CR2"; // // CREDIT ACCOUNT // string public constant CA_CONNECTED_CREDIT_MANAGER_ONLY = "CA1"; string public constant CA_FACTORY_ONLY = "CA2"; // // ACL // string public constant ACL_CALLER_NOT_PAUSABLE_ADMIN = "ACL1"; string public constant ACL_CALLER_NOT_CONFIGURATOR = "ACL2"; // // WETH GATEWAY // string public constant WG_DESTINATION_IS_NOT_WETH_COMPATIBLE = "WG1"; string public constant WG_RECEIVE_IS_NOT_ALLOWED = "WG2"; string public constant WG_NOT_ENOUGH_FUNDS = "WG3"; // // TOKEN DISTRIBUTOR // string public constant TD_WALLET_IS_ALREADY_CONNECTED_TO_VC = "TD1"; string public constant TD_INCORRECT_WEIGHTS = "TD2"; string public constant TD_NON_ZERO_BALANCE_AFTER_DISTRIBUTION = "TD3"; string public constant TD_CONTRIBUTOR_IS_NOT_REGISTERED = "TD4"; }
// SPDX-License-Identifier: BUSL-1.1 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Holdings, 2022 pragma solidity ^0.8.10; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; /// @title Claimable /// @dev Implements logic for a two-step ownership transfer on top of Ownable contract Claimable is Ownable { /// @dev The new owner that has not claimed ownership yet address public pendingOwner; /// @dev A modifier that restricts the function to the pending owner only modifier onlyPendingOwner() { if (msg.sender != pendingOwner) { revert("Claimable: Sender is not pending owner"); } _; } /// @dev Sets pending owner to the new owner, but does not /// transfer ownership yet /// @param newOwner The address to become the future owner function transferOwnership(address newOwner) public override onlyOwner { require( newOwner != address(0), "Claimable: new owner is the zero address" ); pendingOwner = newOwner; } /// @dev Used by the pending owner to claim ownership after transferOwnership function claimOwnership() external onlyPendingOwner { _transferOwnership(pendingOwner); pendingOwner = address(0); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// 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 IACLExceptions { /// @dev Thrown when attempting to delete an address from a set that is not a pausable admin error AddressNotPausableAdminException(address addr); /// @dev Thrown when attempting to delete an address from a set that is not a unpausable admin error AddressNotUnpausableAdminException(address addr); } interface IACLEvents { /// @dev Emits when a new admin is added that can pause contracts event PausableAdminAdded(address indexed newAdmin); /// @dev Emits when a Pausable admin is removed event PausableAdminRemoved(address indexed admin); /// @dev Emits when a new admin is added that can unpause contracts event UnpausableAdminAdded(address indexed newAdmin); /// @dev Emits when an Unpausable admin is removed event UnpausableAdminRemoved(address indexed admin); } /// @title ACL interface interface IACL is IACLEvents, IACLExceptions, IVersion { /// @dev Returns true if the address is a pausable admin and false if not /// @param addr Address to check function isPausableAdmin(address addr) external view returns (bool); /// @dev Returns true if the address is unpausable admin and false if not /// @param addr Address to check function isUnpausableAdmin(address addr) external view returns (bool); /// @dev Returns true if an address has configurator rights /// @param account Address to check function isConfigurator(address account) external view returns (bool); /// @dev Returns address of configurator function owner() external view returns (address); }
// 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); }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.4; interface IWETH { /// @dev Deposits native ETH into the contract and mints WETH function deposit() external payable; /// @dev Transfers WETH to another account function transfer(address to, uint256 value) external returns (bool); /// @dev Burns WETH from msg.sender and send back native ETH function withdraw(uint256) external; }
{ "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":"_lidoGateway","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotConfiguratorException","type":"error"},{"inputs":[],"name":"CallerNotPausableAdminException","type":"error"},{"inputs":[],"name":"CallerNotUnPausableAdminException","type":"error"},{"inputs":[],"name":"LimitIsOverException","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"TokenIsNotInAllowedList","type":"error"},{"inputs":[],"name":"ZeroAddressException","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"NewLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"_acl","outputs":[{"internalType":"contract IACL","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":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sharesAmount","type":"uint256"}],"name":"getPooledEthByShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ethAmount","type":"uint256"}],"name":"getSharesByPooledEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalPooledEther","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"sharesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"submit","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"submitAll","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101606040523480156200001257600080fd5b506040516200230938038062002309833981810160405260408110156200003857600080fd5b50805160209182015160408051632b853d7960e11b81529051929391926001600160a01b0385169263570a7af292600480820193918290030181865afa15801562000087573d6000803e3d6000fd5b505050506040513d60208110156200009e57600080fd5b505160408051630a55006360e21b815290516001600160a01b0390921691632954018c916004808201926020929091908290030181865afa158015620000e8573d6000803e3d6000fd5b505050506040513d6020811015620000ff57600080fd5b505182826001600160a01b03821615806200012157506001600160a01b038116155b156200014057604051635919af9760e11b815260040160405180910390fd5b6001600160a01b038216608081905260408051632f7a188160e01b81529051632f7a1881916004808201926020929091908290030181865afa1580156200018b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b191906200048b565b6001600160a01b0390811660a05290811660c0526000805460ff19169055821615159050620001f357604051635919af9760e11b815260040160405180910390fd5b806001600160a01b031663087376956040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000232573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200025891906200048b565b6001600160a01b031660e0816001600160a01b03168152505050600180819055506000826001600160a01b031663570a7af26040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002ba573d6000803e3d6000fd5b505050506040513d6020811015620002d157600080fd5b505160408051630a55006360e21b815290516001600160a01b0390921691632954018c916004808201926020929091908290030181865afa1580156200031b573d6000803e3d6000fd5b505050506040513d60208110156200033257600080fd5b50516040805163183fc7c960e31b815290519192506001600160a01b0384169163c1fe3e48916004808201926020929091908290030181865afa1580156200037e573d6000803e3d6000fd5b505050506040513d60208110156200039557600080fd5b50516001600160a01b039081166101005260408051634c252f9160e01b8152905191831691634c252f91916004808201926020929091908290030181865afa158015620003e6573d6000803e3d6000fd5b505050506040513d6020811015620003fd57600080fd5b50516001600160a01b0390811661012052604080516326c74fc360e01b81529051918316916326c74fc3916004808201926020929091908290030181865afa1580156200044e573d6000803e3d6000fd5b505050506040513d60208110156200046557600080fd5b50516001600160a01b031661014052505069043c33c193756480000060025550620004bd565b6000602082840312156200049e57600080fd5b81516001600160a01b0381168114620004b657600080fd5b9392505050565b60805160a05160c05160e051610100516101205161014051611d1f620005ea60003960008181610368015261123b01526000818161032701528181610a1501526112c601526000818161048c01526112e80152600081816104170152818161082f01528181610bc40152610db801526000818161043e0152818161057c015281816106e50152818161076f01528181610ac001528181610b2d01528181610c8801528181610d1601528181610e7a01528181610ee701528181610f5401528181610fc101528181611148015281816116d901526117d80152600081816102a1015281816114f10152611887015260008181610465015281816109250152818161108d015281816116aa0152818161180f0152818161190f015281816119c30152611a7f0152611d1f6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80637a28fb88116100f9578063c1fe3e4811610097578063d5002f2e11610071578063d5002f2e146104e5578063dd62ed3e146104ed578063ea99c2a614610528578063f5eb42dc1461054557600080fd5b8063c1fe3e4814610487578063ce30bbdb146104ae578063ced72f87146104dd57600080fd5b8063a4d66daf116100d3578063a4d66daf14610409578063a50cf2c814610412578063bd90df7014610439578063c12c21c01461046057600080fd5b80637a28fb88146103dc5780638456cb59146103f957806395d89b411461040157600080fd5b806337cfdaca116101665780635c975abb116101405780635c975abb1461034957806361d027b31461036357806370a082311461038a57806378aa73a4146103bd57600080fd5b806337cfdaca146103125780633f4ba83a1461031a5780633fc8cef31461032257600080fd5b806327ea6f2b116101a257806327ea6f2b1461027d5780632f7a18811461029c57806330bebac9146102ec578063313ce567146102f457600080fd5b806306fdde03146101c957806318160ddd146102465780631920845114610260575b600080fd5b6101d1610578565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61024e6106e1565b60408051918252519081900360200190f35b61024e6004803603602081101561027657600080fd5b503561076b565b61029a6004803603602081101561029357600080fd5b5035610801565b005b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61024e610920565b6102fc610abc565b6040805160ff9092168252519081900360200190f35b61024e610b29565b61029a610b96565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b60005460ff16604080519115158252519081900360200190f35b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b61024e600480360360208110156103a057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c84565b6103c5600181565b6040805161ffff9092168252519081900360200190f35b61024e600480360360208110156103f257600080fd5b5035610d12565b61029a610d8a565b6101d1610e76565b61024e60025481565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6104b6600d81565b6040518082600f8111156104cc576104cc611ae3565b815260200191505060405180910390f35b6103c5610ee3565b61024e610f50565b61024e6004803603604081101561050357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610fbd565b61024e6004803603602081101561053e57600080fd5b5035611088565b61024e6004803603602081101561055b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611144565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156105e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561062c57600080fd5b810190808051604051939291908464010000000082111561064c57600080fd5b90830190602082018581111561066157600080fd5b825164010000000081118282018810171561067b57600080fd5b82525081516020918201929091019080838360005b838110156106a8578181015183820152602001610690565b50505050905090810190601f1680156106d55780820380516001836020036101000a031916815260200191505b50604052505050905090565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561074e573d6000803e3d6000fd5b505050506040513d602081101561076457600080fd5b5051919050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166319208451836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381865afa1580156107e3573d6000803e3d6000fd5b505050506040513d60208110156107f957600080fd5b505192915050565b6040517f5f259aba0000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690635f259aba90602401602060405180830381865afa15801561088b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108af9190611b12565b6108e5576040517f61081c1500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028190556040805182815290517fe1e1c8251499b303aefb01cf84a5ce22a95911c20ce2f3f5ae670441a6353d829181900360200190a150565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e958b704336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381865afa1580156109af573d6000803e3d6000fd5b505050506040513d60208110156109c557600080fd5b5051604080517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808416600483015291519293506000927f0000000000000000000000000000000000000000000000000000000000000000909216916370a08231916024808201926020929091908290030181865afa158015610a63573d6000803e3d6000fd5b505050506040513d6020811015610a7957600080fd5b505190506001811115610ab7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ab4818360016111d2565b92505b505090565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561074e573d6000803e3d6000fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166337cfdaca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561074e573d6000803e3d6000fd5b6040517fd4eb5db00000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063d4eb5db090602401602060405180830381865afa158015610c20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c449190611b12565b610c7a576040517f10332dee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c8261132e565b565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381865afa1580156107e3573d6000803e3d6000fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637a28fb88836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381865afa1580156107e3573d6000803e3d6000fd5b6040517f3a41ec640000000000000000000000000000000000000000000000000000000081523360048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690633a41ec6490602401602060405180830381865afa158015610e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e389190611b12565b610e6e576040517fd794b1e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c82611414565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156105e5573d6000803e3d6000fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ced72f876040518163ffffffff1660e01b8152600401602060405180830381865afa15801561074e573d6000803e3d6000fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d5002f2e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561074e573d6000803e3d6000fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381865afa158015611069573d6000803e3d6000fd5b505050506040513d602081101561107f57600080fd5b50519392505050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e958b704336040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381865afa158015611117573d6000803e3d6000fd5b505050506040513d602081101561112d57600080fd5b5051905061113d838260006111d2565b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f5eb42dc836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381865afa1580156107e3573d6000803e3d6000fd5b6000600254841115611210576040517f2bfcdce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280548590039055604080516024810186905273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166044808301919091528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff532e86a000000000000000000000000000000000000000000000000000000001790526113109084907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000906001876114d4565b806020019051602081101561132457600080fd5b5051949350505050565b60005460ff1661139f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60005460ff1615611481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401611396565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586113ea3390565b60606000803373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461163d576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a811660048301528916906370a0823190602401602060405180830381865afa158015611582573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a69190611b34565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b81166004830152919350908816906370a0823190602401602060405180830381865afa158015611616573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163a9190611b34565b90505b841561166d5761166d887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611795565b6040517f6ce4074a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690636ce4074a906117039033907f0000000000000000000000000000000000000000000000000000000000000000908b90600401611b76565b6000604051808303816000875af1158015611722573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526117689190810190611c1e565b9250841561177b5761177b886001611795565b61178989898985858961186f565b50509695505050505050565b6040517f46fb371d00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660248301528381166044830152606482018390527f000000000000000000000000000000000000000000000000000000000000000016906346fb371d90608401600060405180830381600087803b15801561185357600080fd5b505af1158015611867573d6000803e3d6000fd5b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611970576040517f654a9eda00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301528681166024830152858116604483015260648201859052608482018490527f0000000000000000000000000000000000000000000000000000000000000000169063654a9eda9060a401600060405180830381600087803b15801561195357600080fd5b505af1158015611967573d6000803e3d6000fd5b50505050611867565b8015611a32576040517f0d8f9cee00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015286811660248301527f00000000000000000000000000000000000000000000000000000000000000001690630d8f9cee906044016020604051808303816000875af1158015611a0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a309190611b12565b505b6040517f51e3f16000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015285811660248301527f000000000000000000000000000000000000000000000000000000000000000016906351e3f16090604401600060405180830381600087803b158015611ac357600080fd5b505af1158015611ad7573d6000803e3d6000fd5b50505050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215611b2457600080fd5b8151801515811461113d57600080fd5b60006020828403121561076457600080fd5b60005b83811015611b61578181015183820152602001611b49565b83811115611b70576000848401525b50505050565b600073ffffffffffffffffffffffffffffffffffffffff8086168352808516602084015250606060408301528251806060840152611bbb816080850160208701611b46565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691909101608001949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611c3057600080fd5b815167ffffffffffffffff80821115611c4857600080fd5b818401915084601f830112611c5c57600080fd5b815181811115611c6e57611c6e611bef565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611cb457611cb4611bef565b81604052828152876020848701011115611ccd57600080fd5b611cde836020830160208801611b46565b97965050505050505056fea2646970667358221220dc369e84db5988a8b036ea0b665addc5aae0f6dcdbb7a2e9162014c42f41261e64736f6c634300080a00330000000000000000000000005887ad4cb2352e7f01527035faa3ae0ef2ce2b9b0000000000000000000000006f4b4ab5142787c05b7ab9a9692a0f46b997c29d
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.