More Info
Private Name Tags
ContractCreator
TokenTracker
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21412846 | 4 days ago | 0.37713771 ETH | ||||
21412846 | 4 days ago | 0.37713771 ETH | ||||
21412339 | 4 days ago | 0.321 ETH | ||||
21412339 | 4 days ago | 0.321 ETH | ||||
21403341 | 5 days ago | 0.0735 ETH | ||||
21403341 | 5 days ago | 0.0735 ETH | ||||
21398164 | 6 days ago | 1.5 ETH | ||||
21398164 | 6 days ago | 1.5 ETH | ||||
21391647 | 7 days ago | 1.00428443 ETH | ||||
21391647 | 7 days ago | 1.00428443 ETH | ||||
21315229 | 17 days ago | 0.3117 ETH | ||||
21315229 | 17 days ago | 0.3117 ETH | ||||
21315186 | 17 days ago | 0.3086 ETH | ||||
21315186 | 17 days ago | 0.3086 ETH | ||||
21310557 | 18 days ago | 0.35 ETH | ||||
21310557 | 18 days ago | 0.35 ETH | ||||
21298405 | 20 days ago | 0.17 ETH | ||||
21298405 | 20 days ago | 0.17 ETH | ||||
21297261 | 20 days ago | 1 ETH | ||||
21297261 | 20 days ago | 1 ETH | ||||
21294033 | 20 days ago | 1.02190218 ETH | ||||
21294033 | 20 days ago | 1.02190218 ETH | ||||
21293873 | 20 days ago | 2.01440142 ETH | ||||
21293873 | 20 days ago | 2.01440142 ETH | ||||
21290137 | 21 days ago | 1.1 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PoolManager
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {IAddressProvider} from 'src/interfaces/IAddressProvider.sol'; import {IACLManager} from 'src/interfaces/IACLManager.sol'; import {Constants} from 'src/libraries/helpers/Constants.sol'; import {Errors} from 'src/libraries/helpers/Errors.sol'; import {StorageSlot} from 'src/libraries/logic/StorageSlot.sol'; import {DataTypes} from 'src/libraries/types/DataTypes.sol'; import {Base} from 'src/base/Base.sol'; import {Proxy} from 'src/base/Proxy.sol'; /// @notice Main storage contract contract PoolManager is Base { string public constant name = 'BendDAO Protocol V2'; constructor(address provider_, address installerModule) { reentrancyLock = Constants.REENTRANCYLOCK__UNLOCKED; DataTypes.PoolStorage storage ps = StorageSlot.getPoolStorage(); ps.addressProvider = provider_; ps.nextPoolId = Constants.INITIAL_POOL_ID; ps.wrappedNativeToken = IAddressProvider(ps.addressProvider).getWrappedNativeToken(); require(ps.wrappedNativeToken != address(0), Errors.INVALID_ADDRESS); moduleLookup[Constants.MODULEID__INSTALLER] = installerModule; address installerProxy = _createProxy(Constants.MODULEID__INSTALLER); trustedSenders[installerProxy].moduleImpl = installerModule; } /// @notice Lookup the current implementation contract for a module /// @param moduleId Fixed constant that refers to a module type /// @return An internal address specifies the module's implementation code function moduleIdToImplementation(uint moduleId) external view returns (address) { return moduleLookup[moduleId]; } /// @notice Lookup a proxy that can be used to interact with a module (only valid for single-proxy modules) /// @param moduleId Fixed constant that refers to a module type /// @return An address that should be cast to the appropriate module interface function moduleIdToProxy(uint moduleId) external view returns (address) { return proxyLookup[moduleId]; } function dispatch() external payable reentrantOK { // only trusted proxy uint32 moduleId = trustedSenders[msg.sender].moduleId; address moduleImpl = trustedSenders[msg.sender].moduleImpl; require(moduleId != 0, Errors.PROXY_SENDER_NOT_TRUST); // multi proxy module if (moduleImpl == address(0)) moduleImpl = moduleLookup[moduleId]; uint msgDataLength = msg.data.length; require(msgDataLength >= (4 + 4 + 20), Errors.PROXY_MSGDATA_TOO_SHORT); assembly { let payloadSize := sub(calldatasize(), 4) calldatacopy(0, 4, payloadSize) mstore(payloadSize, shl(96, caller())) let result := delegatecall(gas(), moduleImpl, 0, add(payloadSize, 20), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } receive() external payable {} modifier onlyPoolAdmin() { _onlyPoolAdmin(); _; } function _onlyPoolAdmin() internal view { DataTypes.PoolStorage storage ps = StorageSlot.getPoolStorage(); IACLManager aclManager = IACLManager(IAddressProvider(ps.addressProvider).getACLManager()); require(aclManager.isPoolAdmin(msg.sender), Errors.CALLER_NOT_POOL_ADMIN); } /* @notice only used when user transfer ETH to contract by mistake */ function emergencyEtherTransfer(address to, uint256 amount) public onlyPoolAdmin { (bool success, ) = to.call{value: amount}(new bytes(0)); require(success, Errors.ETH_TRANSFER_FAILED); } /* @notice only used when user transfer ETH to module contract by mistake */ function emergencyProxyEtherTransfer(address proxyAddr, address to, uint256 amount) public onlyPoolAdmin { Proxy proxy = Proxy(payable(proxyAddr)); proxy.emergencyEtherTransfer(to, amount); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IAddressProvider { event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress); event WrappedNativeTokenUpdated(address indexed oldAddress, address indexed newAddress); event TreasuryUpdated(address indexed oldAddress, address indexed newAddress); event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress); event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress); event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress); event PoolManagerUpdated(address indexed oldAddress, address indexed newAddress); event YieldRegistryUpdated(address indexed oldAddress, address indexed newAddress); function getAddress(bytes32 id) external view returns (address); function setAddress(bytes32 id, address newAddress) external; function getWrappedNativeToken() external view returns (address); function setWrappedNativeToken(address newAddress) external; function getTreasury() external view returns (address); function setTreasury(address newAddress) external; function getACLAdmin() external view returns (address); function setACLAdmin(address newAddress) external; function getACLManager() external view returns (address); function setACLManager(address newAddress) external; function getPriceOracle() external view returns (address); function setPriceOracle(address newAddress) external; function getPoolManager() external view returns (address); function setPoolManager(address newAddress) external; function getPoolModuleImplementation(uint moduleId) external view returns (address); function getPoolModuleProxy(uint moduleId) external view returns (address); function getPoolModuleProxies(uint[] memory moduleIds) external view returns (address[] memory); function getYieldRegistry() external view returns (address); function setYieldRegistry(address newAddress) external; function getDelegateRegistryV2() external view returns (address); function setDelegateRegistryV2(address newAddress) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; /** * @title IACLManager * @notice Defines the basic interface for the ACL Manager */ interface IACLManager { /** * @notice Returns the identifier of the PoolAdmin role * @return The id of the PoolAdmin role */ function POOL_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the EmergencyAdmin role * @return The id of the EmergencyAdmin role */ function EMERGENCY_ADMIN_ROLE() external view returns (bytes32); /** * @notice Returns the identifier of the OracleAdmin role * @return The id of the OracleAdmin role */ function ORACLE_ADMIN_ROLE() external view returns (bytes32); /** * @notice Adds a new admin as PoolAdmin * @param admin The address of the new admin */ function addPoolAdmin(address admin) external; /** * @notice Removes an admin as PoolAdmin * @param admin The address of the admin to remove */ function removePoolAdmin(address admin) external; /** * @notice Returns true if the address is PoolAdmin, false otherwise * @param admin The address to check * @return True if the given address is PoolAdmin, false otherwise */ function isPoolAdmin(address admin) external view returns (bool); /** * @notice Adds a new admin as EmergencyAdmin * @param admin The address of the new admin */ function addEmergencyAdmin(address admin) external; /** * @notice Removes an admin as EmergencyAdmin * @param admin The address of the admin to remove */ function removeEmergencyAdmin(address admin) external; /** * @notice Returns true if the address is EmergencyAdmin, false otherwise * @param admin The address to check * @return True if the given address is EmergencyAdmin, false otherwise */ function isEmergencyAdmin(address admin) external view returns (bool); /** * @notice Adds a new admin as OracleAdmin * @param admin The address of the new admin */ function addOracleAdmin(address admin) external; /** * @notice Removes an admin as OracleAdmin * @param admin The address of the admin to remove */ function removeOracleAdmin(address admin) external; /** * @notice Returns true if the address is OracleAdmin, false otherwise * @param admin The address to check * @return True if the given address is OracleAdmin, false otherwise */ function isOracleAdmin(address admin) external view returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Constants { // Universal address public constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // Implementation internals uint internal constant REENTRANCYLOCK__UNLOCKED = 1; uint internal constant REENTRANCYLOCK__LOCKED = 2; // Modules // Public single-proxy modules uint internal constant MODULEID__INSTALLER = 1; uint internal constant MODULEID__CONFIGURATOR = 2; uint internal constant MODULEID__BVAULT = 3; uint internal constant MODULEID__POOL_LENS = 4; uint internal constant MODULEID__FLASHLOAN = 5; uint internal constant MODULEID__YIELD = 6; uint internal constant MODULEID__CONFIGURATOR_POOL = 7; uint internal constant MODULEID__CROSS_LENDING = 11; uint internal constant MODULEID__CROSS_LIQUIDATION = 12; uint internal constant MODULEID__ISOLATE_LENDING = 21; uint internal constant MODULEID__ISOLATE_LIQUIDATION = 22; uint internal constant MODULEID__UI_POOL_LENS = 31; uint internal constant MAX_EXTERNAL_SINGLE_PROXY_MODULEID = 499_999; // Public multi-proxy modules // uint internal constant MODULEID__xxx = 500_000; uint internal constant MAX_EXTERNAL_MODULEID = 999_999; // Internal modules // uint internal constant MODULEID__xxx = 1_000_000; // Pool params uint32 public constant INITIAL_POOL_ID = 1; // Asset params uint16 public constant MAX_COLLATERAL_FACTOR = 10000; uint16 public constant MAX_LIQUIDATION_THRESHOLD = 10000; uint16 public constant MAX_LIQUIDATION_BONUS = 10000; uint16 public constant MAX_FEE_FACTOR = 10000; uint16 public constant MAX_REDEEM_THRESHOLD = 10000; uint16 public constant MAX_BIDFINE_FACTOR = 10000; uint16 public constant MAX_MIN_BIDFINE_FACTOR = 10000; uint40 public constant MAX_AUCTION_DUARATION = 7 days; uint40 public constant MAX_YIELD_CAP_FACTOR = 10000; uint16 public constant MAX_NUMBER_OF_ASSET = 256; uint8 public constant MAX_NUMBER_OF_GROUP = 4; uint8 public constant GROUP_ID_INVALID = 255; uint8 public constant GROUP_ID_YIELD = 0; uint8 public constant GROUP_ID_LEND_MIN = 1; uint8 public constant GROUP_ID_LEND_MAX = 3; // Asset type uint8 public constant ASSET_TYPE_ERC20 = 1; uint8 public constant ASSET_TYPE_ERC721 = 2; // Supply Mode uint8 public constant SUPPLY_MODE_CROSS = 1; uint8 public constant SUPPLY_MODE_ISOLATE = 2; // Asset Lock Flag uint16 public constant ASSET_LOCK_FLAG_CROSS = 0x0001; // not used uint16 public constant ASSET_LOCK_FLAG_ISOLATE = 0x0002; // not used uint16 public constant ASSET_LOCK_FLAG_YIELD = 0x0004; // Loan Status uint8 public constant LOAN_STATUS_ACTIVE = 1; uint8 public constant LOAN_STATUS_REPAID = 2; uint8 public constant LOAN_STATUS_AUCTION = 3; uint8 public constant LOAN_STATUS_DEFAULT = 4; /** * @dev Minimum health factor to consider a user position healthy * A value of 1e18 results in 1 */ uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18; /** * @dev Default percentage of borrower's debt to be repaid in a liquidation. * @dev Percentage applied when the users health factor is above `CLOSE_FACTOR_HF_THRESHOLD` * Expressed in bps, a value of 0.5e4 results in 50.00% */ uint256 internal constant DEFAULT_LIQUIDATION_CLOSE_FACTOR = 0.5e4; /** * @dev Maximum percentage of borrower's debt to be repaid in a liquidation * @dev Percentage applied when the users health factor is below `CLOSE_FACTOR_HF_THRESHOLD` * Expressed in bps, a value of 1e4 results in 100.00% */ uint256 public constant MAX_LIQUIDATION_CLOSE_FACTOR = 1e4; /** * @dev This constant represents below which health factor value it is possible to liquidate * an amount of debt corresponding to `MAX_LIQUIDATION_CLOSE_FACTOR`. * A value of 0.95e18 results in 0.95 */ uint256 public constant CLOSE_FACTOR_HF_THRESHOLD = 0.95e18; uint256 public constant MAX_LIQUIDATION_ERC721_TOKEN_NUM = 1; // Yield Status uint8 public constant YIELD_STATUS_ACTIVE = 1; uint8 public constant YIELD_STATUS_UNSTAKE = 2; uint8 public constant YIELD_STATUS_CLAIM = 3; uint8 public constant YIELD_STATUS_REPAID = 4; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Errors { string public constant OK = '0'; string public constant EMPTY_ERROR = '1'; string public constant ETH_TRANSFER_FAILED = '2'; string public constant TOKEN_TRANSFER_FAILED = '3'; string public constant MSG_VALUE_NOT_ZERO = '4'; string public constant TOKEN_ALLOWANCE_INSUFFICIENT = '5'; string public constant TOKEN_BALANCE_INSUFFICIENT = '6'; string public constant REENTRANCY_ALREADY_LOCKED = '10'; string public constant PROXY_INVALID_MODULE = '30'; string public constant PROXY_INTERNAL_MODULE = '31'; string public constant PROXY_SENDER_NOT_TRUST = '32'; string public constant PROXY_MSGDATA_TOO_SHORT = '33'; string public constant INVALID_AMOUNT = '100'; string public constant INVALID_SCALED_AMOUNT = '101'; string public constant INVALID_TRANSFER_AMOUNT = '102'; string public constant INVALID_ADDRESS = '103'; string public constant INVALID_FROM_ADDRESS = '104'; string public constant INVALID_TO_ADDRESS = '105'; string public constant INVALID_SUPPLY_MODE = '106'; string public constant INVALID_ASSET_TYPE = '107'; string public constant INVALID_POOL_ID = '108'; string public constant INVALID_GROUP_ID = '109'; string public constant INVALID_ASSET_ID = '110'; string public constant INVALID_ASSET_DECIMALS = '111'; string public constant INVALID_IRM_ADDRESS = '112'; string public constant INVALID_CALLER = '113'; string public constant INVALID_ID_LIST = '114'; string public constant INVALID_COLLATERAL_AMOUNT = '115'; string public constant INVALID_BORROW_AMOUNT = '116'; string public constant INVALID_TOKEN_OWNER = '117'; string public constant INVALID_YIELD_STAKER = '118'; string public constant INCONSISTENT_PARAMS_LENGTH = '119'; string public constant INVALID_LOAN_STATUS = '120'; string public constant ARRAY_HAS_DUP_ELEMENT = '121'; string public constant INVALID_ONBEHALF_ADDRESS = '122'; string public constant SAME_ONBEHALF_ADDRESS = '123'; string public constant INVALID_OPTIMAL_USAGE_RATIO = '124'; string public constant SLOPE_2_MUST_BE_GTE_SLOPE_1 = '125'; string public constant INVALID_MAX_RATE = '126'; string public constant INVALID_RATE_MODEL = '127'; string public constant ENUM_SET_ADD_FAILED = '150'; string public constant ENUM_SET_REMOVE_FAILED = '151'; string public constant ACL_ADMIN_CANNOT_BE_ZERO = '200'; string public constant ACL_MANAGER_CANNOT_BE_ZERO = '201'; string public constant CALLER_NOT_ORACLE_ADMIN = '202'; string public constant CALLER_NOT_POOL_ADMIN = '203'; string public constant CALLER_NOT_EMERGENCY_ADMIN = '204'; string public constant OWNER_CANNOT_BE_ZERO = '205'; string public constant INVALID_ASSET_PARAMS = '206'; string public constant FLASH_LOAN_EXEC_FAILED = '207'; string public constant TREASURY_CANNOT_BE_ZERO = '208'; string public constant PRICE_ORACLE_CANNOT_BE_ZERO = '209'; string public constant ADDR_PROVIDER_CANNOT_BE_ZERO = '210'; string public constant SENDER_NOT_APPROVED = '211'; string public constant SENDER_RECEIVER_NOT_SAME = '212'; string public constant POOL_ALREADY_EXISTS = '300'; string public constant POOL_NOT_EXISTS = '301'; string public constant POOL_IS_PAUSED = '302'; string public constant POOL_YIELD_ALREADY_ENABLE = '303'; string public constant POOL_YIELD_NOT_ENABLE = '304'; string public constant POOL_YIELD_IS_PAUSED = '305'; string public constant GROUP_ALREADY_EXISTS = '320'; string public constant GROUP_NOT_EXISTS = '321'; string public constant GROUP_LIST_NOT_EMPTY = '322'; string public constant GROUP_LIST_IS_EMPTY = '323'; string public constant GROUP_NUMBER_EXCEED_MAX_LIMIT = '324'; string public constant GROUP_USED_BY_ASSET = '325'; string public constant ASSET_ALREADY_EXISTS = '340'; string public constant ASSET_NOT_EXISTS = '341'; string public constant ASSET_LIST_NOT_EMPTY = '342'; string public constant ASSET_NUMBER_EXCEED_MAX_LIMIT = '343'; string public constant ASSET_AGGREGATOR_NOT_EXIST = '344'; string public constant ASSET_PRICE_IS_ZERO = '345'; string public constant ASSET_TYPE_NOT_ERC20 = '346'; string public constant ASSET_TYPE_NOT_ERC721 = '347'; string public constant ASSET_NOT_ACTIVE = '348'; string public constant ASSET_IS_PAUSED = '349'; string public constant ASSET_IS_FROZEN = '350'; string public constant ASSET_IS_BORROW_DISABLED = '351'; string public constant ASSET_NOT_CROSS_MODE = '352'; string public constant ASSET_NOT_ISOLATE_MODE = '353'; string public constant ASSET_YIELD_ALREADY_ENABLE = '354'; string public constant ASSET_YIELD_NOT_ENABLE = '355'; string public constant ASSET_YIELD_IS_PAUSED = '356'; string public constant ASSET_INSUFFICIENT_LIQUIDITY = '357'; string public constant ASSET_INSUFFICIENT_BIDAMOUNT = '358'; string public constant ASSET_ALREADY_LOCKED_IN_USE = '359'; string public constant ASSET_SUPPLY_CAP_EXCEEDED = '360'; string public constant ASSET_BORROW_CAP_EXCEEDED = '361'; string public constant ASSET_IS_FLASHLOAN_DISABLED = '362'; string public constant ASSET_SUPPLY_MODE_IS_SAME = '363'; string public constant ASSET_TOKEN_ALREADY_EXISTS = '364'; string public constant ASSET_LIQUIDITY_NOT_ZERO = '365'; string public constant HEALTH_FACTOR_BELOW_LIQUIDATION_THRESHOLD = '400'; string public constant HEALTH_FACTOR_NOT_BELOW_LIQUIDATION_THRESHOLD = '401'; string public constant CROSS_SUPPLY_NOT_EMPTY = '402'; string public constant ISOLATE_SUPPLY_NOT_EMPTY = '403'; string public constant CROSS_BORROW_NOT_EMPTY = '404'; string public constant ISOLATE_BORROW_NOT_EMPTY = '405'; string public constant COLLATERAL_BALANCE_IS_ZERO = '406'; string public constant BORROW_BALANCE_IS_ZERO = '407'; string public constant LTV_VALIDATION_FAILED = '408'; string public constant COLLATERAL_CANNOT_COVER_NEW_BORROW = '409'; string public constant LIQUIDATE_REPAY_DEBT_FAILED = '410'; string public constant ORACLE_PRICE_IS_STALE = '411'; string public constant LIQUIDATION_EXCEED_MAX_TOKEN_NUM = '412'; string public constant USER_COLLATERAL_SUPPLY_ZERO = '413'; string public constant ACTUAL_COLLATERAL_TO_LIQUIDATE_ZERO = '414'; string public constant ACTUAL_DEBT_TO_LIQUIDATE_ZERO = '415'; string public constant USER_DEBT_BORROWED_ZERO = '416'; string public constant YIELD_EXCEED_ASSET_CAP_LIMIT = '500'; string public constant YIELD_EXCEED_STAKER_CAP_LIMIT = '501'; string public constant YIELD_TOKEN_ALREADY_LOCKED = '502'; string public constant YIELD_ACCOUNT_NOT_EXIST = '503'; string public constant YIELD_ACCOUNT_ALREADY_EXIST = '504'; string public constant YIELD_REGISTRY_IS_NOT_AUTH = '505'; string public constant YIELD_MANAGER_IS_NOT_AUTH = '506'; string public constant YIELD_ACCOUNT_IMPL_ZERO = '507'; string public constant YIELD_TOKEN_LOCKED_BY_OTHER = '508'; string public constant ISOLATE_LOAN_ASSET_NOT_MATCH = '600'; string public constant ISOLATE_LOAN_GROUP_NOT_MATCH = '601'; string public constant ISOLATE_LOAN_OWNER_NOT_MATCH = '602'; string public constant ISOLATE_BORROW_NOT_EXCEED_LIQUIDATION_THRESHOLD = '603'; string public constant ISOLATE_BID_PRICE_LESS_THAN_BORROW = '604'; string public constant ISOLATE_BID_PRICE_LESS_THAN_LIQUIDATION_PRICE = '605'; string public constant ISOLATE_BID_PRICE_LESS_THAN_HIGHEST_PRICE = '606'; string public constant ISOLATE_BID_AUCTION_DURATION_HAS_END = '607'; string public constant ISOLATE_BID_AUCTION_DURATION_NOT_END = '608'; string public constant ISOLATE_LOAN_BORROW_AMOUNT_NOT_COVER = '609'; string public constant ISOLATE_LOAN_EXISTS = '610'; string public constant ISOLATE_LOAN_BIDDER_NOT_SAME = '611'; // Yield Staking, don't care about the ETH string public constant YIELD_ETH_NFT_NOT_ACTIVE = '1000'; string public constant YIELD_ETH_POOL_NOT_SAME = '1001'; string public constant YIELD_ETH_STATUS_NOT_ACTIVE = '1002'; string public constant YIELD_ETH_STATUS_NOT_UNSTAKE = '1003'; string public constant YIELD_ETH_NFT_ALREADY_USED = '1004'; string public constant YIELD_ETH_NFT_NOT_USED_BY_ME = '1005'; string public constant YIELD_ETH_EXCEED_MAX_BORROWABLE = '1006'; string public constant YIELD_ETH_HEATH_FACTOR_TOO_LOW = '1007'; string public constant YIELD_ETH_HEATH_FACTOR_TOO_HIGH = '1008'; string public constant YIELD_ETH_EXCEED_MAX_FINE = '1009'; string public constant YIELD_ETH_WITHDRAW_NOT_READY = '1010'; string public constant YIELD_ETH_DEPOSIT_FAILED = '1011'; string public constant YIELD_ETH_WITHDRAW_FAILED = '1012'; string public constant YIELD_ETH_CLAIM_FAILED = '1013'; string public constant YIELD_ETH_ACCOUNT_INSUFFICIENT = '1014'; string public constant YIELD_ETH_LT_MIN_AMOUNT = '1015'; string public constant YIELD_ETH_GT_MAX_AMOUNT = '1016'; string public constant YIELD_ETH_NFT_LEVERAGE_FACTOR_ZERO = '1017'; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {DataTypes} from '../types/DataTypes.sol'; library StorageSlot { // keccak256(abi.encode(uint256(keccak256("benddao.storage.v2.pool")) - 1)) & ~bytes32(uint256(0xff)); bytes32 constant STORAGE_POSITION_POOL = 0xce044ef5c897ad3fe9fcce02f9f2b7dc69de8685dee403b46b4b685baa720200; function getPoolStorage() internal pure returns (DataTypes.PoolStorage storage rs) { bytes32 position = STORAGE_POSITION_POOL; assembly { rs.slot := position } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {EnumerableSetUpgradeable} from '@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol'; library DataTypes { /****************************************************************************/ /* Data Types for Pool Lending */ struct PoolData { uint32 poolId; string name; bool isPaused; // group mapping(uint8 => bool) enabledGroups; EnumerableSetUpgradeable.UintSet groupList; // underlying asset to asset data mapping(address => AssetData) assetLookup; EnumerableSetUpgradeable.AddressSet assetList; // nft address -> nft id -> isolate loan mapping(address => mapping(uint256 => IsolateLoanData)) loanLookup; // account data mapping(address => AccountData) accountLookup; // yield bool isYieldEnabled; bool isYieldPaused; uint8 yieldGroup; } struct AccountData { EnumerableSetUpgradeable.AddressSet suppliedAssets; EnumerableSetUpgradeable.AddressSet borrowedAssets; // asset => operator => approved mapping(address => mapping(address => bool)) operatorAuthorizations; } struct GroupData { // config parameters address rateModel; // user state uint256 totalScaledCrossBorrow; mapping(address => uint256) userScaledCrossBorrow; uint256 totalScaledIsolateBorrow; mapping(address => uint256) userScaledIsolateBorrow; // interest state uint128 borrowRate; uint128 borrowIndex; uint8 groupId; } struct ERC721TokenData { address owner; uint8 supplyMode; // 0=cross margin, 1=isolate address lockerAddr; } struct YieldManagerData { uint256 yieldCap; // percentage, 500 -> 5% } struct AssetData { // config params address underlyingAsset; uint8 assetType; // See ASSET_TYPE_xxx uint8 underlyingDecimals; // only for ERC20 uint8 classGroup; bool isActive; bool isFrozen; bool isPaused; bool isBorrowingEnabled; bool isFlashLoanEnabled; bool isYieldEnabled; bool isYieldPaused; uint16 feeFactor; uint16 collateralFactor; uint16 liquidationThreshold; uint16 liquidationBonus; uint16 redeemThreshold; uint16 bidFineFactor; uint16 minBidFineFactor; uint40 auctionDuration; uint256 supplyCap; // amount with token decimals, 100e18 -> 100 uint256 borrowCap; // amount with token decimals uint256 yieldCap; // percentage, 500 -> 5% // group state mapping(uint8 => GroupData) groupLookup; EnumerableSetUpgradeable.UintSet groupList; // user state uint256 totalScaledCrossSupply; // total supplied balance in cross margin mode uint256 totalScaledIsolateSupply; // total supplied balance in isolate mode, only for ERC721 uint256 availableLiquidity; uint256 totalBidAmout; mapping(address => uint256) userScaledCrossSupply; // user supplied balance in cross margin mode mapping(address => uint256) userScaledIsolateSupply; // user supplied balance in isolate mode, only for ERC721 mapping(uint256 => ERC721TokenData) erc721TokenData; // token -> data, only for ERC721 // asset interest state uint128 supplyRate; uint128 supplyIndex; uint256 accruedFee; // as treasury supplied balance in cross mode uint40 lastUpdateTimestamp; // yield state mapping(address => YieldManagerData) yieldManagerLookup; } struct IsolateLoanData { address reserveAsset; uint256 scaledAmount; uint8 reserveGroup; uint8 loanStatus; uint40 bidStartTimestamp; address firstBidder; address lastBidder; uint256 bidAmount; } /****************************************************************************/ /* Data Types for Storage */ struct PoolStorage { // common fileds address addressProvider; address wrappedNativeToken; // WETH // pool fields uint32 nextPoolId; mapping(uint32 => PoolData) poolLookup; EnumerableSetUpgradeable.UintSet poolList; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {Pausable} from '@openzeppelin/contracts/security/Pausable.sol'; import {ERC721Holder} from '@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol'; import {Constants} from 'src/libraries/helpers/Constants.sol'; import {Events} from 'src/libraries/helpers/Events.sol'; import {Errors} from 'src/libraries/helpers/Errors.sol'; import {Storage} from 'src/base/Storage.sol'; import {Proxy} from 'src/base/Proxy.sol'; abstract contract Base is Storage, Pausable, ERC721Holder { constructor() { reentrancyLock = Constants.REENTRANCYLOCK__UNLOCKED; } // Modules function _createProxy(uint proxyModuleId) internal returns (address) { require(proxyModuleId != 0, Errors.PROXY_INVALID_MODULE); require(proxyModuleId <= Constants.MAX_EXTERNAL_MODULEID, Errors.PROXY_INTERNAL_MODULE); // If we've already created a proxy for a single-proxy module, just return it: if (proxyLookup[proxyModuleId] != address(0)) return proxyLookup[proxyModuleId]; // Otherwise create a proxy: address proxyAddr = address(new Proxy()); if (proxyModuleId <= Constants.MAX_EXTERNAL_SINGLE_PROXY_MODULEID) proxyLookup[proxyModuleId] = proxyAddr; trustedSenders[proxyAddr] = TrustedSenderInfo({moduleId: uint32(proxyModuleId), moduleImpl: address(0)}); emit Events.ProxyCreated(proxyAddr, proxyModuleId); return proxyAddr; } function callInternalModule(uint moduleId, bytes memory input) internal returns (bytes memory) { (bool success, bytes memory result) = moduleLookup[moduleId].delegatecall(input); if (!success) revertBytes(result); return result; } // Modifiers modifier nonReentrant() { require(reentrancyLock == Constants.REENTRANCYLOCK__UNLOCKED, Errors.REENTRANCY_ALREADY_LOCKED); reentrancyLock = Constants.REENTRANCYLOCK__LOCKED; _; reentrancyLock = Constants.REENTRANCYLOCK__UNLOCKED; } modifier reentrantOK() { // documentation only _; } // Used to flag functions which do not modify storage, but do perform a delegate call // to a view function, which prohibits a standard view modifier. The flag is used to // patch state mutability in compiled ABIs and interfaces. modifier staticDelegate() { _; } // Error handling function revertBytes(bytes memory errMsg) internal pure { if (errMsg.length > 0) { assembly { revert(add(32, errMsg), mload(errMsg)) } } revert(Errors.EMPTY_ERROR); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; contract Proxy { address immutable creator; constructor() { creator = msg.sender; } // External interface receive() external payable {} fallback() external payable { address creator_ = creator; uint value = msg.value; if (msg.sender == creator_) { assembly { mstore(0, 0) calldatacopy(31, 0, calldatasize()) switch mload(0) // numTopics case 0 { log0(32, sub(calldatasize(), 1)) } case 1 { log1(64, sub(calldatasize(), 33), mload(32)) } case 2 { log2(96, sub(calldatasize(), 65), mload(32), mload(64)) } case 3 { log3(128, sub(calldatasize(), 97), mload(32), mload(64), mload(96)) } case 4 { log4(160, sub(calldatasize(), 129), mload(32), mload(64), mload(96), mload(128)) } default { revert(0, 0) } return(0, 0) } } else { assembly { mstore(0, 0xe9c4a3ac00000000000000000000000000000000000000000000000000000000) // dispatch() selector calldatacopy(4, 0, calldatasize()) mstore(add(4, calldatasize()), shl(96, caller())) let result := call(gas(), creator_, value, 0, add(24, calldatasize()), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } } /* @notice only used when user transfer ETH to contract by mistake */ function emergencyEtherTransfer(address to, uint256 amount) public { require(msg.sender == creator, 'Invalid caller'); (bool success, ) = to.call{value: amount}(new bytes(0)); require(success, 'ETH_TRANSFER_FAILED'); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (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 Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { 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 // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; import "../IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Events { // Modeuls Events event ProxyCreated(address indexed proxy, uint moduleId); event InstallerSetUpgradeAdmin(address indexed newUpgradeAdmin); event InstallerSetGovernorAdmin(address indexed newGovernorAdmin); event InstallerInstallModule(uint indexed moduleId, address indexed moduleImpl, bytes32 moduleGitCommit); /* Oracle Events */ event AssetAggregatorUpdated(address indexed asset, address aggregator); event BendNFTOracleUpdated(address bendNFTOracle); /* Pool Events */ event CreatePool(uint32 indexed poolId, string name); event DeletePool(uint32 indexed poolId); event SetPoolName(uint32 indexed poolId, string name); event AddPoolGroup(uint32 indexed poolId, uint8 groupId); event RemovePoolGroup(uint32 indexed poolId, uint8 groupId); event SetPoolPause(uint32 indexed poolId, bool isPause); event CollectFeeToTreasury(uint32 indexed poolId, address indexed asset, uint256 fee, uint256 index); event SetPoolYieldEnable(uint32 indexed poolId, bool isEnable); event SetPoolYieldPause(uint32 indexed poolId, bool isPause); /* Asset Events */ event AssetInterestSupplyDataUpdated( uint32 indexed poolId, address indexed asset, uint256 supplyRate, uint256 supplyIndex ); event AssetInterestBorrowDataUpdated( uint32 indexed poolId, address indexed asset, uint256 groupId, uint256 borrowRate, uint256 borrowIndex ); event AddAsset(uint32 indexed poolId, address indexed asset, uint8 assetType); event RemoveAsset(uint32 indexed poolId, address indexed asset, uint8 assetType); event AddAssetGroup(uint32 indexed poolId, address indexed asset, uint8 groupId); event RemoveAssetGroup(uint32 indexed poolId, address indexed asset, uint8 groupId); event SetAssetActive(uint32 indexed poolId, address indexed asset, bool isActive); event SetAssetFrozen(uint32 indexed poolId, address indexed asset, bool isFrozen); event SetAssetPause(uint32 indexed poolId, address indexed asset, bool isPause); event SetAssetBorrowing(uint32 indexed poolId, address indexed asset, bool isEnable); event SetAssetFlashLoan(uint32 indexed poolId, address indexed asset, bool isEnable); event SetAssetSupplyCap(uint32 indexed poolId, address indexed asset, uint256 newCap); event SetAssetBorrowCap(uint32 indexed poolId, address indexed asset, uint256 newCap); event SetAssetClassGroup(uint32 indexed poolId, address indexed asset, uint8 groupId); event SetAssetCollateralParams( uint32 indexed poolId, address indexed asset, uint16 collateralFactor, uint16 liquidationThreshold, uint16 liquidationBonus ); event SetAssetAuctionParams( uint32 indexed poolId, address indexed asset, uint16 redeemThreshold, uint16 bidFineFactor, uint16 minBidFineFactor, uint40 auctionDuration ); event SetAssetProtocolFee(uint32 indexed poolId, address indexed asset, uint16 feeFactor); event SetAssetLendingRate(uint32 indexed poolId, address indexed asset, uint8 groupId, address rateModel); event SetAssetYieldEnable(uint32 indexed poolId, address indexed asset, bool isEnable); event SetAssetYieldPause(uint32 indexed poolId, address indexed asset, bool isPause); event SetAssetYieldCap(uint32 indexed poolId, address indexed asset, uint256 newCap); event SetAssetYieldRate(uint32 indexed poolId, address indexed asset, address rateModel); event SetManagerYieldCap(uint32 indexed poolId, address indexed staker, address indexed asset, uint256 newCap); /* Supply Events */ event DepositERC20( address indexed sender, uint256 indexed poolId, address indexed asset, uint256 amount, address onBehalf ); event WithdrawERC20( address indexed sender, uint256 indexed poolId, address indexed asset, uint256 amount, address onBehalf, address receiver ); event DepositERC721( address indexed sender, uint256 indexed poolId, address indexed asset, uint256[] tokenIds, uint8 supplyMode, address onBehalf ); event WithdrawERC721( address indexed sender, uint256 indexed poolId, address indexed asset, uint256[] tokenIds, uint8 supplyMode, address onBehalf, address receiver ); event SetERC721SupplyMode( address indexed sender, uint256 indexed poolId, address indexed asset, uint256[] tokenIds, uint8 supplyMode, address onBehalf ); // Cross Lending Events event CrossBorrowERC20( address indexed sender, uint256 indexed poolId, address indexed asset, uint8[] groups, uint256[] amounts, address onBehalf, address receiver ); event CrossRepayERC20( address indexed sender, uint256 indexed poolId, address indexed asset, uint8[] groups, uint256[] amounts, address onBehalf ); event CrossLiquidateERC20( address indexed liquidator, uint256 indexed poolId, address indexed user, address collateralAsset, address debtAsset, uint256 debtToCover, uint256 liquidatedCollateralAmount, bool supplyAsCollateral ); event CrossLiquidateERC721( address indexed liquidator, uint256 indexed poolId, address indexed user, address collateralAsset, uint256[] liquidatedCollateralTokenIds, address debtAsset, uint256 liquidatedDebtAmount, bool supplyAsCollateral ); // Isolate Lending Events event IsolateBorrow( address indexed sender, uint256 indexed poolId, address indexed nftAsset, uint256[] tokenIds, address debtAsset, uint256[] amounts, address onBehalf, address receiver ); event IsolateRepay( address indexed sender, uint256 indexed poolId, address indexed nftAsset, uint256[] tokenIds, address debtAsset, uint256[] amounts, address onBehalf ); event IsolateAuction( address indexed sender, uint256 indexed poolId, address indexed nftAsset, uint256[] tokenIds, address debtAsset, uint256[] bidAmounts ); event IsolateRedeem( address indexed sender, uint256 indexed poolId, address indexed nftAsset, uint256[] tokenIds, address debtAsset, uint256[] redeemAmounts, uint256[] bidFines ); event IsolateLiquidate( address indexed sender, uint256 indexed poolId, address indexed nftAsset, uint256[] tokenIds, address debtAsset, uint256[] extraAmounts, uint256[] remainAmounts, bool supplyAsCollateral ); /* Yield Events */ event YieldBorrowERC20(address indexed sender, uint256 indexed poolId, address indexed asset, uint256 amount); event YieldRepayERC20(address indexed sender, uint256 indexed poolId, address indexed asset, uint256 amount); // Misc Events event FlashLoanERC20( address indexed sender, uint32 indexed poolId, address[] assets, uint256[] amounts, address receiverAddress ); event FlashLoanERC721( address indexed sender, uint32 indexed poolId, address[] nftAssets, uint256[] nftTokenIds, address receiverAddress ); event SetAuthorization( address indexed sender, uint32 indexed poolId, address indexed asset, address operator, bool approved ); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {StorageSlot} from 'src/libraries/logic/StorageSlot.sol'; import {DataTypes} from 'src/libraries/types/DataTypes.sol'; abstract contract Storage { // Dispatcher and upgrades uint internal reentrancyLock; mapping(uint => address) moduleLookup; // moduleId => module implementation mapping(uint => address) proxyLookup; // moduleId => proxy address (only for single-proxy modules) struct TrustedSenderInfo { uint32 moduleId; // 0 = un-trusted address moduleImpl; // only non-zero for external single-proxy modules } mapping(address => TrustedSenderInfo) trustedSenders; // sender address => moduleId (0 = un-trusted) /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[46] private __gap; // Services function getPoolStorage() internal pure returns (DataTypes.PoolStorage storage rs) { return StorageSlot.getPoolStorage(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
{ "remappings": [ "src/=src/", "test/=test/", "config/=config/", "@ds-test/=lib/forge-std/lib/ds-test/src/", "@forge-std/=lib/forge-std/src/", "@openzeppelin/=node_modules/@openzeppelin/", "@chainlink/=node_modules/@chainlink/", "@eth-gas-reporter/=node_modules/eth-gas-reporter/", "@hardhat/=node_modules/hardhat/", "@eth-optimism/=node_modules/@eth-optimism/", "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "hardhat/=node_modules/hardhat/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "debug": { "revertStrings": "default" }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"provider_","type":"address"},{"internalType":"address","name":"installerModule","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proxy","type":"address"},{"indexed":false,"internalType":"uint256","name":"moduleId","type":"uint256"}],"name":"ProxyCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyEtherTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddr","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyProxyEtherTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moduleId","type":"uint256"}],"name":"moduleIdToImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"moduleId","type":"uint256"}],"name":"moduleIdToProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50604051610fdc380380610fdc83398101604081905261002f916103dc565b6032805460ff1916905560016000557fce044ef5c897ad3fe9fcce02f9f2b7dc69de8685dee403b46b4b685baa72020080546001600160a01b0384166001600160a01b0319909116811782557fce044ef5c897ad3fe9fcce02f9f2b7dc69de8685dee403b46b4b685baa720201805463ffffffff60a01b1916600160a01b17905560408051630eca3c5b60e11b81529051631d9478b6916004808201926020929091908290030181865afa1580156100eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010f919061040f565b6001820180546001600160a01b0319166001600160a01b0392909216918217905560408051808201909152600381526231303360e81b6020820152906101715760405162461bcd60e51b81526004016101689190610431565b60405180910390fd5b506001600081815260208290527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b0319166001600160a01b038616179055906101c290610204565b6001600160a01b03908116600090815260036020526040902080549190941664010000000002600160201b600160c01b03199091161790925550610480915050565b604080518082019091526002815261033360f41b60208201526000908261023e5760405162461bcd60e51b81526004016101689190610431565b50604080518082019091526002815261333160f01b6020820152620f423f83111561027c5760405162461bcd60e51b81526004016101689190610431565b506000828152600260205260409020546001600160a01b0316156102b657506000908152600260205260409020546001600160a01b031690565b60006040516102c4906103b3565b604051809103906000f0801580156102e0573d6000803e3d6000fd5b5090506207a11f831161031557600083815260026020526040902080546001600160a01b0319166001600160a01b0383161790555b60408051808201825263ffffffff8086168252600060208084018281526001600160a01b03878116808552600390935292869020945185549151909316640100000000026001600160c01b031990911692909316919091179190911790915590517f6c6ffd7df9a0cfaa14ee2cf752003968de6c340564276242aa48ca641b09bce4906103a59086815260200190565b60405180910390a292915050565b61034280610c9a83390190565b80516001600160a01b03811681146103d757600080fd5b919050565b600080604083850312156103ef57600080fd5b6103f8836103c0565b9150610406602084016103c0565b90509250929050565b60006020828403121561042157600080fd5b61042a826103c0565b9392505050565b60006020808352835180602085015260005b8181101561045f57858101830151858201604001528201610443565b506000604082860101526040601f19601f8301168501019250505092915050565b61080b8061048f6000396000f3fe60806040526004361061007f5760003560e01c8063734c938f1161004e578063734c938f14610169578063cab65f01146101b7578063e9c4a3ac146101ed578063eed88b8d146101f557600080fd5b806306fdde031461008b578063150b7a02146100e05780635bfad5af146101245780635c975abb1461014657600080fd5b3661008657005b600080fd5b34801561009757600080fd5b506100ca604051806040016040528060138152602001722132b7322220a790283937ba37b1b7b6102b1960691b81525081565b6040516100d791906105ac565b60405180910390f35b3480156100ec57600080fd5b5061010b6100fb36600461060d565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016100d7565b34801561013057600080fd5b5061014461013f3660046106ed565b610215565b005b34801561015257600080fd5b5060325460ff1660405190151581526020016100d7565b34801561017557600080fd5b5061019f61018436600461072e565b6000908152600260205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016100d7565b3480156101c357600080fd5b5061019f6101d236600461072e565b6000908152600160205260409020546001600160a01b031690565b610144610288565b34801561020157600080fd5b50610144610210366004610747565b610399565b61021d610450565b60405163eed88b8d60e01b81526001600160a01b0383811660048301526024820183905284919082169063eed88b8d90604401600060405180830381600087803b15801561026a57600080fd5b505af115801561027e573d6000803e3d6000fd5b5050505050505050565b336000908152600360209081526040918290205482518084019093526002835261199960f11b9183019190915263ffffffff8116916401000000009091046001600160a01b031690826102f75760405162461bcd60e51b81526004016102ee91906105ac565b60405180910390fd5b506001600160a01b038116610327575063ffffffff81166000908152600160205260409020546001600160a01b03165b604080518082019091526002815261333360f01b60208201523690601c8210156103645760405162461bcd60e51b81526004016102ee91906105ac565b50600436038060046000373360601b8152600080601483016000865af490503d6000803e808015610394573d6000f35b3d6000fd5b6103a1610450565b604080516000808252602082019092526001600160a01b0384169083906040516103cb9190610773565b60006040518083038185875af1925050503d8060008114610408576040519150601f19603f3d011682016040523d82523d6000602084013e61040d565b606091505b5050905080604051806040016040528060018152602001601960f91b8152509061044a5760405162461bcd60e51b81526004016102ee91906105ac565b50505050565b7fce044ef5c897ad3fe9fcce02f9f2b7dc69de8685dee403b46b4b685baa72020080546040805163383e6b8b60e11b815290516000926001600160a01b03169163707cd7169160048083019260209291908290030181865afa1580156104ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104de919061078f565b604051637be53ca160e01b81523360048201529091506001600160a01b03821690637be53ca190602401602060405180830381865afa158015610525573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054991906107b3565b6040518060400160405280600381526020016232303360e81b815250906105835760405162461bcd60e51b81526004016102ee91906105ac565b505050565b60005b838110156105a357818101518382015260200161058b565b50506000910152565b60208152600082518060208401526105cb816040850160208701610588565b601f01601f19169190910160400192915050565b6001600160a01b03811681146105f457600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561062357600080fd5b843561062e816105df565b9350602085013561063e816105df565b925060408501359150606085013567ffffffffffffffff8082111561066257600080fd5b818701915087601f83011261067657600080fd5b813581811115610688576106886105f7565b604051601f8201601f19908116603f011681019083821181831017156106b0576106b06105f7565b816040528281528a60208487010111156106c957600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060006060848603121561070257600080fd5b833561070d816105df565b9250602084013561071d816105df565b929592945050506040919091013590565b60006020828403121561074057600080fd5b5035919050565b6000806040838503121561075a57600080fd5b8235610765816105df565b946020939093013593505050565b60008251610785818460208701610588565b9190910192915050565b6000602082840312156107a157600080fd5b81516107ac816105df565b9392505050565b6000602082840312156107c557600080fd5b815180151581146107ac57600080fdfea2646970667358221220267a087dacb3ad5758daff8be59841bf10a8048066a5421215cbee8eea3d235064736f6c6343000819003360a0604052348015600f57600080fd5b503360805260805161030d61003560003960008181602b0152610155015261030d6000f3fe6080604052600436106100225760003560e01c8063eed88b8d1461012f57610029565b3661002957005b7f0000000000000000000000000000000000000000000000000000000000000000346001600160a01b03821633036100f05760008081523681601f3780518015610091576001811461009e57600281146100ae57600381146100c157600481146100d7578182fd5b36600019016020a0508081f35b60205136602019016040a1508081f35b60405160205136604019016060a2508081f35b60605160405160205136606019016080a3508081f35b608051606051604051602051366080190160a0a4508081f35b633a7128eb60e21b6000523660006004373360601b366004015260008036601801600084865af13d6000803e808015610128573d6000f35b3d6000fd5b005b34801561013b57600080fd5b5061012d61014a366004610270565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101b85760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21031b0b63632b960911b60448201526064015b60405180910390fd5b604080516000808252602082019092526001600160a01b0384169083906040516101e291906102a8565b60006040518083038185875af1925050503d806000811461021f576040519150601f19603f3d011682016040523d82523d6000602084013e610224565b606091505b505090508061026b5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b60448201526064016101af565b505050565b6000806040838503121561028357600080fd5b82356001600160a01b038116811461029a57600080fd5b946020939093013593505050565b6000825160005b818110156102c957602081860181015185830152016102af565b50600092019182525091905056fea2646970667358221220052b67e8ec362052f26c829550bcb42a8f7fe5414661d70bb3ba4bff2ca5fb9964736f6c63430008190033000000000000000000000000a9afc955d549d43db056655b98fab02870a45fcd000000000000000000000000ca1b6dc58c8fe92c4ced26a5e083a1ceeb728226
Deployed Bytecode
0x60806040526004361061007f5760003560e01c8063734c938f1161004e578063734c938f14610169578063cab65f01146101b7578063e9c4a3ac146101ed578063eed88b8d146101f557600080fd5b806306fdde031461008b578063150b7a02146100e05780635bfad5af146101245780635c975abb1461014657600080fd5b3661008657005b600080fd5b34801561009757600080fd5b506100ca604051806040016040528060138152602001722132b7322220a790283937ba37b1b7b6102b1960691b81525081565b6040516100d791906105ac565b60405180910390f35b3480156100ec57600080fd5b5061010b6100fb36600461060d565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016100d7565b34801561013057600080fd5b5061014461013f3660046106ed565b610215565b005b34801561015257600080fd5b5060325460ff1660405190151581526020016100d7565b34801561017557600080fd5b5061019f61018436600461072e565b6000908152600260205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016100d7565b3480156101c357600080fd5b5061019f6101d236600461072e565b6000908152600160205260409020546001600160a01b031690565b610144610288565b34801561020157600080fd5b50610144610210366004610747565b610399565b61021d610450565b60405163eed88b8d60e01b81526001600160a01b0383811660048301526024820183905284919082169063eed88b8d90604401600060405180830381600087803b15801561026a57600080fd5b505af115801561027e573d6000803e3d6000fd5b5050505050505050565b336000908152600360209081526040918290205482518084019093526002835261199960f11b9183019190915263ffffffff8116916401000000009091046001600160a01b031690826102f75760405162461bcd60e51b81526004016102ee91906105ac565b60405180910390fd5b506001600160a01b038116610327575063ffffffff81166000908152600160205260409020546001600160a01b03165b604080518082019091526002815261333360f01b60208201523690601c8210156103645760405162461bcd60e51b81526004016102ee91906105ac565b50600436038060046000373360601b8152600080601483016000865af490503d6000803e808015610394573d6000f35b3d6000fd5b6103a1610450565b604080516000808252602082019092526001600160a01b0384169083906040516103cb9190610773565b60006040518083038185875af1925050503d8060008114610408576040519150601f19603f3d011682016040523d82523d6000602084013e61040d565b606091505b5050905080604051806040016040528060018152602001601960f91b8152509061044a5760405162461bcd60e51b81526004016102ee91906105ac565b50505050565b7fce044ef5c897ad3fe9fcce02f9f2b7dc69de8685dee403b46b4b685baa72020080546040805163383e6b8b60e11b815290516000926001600160a01b03169163707cd7169160048083019260209291908290030181865afa1580156104ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104de919061078f565b604051637be53ca160e01b81523360048201529091506001600160a01b03821690637be53ca190602401602060405180830381865afa158015610525573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054991906107b3565b6040518060400160405280600381526020016232303360e81b815250906105835760405162461bcd60e51b81526004016102ee91906105ac565b505050565b60005b838110156105a357818101518382015260200161058b565b50506000910152565b60208152600082518060208401526105cb816040850160208701610588565b601f01601f19169190910160400192915050565b6001600160a01b03811681146105f457600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561062357600080fd5b843561062e816105df565b9350602085013561063e816105df565b925060408501359150606085013567ffffffffffffffff8082111561066257600080fd5b818701915087601f83011261067657600080fd5b813581811115610688576106886105f7565b604051601f8201601f19908116603f011681019083821181831017156106b0576106b06105f7565b816040528281528a60208487010111156106c957600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060006060848603121561070257600080fd5b833561070d816105df565b9250602084013561071d816105df565b929592945050506040919091013590565b60006020828403121561074057600080fd5b5035919050565b6000806040838503121561075a57600080fd5b8235610765816105df565b946020939093013593505050565b60008251610785818460208701610588565b9190910192915050565b6000602082840312156107a157600080fd5b81516107ac816105df565b9392505050565b6000602082840312156107c557600080fd5b815180151581146107ac57600080fdfea2646970667358221220267a087dacb3ad5758daff8be59841bf10a8048066a5421215cbee8eea3d235064736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a9afc955d549d43db056655b98fab02870a45fcd000000000000000000000000ca1b6dc58c8fe92c4ced26a5e083a1ceeb728226
-----Decoded View---------------
Arg [0] : provider_ (address): 0xa9Afc955d549D43DB056655b98FaB02870A45Fcd
Arg [1] : installerModule (address): 0xcA1B6DC58C8FE92c4ced26A5e083a1cEEB728226
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a9afc955d549d43db056655b98fab02870a45fcd
Arg [1] : 000000000000000000000000ca1b6dc58c8fe92c4ced26a5e083a1ceeb728226
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.