Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 19329214 | 181 days ago | IN | 0 ETH | 0.04051192 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
BusinessDayRegistry
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 10 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "./interfaces/IBusinessDayRegistry.sol"; import "./interfaces/IPoolFlex.sol"; import "./upgrades/BeaconImplementation.sol"; /** * @title Terms of Service Acceptance Registry. * @dev Terms of Service acceptance is required in the permissioned version of Perimeter * before lenders, borrowers, or PoolAdmin's can meaningfully interact with the protocol. */ contract BusinessDayRegistry is IBusinessDayRegistry, BeaconImplementation { mapping(uint64 => bool) private _isHoliday; error TransferInOverflow(); error NotOperator(); error NotPoolAdmin(); error NotPoolsCalendar(); uint64[] public isHolidayKeys; IPoolFlex private _pool; /** * @dev Restricts caller to ServiceOperator */ modifier onlyOperator() { if (!_pool.serviceConfiguration().isOperator(msg.sender)) { revert NotOperator(); } _; } modifier onlyPoolAdmin() { if (!_pool.serviceConfiguration().isPoolAdmin(msg.sender)) { revert NotPoolAdmin(); } _; } modifier onlyPool() { if (address(_pool) != msg.sender) { revert NotPoolsCalendar(); } _; } // 0 = Monday, 7 = Sunday function isWeekDay(uint64 _timestamp) public pure returns (bool) { uint64 _days = _timestamp / 1 days; uint64 dayOfWeek = ((_days + 4) % 7); return !(dayOfWeek == 0 || dayOfWeek == 6); } function toMidnight(uint64 _timestamp) public pure returns (uint64) { return _timestamp - (_timestamp % 1 days); } function addHoliday(uint64 _timestamp) external onlyPoolAdmin { uint64 _midnight = toMidnight(_timestamp); _isHoliday[_midnight] = true; isHolidayKeys.push(_midnight); emit AddHoliday(_midnight); } function isHoliday(uint64 _timestamp) public view returns (bool) { uint64 _midnight = toMidnight(_timestamp); return _isHoliday[_midnight]; } function isBusinessDay(uint64 _timestamp) public view returns (bool) { if (!isWeekDay(_timestamp)) { return false; } if (isHoliday(_timestamp)) { return false; } return true; } function nonBusinessDays() public view returns (uint64[] memory) { return isHolidayKeys; } function updateNonBusinessDays( uint64[] memory _timestamps ) onlyPool public{ uint256 length = isHolidayKeys.length; for (uint i = 0; i < length; i++) { delete _isHoliday[isHolidayKeys[i]]; } for (uint i = 0; i < length; i++) { isHolidayKeys.pop(); } for (uint i = 0; i < _timestamps.length; i++) { uint64 _midnight = toMidnight(_timestamps[i]); _isHoliday[_midnight] = true; isHolidayKeys.push(_midnight); } } function businessDaysToCalendarDays( uint64 _timestamp, uint256 cutoffTime, uint256 transferBusinessDays ) public view returns (uint8 numberOfDays, uint256 transferDayTimestamp) { require(transferBusinessDays < 5, "BD: transferInBusinessDays > 5"); uint64 currentDay = toMidnight(_timestamp); uint256 timeOfDay = _timestamp % 1 days; if (timeOfDay < cutoffTime) { transferDayTimestamp = currentDay - 1 days; numberOfDays = 0; uint256 businessDays = 0; for (uint i = 0; i < 10; i++) { if (isBusinessDay(currentDay)) { if (businessDays == transferBusinessDays) { return (numberOfDays, transferDayTimestamp); } businessDays += 1; } transferDayTimestamp += 1 days; currentDay += 1 days; numberOfDays += 1; } } else { transferDayTimestamp = currentDay; numberOfDays = 0; transferDayTimestamp += 1 days; currentDay += 1 days; numberOfDays += 1; uint256 businessDays = 0; for (uint i = 0; i < 10; i++) { if (isBusinessDay(currentDay)) { if (businessDays == transferBusinessDays) { return (numberOfDays, transferDayTimestamp); } businessDays += 1; } transferDayTimestamp += 1 days; currentDay += 1 days; numberOfDays += 1; } } revert TransferInOverflow(); } /** * @dev Initializer for the BusinessDayRegistry */ function initialize(address poolAddr) public initializer { _pool = IPoolFlex(poolAddr); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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); } /** * @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[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } 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; } /** * @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[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "../../interfaces/IPool.sol"; import "../../interfaces/ILoan.sol"; /** * @dev Expresses the various states a pool can be in throughout its lifecycle. */ enum IPoolLifeCycleState { Initialized, Active, Closed, DisruptionOrDefault } /** * @title The various configurable settings that customize Pool behavior. */ struct IPoolConfigurableSettings { uint256 maxCapacity; // amount uint256 endDate; // epoch seconds address borrowerManager; address borrowerWalletAddress; uint256 closeOfBusinessTime; uint256 earlyWithdrawFeeBps; } /** * @title A Pool's Admin controller * @dev Pool Admin's interact with the pool via the controller, including funding loans and adjusting * settings. */ interface IPoolController { /** * @dev Emitted when pool settings are updated. */ event PoolSettingsUpdated(); /** * @dev Emitted when the pool transitions a lifecycle state. */ event LifeCycleStateTransition(IPoolLifeCycleState state); /** * @dev Emitted when a pool is marked as in DisruptionOrDefault. */ event DisruptionOrDefault(address indexed pool); event Rescheduled(address indexed pool); function version() external returns (uint16); /** * @dev The Pool's admin */ function admin() external view returns (address); /*////////////////////////////////////////////////////////////// Settings //////////////////////////////////////////////////////////////*/ /** * @dev The current configurable pool settings. */ function settings() external view returns (IPoolConfigurableSettings memory); function serviceConfiguration() external view returns (address); /** * @dev Allow the current pool admin to update the pool capacity at any * time. */ function setPoolCapacity(uint256) external; /** * @dev Allow the current pool admin to update the pool's end date. The end date can * only be moved earlier (but not in the past, as measured by the current block's timestamp). * Once the end date is reached, the Pool is closed. */ function setPoolEndDate(uint256) external; function closeOfBusinessTime() external view returns (uint256); function borrowerManager() external view returns (address); function borrowerWalletAddress() external view returns (address); /*////////////////////////////////////////////////////////////// State //////////////////////////////////////////////////////////////*/ function reschedule( address loan, uint256 accrualStartDayTimestamp, uint256 transferInWindowDurationDays, uint256 transferOutWindowDurationDays, uint256 durationDays ) external; /** * @dev Returns the current pool lifecycle state. */ function state() external view returns (IPoolLifeCycleState); function activatePool() external; /*////////////////////////////////////////////////////////////// Loans //////////////////////////////////////////////////////////////*/ function approveLoanForPool(address loan) external; function initiateRollover(address loan, address priorLoan) external; function completeRolloverNetPayment(address) external; function disruptionOrDefault() external; function releaseRolloverRedemption(address owner) external; /*////////////////////////////////////////////////////////////// Fees //////////////////////////////////////////////////////////////*/ /** * @dev Called by the pool admin, this claims fees that have accumulated * in the Pool's FeeVault from ongoing borrower payments. */ function withdrawFeeVault(uint256 amount, address receiver) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "../../interfaces/IPool.sol"; import "../../interfaces/ILoan.sol"; /** * @dev Expresses the various states a pool can be in throughout its lifecycle. */ enum IPoolLifeCycleStateFlex { Initialized, Active, Closed, DisruptionOrDefault } /** * @title The various configurable settings that customize Pool behavior. */ struct IPoolConfigurableSettingsFlex { uint256 maxCapacity; // amount address borrowerManagerAddr; address borrowerWalletAddr; uint256 closeOfDepositTime; uint256 closeOfWithdrawTime; uint256 originationFee; uint256 dailyOriginationFeeRate; uint256 transferInDays; uint256 transferOutDays; } /** * @title A Pool's Admin controller * @dev Pool Admin's interact with the pool via the controller, including funding loans and adjusting * settings. */ interface IPoolControllerFlex { /** * @dev Emitted when pool settings are updated. */ event PoolSettingsUpdated(); /** * @dev Emitted when the pool transitions a lifecycle state. */ event LifeCycleStateTransition(IPoolLifeCycleStateFlex state); /** * @dev Emitted when a pool is marked as in DisruptionOrDefault. */ event DisruptionOrDefault(address indexed pool); event Rescheduled(address indexed pool); function version() external returns (uint16); /** * @dev The Pool's admin */ function admin() external view returns (address); /*////////////////////////////////////////////////////////////// Settings //////////////////////////////////////////////////////////////*/ /** * @dev The current configurable pool settings. */ function settings() external view returns (IPoolConfigurableSettingsFlex memory); function serviceConfiguration() external view returns (address); /** * @dev Allow the current pool admin to update the pool capacity at any * time. */ function updatePoolSettings( IPoolConfigurableSettingsFlex memory poolSettings_ ) external; function dailyOriginationFeeRate() external view returns (uint256); function originationFee() external view returns (uint256); function closeOfDepositTime() external view returns (uint256); function closeOfWithdrawTime() external view returns (uint256); function transferInDays() external view returns (uint256); function transferOutDays() external view returns (uint256); function borrowerManagerAddr() external view returns (address); function borrowerWalletAddr() external view returns (address); function disruptionOrDefault() external; /** * @dev Returns the current pool lifecycle state. */ function state() external view returns (IPoolLifeCycleStateFlex); function activatePool() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "../../interfaces/IPool.sol"; struct IPoolRolloverWithdrawState { uint256 requestedShares; // Number of shares requested in the `latestPeriod` uint256 requestedAssets; uint256 redeemableShares; // The shares that are currently withdrawable uint256 withdrawableAssets; // The assets that are currently withdrawable uint256 earlyRequestedShares; // The period in which the shares were requested uint256 earlyRequestedAssets; uint256 earlyAcceptedShares; // The period in which the shares were requested uint256 earlyAcceptedAssets; } /** * @title A Pool's Withdraw controller * @dev Holds state related to withdraw requests, and logic for snapshotting the * pool's liquidity reserve at regular intervals, earmarking funds for lenders according * to their withdrawal requests. */ interface IWithdrawController { function version() external pure returns (uint16); function pool() external view returns (address); function feeVault() external view returns (address); function borrowerVault() external view returns (address); function borrowerWallet() external view returns (address); function withdrawFeeVault(uint256 amount, address receiver) external; /*////////////////////////////////////////////////////////////// Balance Views //////////////////////////////////////////////////////////////*/ function drawDownToBorrowerWallet(uint256 amount) external; function redemptionState() external view returns (IRedemptionState memory); function requestedSharesOf( address owner ) external view returns (uint256 shares); function requestedAssetsOf( address owner ) external view returns (uint256 assets); function redeemableSharesOf( address owner ) external view returns (uint256 shares); function withdrawableAssetsOf( address owner ) external view returns (uint256 assets); /** * @dev Returns the number of shares that are available to be redeemed by * the owner in the current block. */ function totalRequestedShares() external view returns (uint256); function totalRequestedAssets() external view returns (uint256 assets); /** * @dev Returns the number of shares that are available to be redeemed * overall in the current block. */ function totalRedeemableShares() external view returns (uint256); /** * @dev Returns the number of `assets` that are available to be withdrawn * overall in the current block. */ function totalWithdrawableAssets() external view returns (uint256); function releaseRolloverRedemption( address owner ) external returns (uint256 shares, uint256 assets); /*////////////////////////////////////////////////////////////// Max Methods //////////////////////////////////////////////////////////////*/ /** * @dev Returns the maximum number of `shares` that can be * requested to be redeemed from the owner balance with a single * `requestRedeem` call in the current block. * * Note: This is equivalent of EIP-4626 `maxRedeem` */ function maxRedeemRequest(address) external view returns (uint256); /** * @dev The maximum amount of shares that can be redeemed from the owner * balance through a redeem call. */ function maxRedeem(address) external view returns (uint256); /** * @dev Returns the maximum amount of underlying assets that can be * withdrawn from the owner balance with a single withdraw call. */ function maxWithdraw(address) external view returns (uint256); /*////////////////////////////////////////////////////////////// Preview Methods //////////////////////////////////////////////////////////////*/ /** * @dev Simulates the effects of their redeemption at the current block. * Per EIP4626, should round DOWN. */ function previewRedeem(address, uint256) external view returns (uint256); /** * @dev Simulate the effects of their withdrawal at the current block. * Per EIP4626, should round UP on the number of shares required for assets. */ function previewWithdraw(address, uint256) external view returns (uint256); /*////////////////////////////////////////////////////////////// Request Methods //////////////////////////////////////////////////////////////*/ /** * @dev Requests redeeming a specific number of `shares` and `assets` from * the pool. * * NOTE: The pool is responsible for handling any fees, and for providing * the proper shares/assets ratio. */ function performRequest(address, uint256, uint256) external; /*////////////////////////////////////////////////////////////// Early Withdraw Methods //////////////////////////////////////////////////////////////*/ function requestEarlyRedeem( address owner, uint256 shares ) external returns (uint256 principal); function acceptEarlyRedeemRequest( address investorAddr ) external returns (uint256 shares, uint256 principal); function repayEarlyWithdraw( address investorAddr, uint256 amount ) external returns ( uint256 principal, uint256 repayment, uint256 redeemedShares, uint256 fees, uint256 assetReduction ); function totalEarlyRequestedShares() external view returns (uint256 shares); function totalEarlyRequestedAssets() external view returns (uint256 assets); function totalEarlyAcceptedShares() external view returns (uint256 shares); function totalEarlyAcceptedAssets() external view returns (uint256 assets); function earlyRequestedSharesOf( address owner ) external view returns (uint256 shares); function earlyRequestedAssetsOf( address owner ) external view returns (uint256 assets); function earlyAcceptedSharesOf( address owner ) external view returns (uint256 shares); function earlyAcceptedAssetsOf( address owner ) external view returns (uint256 assets); /*////////////////////////////////////////////////////////////// Withdraw / Redeem //////////////////////////////////////////////////////////////*/ /** * @dev Redeems a specific number of shares from owner and send assets of underlying token from the vault to receiver. * * Per EIP4626, should round DOWN. */ function redeem(address, uint256) external returns (uint256); /** * @dev Burns shares from owner and send exactly assets token from the vault to receiver. * Should round UP for EIP4626. */ function withdraw(address, uint256) external returns (uint256); function payFees(uint256) external; function repayLoan(uint256) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "../../interfaces/IPoolFlex.sol"; struct IPoolLenderWithdrawEvent { uint256 requestedShares; // Number of shares requested in the `latestPeriod` uint256 requestedAssets; uint256 transferOutDayTimestamp; uint256 requestTimestamp; address lender; uint256 eventId; } struct IPoolLenderTotals { uint256 requestedShares; // Number of shares requested in the `latestPeriod` uint256 requestedAssets; address lender; uint256 assetsDeposited; uint256 assetsWithdrawn; uint256 sharesTransitioningIn; uint256 assetsTransitioningIn; uint256 assetsDueForWithdraws; uint256 sharesDueForWithdraws; } struct IDailyWithdrawTotals { uint256 requestedShares; // Number of shares requested in the `latestPeriod` uint256 requestedAssets; uint256 transferOutDayTimestamp; } struct IPoolWithdrawTotal { uint256 requestedShares; // Number of shares requested in the `latestPeriod` uint256 requestedAssets; } struct IPoolLenderDepositEvent { uint256 mintedShares; uint256 depositedAssets; uint256 transferInDayTimestamp; address lender; } struct IDailyDepositTotals { uint256 mintedShares; uint256 depositedAssets; uint256 transferInDayTimestamp; } struct IPoolDepositsTotal { uint256 mintedShares; uint256 depositedAssets; } /** * @title A Pool's Withdraw controller * @dev Holds state related to withdraw requests, and logic for snapshotting the * pool's liquidity reserve at regular intervals, earmarking funds for lenders according * to their withdrawal requests. */ interface IWithdrawDepositControllerFlex { function version() external pure returns (uint16); function poolAddr() external view returns (address); function pool() external view returns (address); // back compatible function feeVaultAddr() external view returns (address); function borrowerVaultAddr() external view returns (address); function lenderTotals( address lender ) external view returns (IPoolLenderTotals memory); function borrowerVault() external view returns (address); // back compatible function borrowerWallet() external view returns (address); function borrowerWalletAddr() external view returns (address); function dailyInterestAccural( uint256 currentDay ) external returns (uint256 inflows); function deposit( address lender, uint256 assets, uint256 exchangeRate, uint256 interestRate ) external returns ( uint256 inflows, uint256 shares, uint256 transferInDayTimestamp ); /*////////////////////////////////////////////////////////////// Balance Views //////////////////////////////////////////////////////////////*/ function drawDownToBorrowerWallet(uint256 amount) external; function requestedSharesOf( address owner ) external view returns (uint256 shares); function requestedAssetsOf( address owner ) external view returns (uint256 assets); function totalAssetsTransitioningIn() external view returns (uint256 assets); function totalSharesTransitioningIn() external view returns (uint256 shares); /** * @dev Returns the number of shares that are available to be redeemed by * the owner in the current block. */ function totalRequestedShares() external view returns (uint256 shares); function totalRequestedAssets() external view returns (uint256 assets); /*////////////////////////////////////////////////////////////// Max Methods //////////////////////////////////////////////////////////////*/ /** * @dev Returns the maximum number of `shares` that can be * requested to be redeemed from the owner balance with a single * `requestRedeem` call in the current block. * * Note: This is equivalent of EIP-4626 `maxRedeem` */ function maxRedeemRequest(address) external view returns (uint256); /*////////////////////////////////////////////////////////////// Request Methods //////////////////////////////////////////////////////////////*/ /** * @dev Requests redeeming a specific number of `shares` and `assets` from * the pool. * * NOTE: The pool is responsible for handling any fees, and for providing * the proper shares/assets ratio. */ function performRequest(address, uint256, uint256) external; /*////////////////////////////////////////////////////////////// Withdraw / Redeem //////////////////////////////////////////////////////////////*/ function totalAssetsDueForWithdraws() external view returns (uint256); function releaseWithdrawal( uint256 eventId ) external returns (IPoolLenderWithdrawEvent memory ev); function withdrawEvents() external view returns (IPoolLenderWithdrawEvent[] memory); function repayLoans(uint256 assets) external; function tokenTransfer( address from, address to, uint256 assetAmount ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; /** * @title The interface for interacting with IBusinessDayRegistry */ interface IBusinessDayRegistry { event AddHoliday(uint256 _timestamp); function isBusinessDay(uint64 _timestamp) external view returns (bool); function isHoliday(uint64 _timestamp) external view returns (bool); function isWeekDay(uint64 _timestamp) external pure returns (bool); function addHoliday(uint64 _timestamp) external; function toMidnight(uint64 _timestamp) external pure returns (uint64); function nonBusinessDays() external view returns (uint64[] memory); function updateNonBusinessDays(uint64[] memory _timestamps) external; function businessDaysToCalendarDays( uint64 _timestamp, uint256 depositCutoffTime, uint256 transferBusinessDays ) external view returns (uint8 numberOfDays, uint256 transferDayTimestamp); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; /** * @title The interface according to the ERC-4626 standard. */ interface IERC4626 is IERC20Upgradeable { /** * @dev Emitted when tokens are deposited into the vault via the mint and deposit methods. */ event Deposit( address indexed sender, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Emitted when shares are withdrawn from the vault by a depositor in the redeem or withdraw methods. */ event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Return the address of the underlying ERC-20 token used for the vault for accounting, depositing, withdrawing. */ function asset() external view returns (address); /** * @dev Calculate the total amount of underlying assets held by the vault. * NOTE: This method includes assets that are marked for withdrawal. */ function totalAssets() external view returns (uint256); /** * @dev Calculates the amount of shares that would be exchanged by the vault for the amount of assets provided. * Rounds DOWN per EIP4626. */ function convertToShares(uint256 assets) external view returns (uint256); /** * @dev Calculates the amount of assets that would be exchanged by the vault for the amount of shares provided. * Rounds DOWN per EIP4626. */ function convertToAssets(uint256 shares) external view returns (uint256); /** * @dev Calculates the maximum amount of underlying assets that can be deposited in a single deposit call by the receiver. */ function maxDeposit(address receiver) external view returns (uint256); /** * @dev Allows users to simulate the effects of their deposit at the current block. */ function previewDeposit(uint256 assets) external view returns (uint256); /** * @dev Deposits assets of underlying tokens into the vault and grants ownership of shares to receiver. * Emits a {Deposit} event. */ function deposit( uint256 assets, address receiver ) external returns (uint256); /** * @dev Returns the maximum amount of shares that can be minted in a single mint call by the receiver. */ function maxMint(address receiver) external view returns (uint256); /** * @dev Allows users to simulate the effects of their mint at the current block. */ function previewMint(uint256 shares) external view returns (uint256); /** * @dev Mints exactly shares vault shares to receiver by depositing assets of underlying tokens. * Emits a {Deposit} event. */ function mint(uint256 shares, address receiver) external returns (uint256); /** * @dev Returns the maximum amount of underlying assets that can be withdrawn from the owner balance with a single withdraw call. */ function maxWithdraw(address owner) external view returns (uint256); /** * @dev Simulate the effects of their withdrawal at the current block. * Per EIP4626, should round UP on the number of shares required for assets. */ function previewWithdraw(uint256 assets) external view returns (uint256); /** * @dev Burns shares from owner and send exactly assets token from the vault to receiver. * Emits a {Withdraw} event. * Should round UP for EIP4626. */ function withdraw( uint256 assets, address receiver, address owner ) external returns (uint256); /** * @dev The maximum amount of shares that can be redeemed from the owner balance through a redeem call. */ function maxRedeem(address owner) external view returns (uint256); /** * @dev Simulates the effects of their redeemption at the current block. * Per EIP4626, should round DOWN. */ function previewRedeem(uint256 shares) external view returns (uint256); /** * @dev Redeems a specific number of shares from owner and send assets of underlying token from the vault to receiver. * Emits a {Withdraw} event. * Per EIP4626, should round DOWN. */ function redeem( uint256 shares, address receiver, address owner ) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "./IServiceConfigurationV3.sol"; import "../interfaces/IVault.sol"; /** * @title An enum capturing the various states a Loan may be in. */ enum ILoanLifeCycleState { Requested, Canceled, Funded, Matured, Active, Settled } enum ILoanTransitionState { Created /* RequestedLoan */, ApprovedForDeposits /* RequestedLoan */, TransitioningFundsIn /* RequestedLoan */, AccruingInterest /* ActiveLoan */, RedemptionsClosed /* ActiveLoan */, TransitioningFundsOut /* MaturedLoan */, RedemptionsReleased /* Settled loan */ } struct ILoanCompleteState { address loanAddr; address borrowerAddr; address fundingVaultAddr; address poolAddr; uint256 state; uint256 transitionState; uint256 durationDays; uint256 principal; uint256 startingPrincipal; uint256 interest; uint256 indicativeInterest; uint256 originationFee; uint256 indicativeApr; uint256 finalizedApr; uint256 exchangeRateAtDeposit; uint256 exchangeRateAtMaturity; uint256 fundingVaultBalance; uint256 assetsRolloverToNextLoan; uint256 assetsToReturnToPool; uint256 assetsFromPool; uint256 accrualStartDayTimestamp; uint256 accrualStartTimestamp; uint256 transferInWindowDurationDays; uint256 transferOutWindowDurationDays; uint256 depositClosingTimestamp; uint256 redemptionRequestClosingTimestamp; uint256 maturingTimestamp; uint256 redemptionAvailableTimestamp; ILoanRolloverAccounting rolloverAccounting; bool canRequestRedemption; } /** * @title The various Loan terms. */ struct ILoanSettings { uint256 principal; uint256 indicativeApr; uint256 finalizedApr; uint256 durationDays; uint256 dropDeadTimestamp; uint256 originationBps; uint256 accrualStartDayTimestamp; uint256 transferInWindowDurationDays; uint256 transferOutWindowDurationDays; address priorLoan; uint256 startingPrincipal; } struct ILoanRolloverAccounting { uint256 totalSupply; uint256 assetsFromPool; uint256 assetsFromPriorLoan; uint256 assetToReturnToPool; uint256 exchangeRateAtDeposit; uint256 exchangeRateAtMaturity; } /** * @title The primary interface for Perimeter loans. */ interface ILoan { /** * @dev Emitted when loan is funded. */ event LoanFunded(address asset, uint256 amount); /** * @dev Emitted when a Loan's lifecycle state transitions */ event LifeCycleStateTransition(ILoanLifeCycleState state); function getRolloverAccounting() external view returns (ILoanRolloverAccounting memory); function approve() external; function canRequestRedemption() external view returns (bool); function inDepositWindow() external view returns (bool); function inInitiateRolloverWindow() external view returns (bool); function exchangeRateAtDeposit() external view returns (uint256); function exchangeRateAtMaturity() external view returns (uint256); function assetsRolloverToNextLoan() external view returns (uint256); function assetsFromPool() external view returns (uint256); function assetsToReturnToPool() external view returns (uint256); function accrualStartTimestamp() external view returns (uint256); function accrualStartDayTimestamp() external view returns (uint256); function transferInWindowDurationDays() external view returns (uint256); function transferOutWindowDurationDays() external view returns (uint256); function depositClosingTimestamp() external view returns (uint256); function earlyRedeemRequestClosingTimestamp() external view returns (uint256); function redemptionRequestClosingTimestamp() external view returns (uint256); function maturingTimestamp() external view returns (uint256); function redemptionAvailableTimestamp() external view returns (uint256); /** * @dev Current Loan lifecycle state. */ function state() external view returns (ILoanLifeCycleState); function transitionState() external view returns (ILoanTransitionState); /** * @dev The loan's borrower. */ function borrower() external view returns (address); /** * @dev The pool associated with a loan. */ function pool() external view returns (address); /** * @dev The factory that created the loan. */ function factory() external view returns (address); /** * @dev A timestamp that controls when the loan can be dissolved */ function dropDeadTimestamp() external view returns (uint256); /** * @dev Amount expected in each payment */ function interest() external view returns (uint256); function indicativeInterest() external view returns (uint256); function rolloverMaturedLoan() external; function rolloverAndFinalizeApr(uint256 apr) external; function rolloverAllocation( uint256 assetsRolloverToNextLoan_, uint256 assetToReturnToPool_ ) external; function completeRolloverNetPayment() external returns ( uint256 feeVaultAmount, uint256 assetsReturnedToPool, uint256 interestAccrued ); function fundRollover( uint256 assetsFromPool, uint256 assetsFromPriorLoan, uint256 totalSupply, address priorLoan ) external returns (ILoanLifeCycleState); function reschedule( uint256 accrualStartDayTimestamp_, uint256 transferInWindowDurationDays_, uint256 transferOutWindowDurationDays_, uint256 durationDays_ ) external; /** * @dev When the loan was created. */ function createdAt() external returns (uint256); /** * @dev Duration of the loan, after which the principal must be returned. */ function durationDays() external view returns (uint256); /** * @dev Interest rate for the loan. */ function finalizedApr() external view returns (uint256); function indicativeApr() external view returns (uint256); function originationFee() external view returns (uint256); /** * @dev Amount of loan principal. */ function principal() external view returns (uint256); function startingPrincipal() external view returns (uint256); /** * @dev Address of the loan's funding vault, which holds liquidity transferred from the pool. */ function fundingVault() external view returns (IVault); /** * @dev Liquidity asset of the loan or pool. */ function liquidityAsset() external view returns (address); /** * @dev Address of the global service configuration. */ function serviceConfiguration() external view returns (IServiceConfigurationV3); function repayEarlyWithdraw( uint256 principal, uint256 assetReduction ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "./IERC4626.sol"; import "./IServiceConfiguration.sol"; import "../controllers/interfaces/IPoolController.sol"; import "./IPoolBase.sol"; import "../controllers/interfaces/IWithdrawController.sol"; import "./ILoan.sol"; import "../interfaces/IPoolAccessControl.sol"; /* Paired with rolloverTiming field */ enum IPoolRolloverState { EarlyRolloverInitiate, // 0 accept Deposits and WithdrawRequests, no early withdraws) transitionTiming = time to expected rollover */ RolloverInitiate, // 1 no deposits or withdrawRequests) transitionTiming = time left of expected rollover */ LateRolloverInitiate, // 2 transitionTiming = time expected rollover pastDue */ EarlyRolloverFinalize, // 3 Requested RolloverFinalize, // 4 Requested LateRolloverFinalize, // 5 Requested EarlyRepayWithdrawsAndFees, // 6 Matured loan RepayWithdrawsAndFees, // 7 Matured loan LateRepayWithdrawsAndFees, // 8 Matured loan EarlyReleaseRedemptions, // 9 Matured loan ReleaseRedemptions, // 10 Matured loan LateReleaseRedemptions, // 11 Matured loan CreateNextLoan, // 12 ApproveNextLoan, //13 LateApproveNextLoan, //14 LoanNeedsRescheduling, //15 NotRollingOver, //16 InvalidState // 17 } enum IPoolRolloverActor { PoolAdmin, // 0 BorrowerManager, //1 BorrowerWallet, //2 Investor // 3 } struct IPoolAccountings { uint256 totalAvailableAssets; uint256 outstandingLoanPrincipals; uint256 totalAssetsDeposited; uint256 totalAssetsWithdrawn; } struct IPoolRolloverStateStruct { IPoolRolloverState rolloverState; IPoolRolloverActor rolloverActor; uint256 rolloverTimeToActionWindow; uint256 rolloverTimeLeftInActionWindow; uint256 rolloverTimePastActionWindow; } struct IPoolConfigurationState { address poolAddr; address admin; address poolController; address feeVault; address withdrawController; string name; string symbol; address borrowerManager; address borrowerWallet; address borrowerVault; uint256 maxCapacity; uint256 closeOfBusinessTime; uint256 poolEndDate; address liquidityPoolAssetAddr; } struct IRedemptionState { address[] redemptionLenders; uint256[] requestedShares; uint256[] redeemableShares; } struct IPoolOverviewState { address poolAddr; address[] settledLoans; uint8 state; uint8 rolloverState; uint8 rolloverActor; uint256 rolloverTimeToActionWindow; uint256 rolloverTimeLeftInActionWindow; uint256 rolloverTimePastActionWindow; uint256 totalAvailableAssets; uint256 totalAvailableSupply; uint256 currentExpectedInterest; uint256 liquidityPoolAssets; uint256 totalAssets; uint256 totalOutstandingLoanPrincipal; uint256 totalAssetsDeposited; uint256 totalAssetsWithdrawn; uint256 totalRequestedShares; uint256 totalRedeemableShares; uint256 totalWithdrawableAssets; uint256 totalRequestedAssets; uint256 feeVaultBalance; uint256 borrowerVaultBalance; uint256 borrowerWalletBalance; uint256 poolBalance; uint256 exchangeRateAtMaturity; ILoanCompleteState requestedLoanState; ILoanCompleteState activeLoanState; ILoanCompleteState maturedLoanState; ILoanCompleteState createdLoanState; IRedemptionState redemptionState; uint256 totalEarlyRequestedShares; uint256 totalEarlyRequestedAssets; uint256 totalEarlyAcceptedShares; uint256 totalEarlyAcceptedAssets; } struct IPoolAccountState { address poolAddr; address accountAddr; uint256 balance; uint256 maxWithdrawRequest; uint256 maxRedeemRequest; uint256 maxWithdraw; uint256 maxRedeem; uint256 requestedSharesOf; uint256 redeemableSharesOf; uint256 requestedAssetsOf; uint256 withdrawableAssetsOf; uint256 earlyRequestedSharesOf; uint256 earlyRequestedAssetsOf; uint256 earlyAcceptedSharesOf; uint256 earlyAcceptedAssetsOf; } struct PoolAddressList { address liquidityAsset; address poolAdmin; address serviceConfiguration; address withdrawControllerFactory; address poolControllerFactory; address vaultFactory; address poolAccessControlFactory; } /** * @title The interface for liquidity pools. */ interface IPool is IPoolBase { event Deposit( address indexed sender, address indexed owner, uint256 assets, uint256 shares ); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev The PoolController contract */ function poolController() external view returns (IPoolController); /** * @dev The WithdrawController contract */ function withdrawController() external view returns (IWithdrawController); /** * @dev The current configurable pool settings. */ function settings() external view returns (IPoolConfigurableSettings calldata settings); /** * @dev The current pool state. */ function state() external view returns (IPoolLifeCycleState); /** * @dev The pool accounting variables; */ function accountings() external view returns (IPoolAccountings memory); function closeOfBusinessTime() external view returns (uint256); /** * @dev Callback from the pool controller when the pool is activated */ function onActivated() external; function initiateRollover(address loan, address priorLoan) external; function completeRolloverNetPayment(address) external; function withdrawFeeVault(uint256 amount, address receiver) external; function loanCreated(address loan) external; function reschedule( address loan, uint256 accrualStartDayTimestamp, uint256 transferInWindowDurationDays, uint256 transferOutWindowDurationDays, uint256 durationDays ) external; function redemptionState() external view returns (IRedemptionState memory _redemptionState); function releaseRolloverRedemption(address owner) external; function exchangeRateAtMaturity() external view returns (uint256 _exchangeRateAtMaturity); function exchangeRateAtDeposit() external view returns (uint256); /** * @dev Calculate the total amount of underlying assets held by the vault, * excluding any assets due for withdrawal. */ function totalAvailableAssets() external view returns (uint256); /** * @dev The total available supply that is not marked for withdrawal */ function totalAvailableSupply() external view returns (uint256); /** * @dev The accrued interest at the current block. */ function currentExpectedInterest() external view returns (uint256 interest); function rolloverAndFinalizeApr(uint256 _apr) external; /*////////////////////////////////////////////////////////////// LOAN SET OPERATIONS //////////////////////////////////////////////////////////////*/ function approveLoanForPool(address loan) external; function createdLoan() external view returns (address); function activeLoan() external view returns (address); function requestedLoan() external view returns (address); function maturedLoan() external view returns (address); function settledLoans() external view returns (address[] memory); /*////////////////////////////////////////////////////////////// Early Withdraw //////////////////////////////////////////////////////////////*/ function requestEarlyRedeem(uint256 shares) external; function acceptEarlyRedeemRequest( address investorAddr ) external returns (uint256 principal); function repayEarlyWithdraw( address investorAddr, uint256 amount ) external returns ( uint256 principal, uint256 repayment, uint256 redeemedShares, uint256 fees ); function deposit( uint256 assets, address lender ) external returns (uint256 shares); function convertToAssets( uint256 shares ) external view returns (uint256 assets); function convertToShares( uint256 assets ) external view returns (uint256 shares); function maxWithdraw(address owner) external view returns (uint256 assets); function maxRedeem(address owner) external view returns (uint256 maxShares); function totalAssets() external view returns (uint256); function asset() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; /** * @title The interface for controlling access to Pools */ interface IPoolAccessControl { /** * @dev Check if an address is allowed as a participant in the pool * @param addr The address to verify * @return whether the address is allowed as a participant */ function isAllowed(address addr) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "./IRequestWithdrawable.sol"; import "./IServiceConfigurationV3.sol"; import "./IPoolAccessControl.sol"; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; enum IPoolType { TermPool, FlexRatePool } interface IPoolBase is IERC20Upgradeable, IRequestWithdrawable { function poolType() external view returns (IPoolType); function liquidityAssetAddr() external view returns (address); function version() external view returns (uint16); /** * @dev The ServiceConfiguration. */ function serviceConfiguration() external view returns (IServiceConfigurationV3); /** * @dev The admin for the pool. */ function admin() external view returns (address); function borrowerManagerAddr() external view returns (address); function borrowerWalletAddr() external view returns (address); /** * @dev The activation timestamp of the pool. */ function activatedAt() external view returns (uint256); function poolAccessControl() external view returns (IPoolAccessControl); /** * @dev The sum of all assets available in the liquidity pool, excluding * any assets that are marked for withdrawal. */ function liquidityPoolAssets() external view returns (uint256); function isPermittedLender(address) external view returns (bool); function maxDeposit(address owner) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "./IERC4626.sol"; import "./IServiceConfigurationV3.sol"; import "./IRequestWithdrawable.sol"; import "../controllers/interfaces/IPoolControllerFlex.sol"; import "../controllers/interfaces/IWithdrawDepositControllerFlex.sol"; import "./IPoolBase.sol"; import "../interfaces/IPoolAccessControl.sol"; import "../interfaces/IBusinessDayRegistry.sol"; struct IPoolAccountingsFlex { uint256 interestRate; uint256 dailyInterestRate; uint256 totalPrincipalEarningInterest; uint256 totalInterestAccrued; uint256 totalAssetsDeposited; uint256 totalAssetsWithdrawn; uint256 exchangeRate; uint256 lastDayAccrued; uint256 totalFees; uint256 feesOutstanding; uint256 interstRateSetTime; } struct IPoolConfigurationStateFlex { address poolAddr; uint256 dailyOriginationFeeRate; uint256 originationFee; uint256 closeOfDepositTime; uint256 closeOfWithdrawTime; uint256 transferInDays; uint256 transferOutDays; address liquidityAssetAddr; address poolAdminAddr; address poolControllerAddr; address withdrawControllerAddr; address borrowerVaultAddr; string name; string symbol; address borrowerManagerAddr; address borrowerWalletAddr; uint256 maxCapacity; uint64[] nonBusinessDays; address businessDayRegistryAddr; } struct IPoolOverviewStateFlex { address poolAddr; uint256 interestRate; uint256 dailyInterestRate; uint256 totalPrincipalEarningInterest; uint256 totalInterestAccrued; uint256 totalAssetsDeposited; uint256 totalAssetsWithdrawn; uint256 exchangeRate; uint256 totalSupply; uint256 totalRequestedShares; uint256 totalRequestedAssets; uint256 totalAssetsTransitioningIn; uint256 totalSharesTransitioningIn; uint256 totalAssetsDueForWithdraws; uint256 totalFees; uint256 feesOutstanding; uint64[] nonBusinessDays; uint8 state; uint256 lastDayAccrued; } struct IPoolAccountStateFlex { address poolAddr; address accountAddr; uint256 tokenBalance; uint256 maxWithdrawRequest; uint256 maxRedeemRequest; uint256 requestedSharesOf; uint256 requestedAssetsOf; uint256 principalEarningInterest; uint256 interestAccrued; uint256 assetsDeposited; uint256 assetsWithdrawn; uint256 sharesTransitioningIn; uint256 assetsTransitioningIn; uint256 assetsDueForWithdraws; uint256 sharesDueForWithdraws; } struct PoolAddressListFlex { address liquidityAsset; address poolAdmin; address serviceConfiguration; address withdrawDepositControllerFactoryFlex; address poolControllerFactoryFlex; address vaultFactory; address poolAccessControlFactory; address businessDayRegistryFactory; } /** * @title The interface for liquidity pools. */ interface IPoolFlex is IPoolBase { /** * @dev Emitted when tokens are deposited into the vault via the mint and deposit methods. */ event Deposit( address indexed sender, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Emitted when shares are withdrawn from the vault by a depositor in the redeem or withdraw methods. */ event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /**W * @dev The PoolController contract */ function poolController() external view returns (IPoolControllerFlex); /** * @dev The WithdrawController contract */ function withdrawDepositController() external view returns (IWithdrawDepositControllerFlex); /** * @dev The current configurable pool settings. */ function settings() external view returns (IPoolConfigurableSettingsFlex calldata settings); /** * @dev The current pool state. */ function state() external view returns (IPoolLifeCycleStateFlex); function borrowerVaultAddr() external view returns (address); /** * @dev The pool accounting variables; */ function accountings() external view returns (IPoolAccountingsFlex memory); function closeOfWithdrawTime() external view returns (uint256); function closeOfDepositTime() external view returns (uint256); function transferInDays() external view returns (uint256); function transferOutDays() external view returns (uint256); function businessDayRegistry() external view returns (IBusinessDayRegistry); /** * @dev Callback from the pool controller when the pool is activated */ function onActivated() external; function setDailyInterestRate( uint256 _interestRate, uint256 _estimatedDailyRate ) external; function dailyInterestAccural() external; function applyDailyRate(uint256 principal) external returns (uint256); function annualAPRToDailyRate( uint256 annualAPR, uint256 _estimatedDailyRate ) external view returns (uint256 _dailyInterestRate); function interestRate() external view returns (uint256 assets); function exchangeRate() external view returns (uint256 _exchangeRate); function getPoolConfiguration() external view returns (IPoolConfigurationStateFlex memory); function getPoolOverview() external view returns (IPoolOverviewStateFlex memory); function getPoolAccountState( address accountAddr ) external view returns (IPoolAccountStateFlex memory); /** * @dev Calculate the total amount of underlying assets held by the vault, * excluding any assets due for withdrawal. */ function totalAvailableAssets() external view returns (uint256); /** * @dev The total available supply that is not marked for withdrawal */ function totalAvailableSupply() external view returns (uint256); function convertToShares( uint256 assets ) external view returns (uint256 shares); function convertToAssets( uint256 shares ) external view returns (uint256 assets); function deposit( uint256 assets, address lender ) external returns (uint256 shares, uint256 transferInDayTimestamp); function totalAssetsDueForWithdraws() external view returns (uint256); function feesPaidDown(uint256 paidAmount) external; function withdrawEvents() external view returns (IPoolLenderWithdrawEvent[] memory); function releaseWithdrawal( uint256 eventId ) external returns (IPoolLenderWithdrawEvent memory ev); function repayLoans(uint256 assets, uint256 eventId) external; function nonBusinessDays() external view returns (uint64[] memory); function updateNonBusinessDays(uint64[] memory _timestamps) external; function topOffSharesDueToExchangeRateDecrease( address lender, uint256 catchupShares ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; /** * @title Interface that exposes methods to request withdraws / redeems. * @dev Terminology and design informed to complement ERC4626. */ interface IRequestWithdrawable { /** * @dev Returns the maximum number of `shares` that can be * requested to be redeemed from the owner balance with a single * `requestRedeem` call in the current block. * * Note: This is equivalent of EIP-4626 `maxRedeem` */ function maxRedeemRequest( address owner ) external view returns (uint256 maxShares); /** * @dev Returns the maximum amount of underlying `assets` that can be * requested to be withdrawn from the owner balance with a single * `requestWithdraw` call in the current block. * * Note: This is equivalent of EIP-4626 `maxWithdraw` */ function maxWithdrawRequest( address owner ) external view returns (uint256 maxAssets); /** * @dev Simulate the effects of a redeem request at the current block. * Returns the amount of underlying assets that would be requested if this * entire redeem request were to be processed at the current block. * * Note: This is equivalent of EIP-4626 `previewRedeem` */ function previewRedeemRequest( uint256 shares ) external view returns (uint256 assets); /** * @dev Simulate the effects of a withdrawal request at the current block. * Returns the amount of `shares` that would be burned if this entire * withdrawal request were to be processed at the current block. * * Note: This is equivalent of EIP-4626 `previewWithdraw` */ function previewWithdrawRequest( uint256 assets ) external view returns (uint256 shares); /** * @dev Submits a withdrawal request, incurring a fee. */ function requestRedeem(uint256 shares) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; struct SerivceAddressList { address[] liquidityAssets; address tosAcceptanceRegistry; address loanFactory; address poolFactoryAddress; address queryLibAddress; address poolLibAddress; address loanLibAddress; address poolControllerFactoryAddress; address withdrawControllerFactoryAddress; address vaultFactoryAddress; address poolAccessControlFactoryAddress; } /** * @title The protocol global Service Configuration */ interface IServiceConfiguration { /** * @dev Emitted when an address is changed. */ event AddressSet(bytes32 which, address addr); /** * @dev Emitted when a liquidity asset is set. */ event LiquidityAssetSet(address addr, bool value); /** * @dev Emitted when a parameter is set. */ event ParameterSet(bytes32, uint256 value); /** * @dev Emitted when the protocol is paused. */ event ProtocolPaused(bool paused); /** * @dev Emitted when a loan factory is set */ event LoanFactorySet(address indexed factory); event PoolFactorySet(address indexed factory); event QueryLibSet(address indexed factory); event LoanLibSet(address indexed factory); event PoolLibSet(address indexed factory); event PoolAdminWalletSet(address indexed factory); /** * @dev Emitted when the TermsOfServiceRegistry is set */ event TermsOfServiceRegistrySet(address indexed registry); /** * @dev checks if a given address has the Operator role */ function isOperator(address addr) external view returns (bool); /** * @dev checks if a given address has the Deployer role */ function isDeployer(address addr) external view returns (bool); /** * @dev checks if a given address has the Deployer role */ function isPoolAdmin(address addr) external view returns (bool); /** * @dev checks if a given address has the Deployer role */ function isBorrower(address addr) external view returns (bool); /** * @dev Whether the protocol is paused. */ function paused() external view returns (bool); /** * @dev Whether an address is supported as a liquidity asset. */ function isLiquidityAsset(address addr) external view returns (bool); /** * @dev Address of the Terms of Service acceptance registry. */ function tosAcceptanceRegistry() external view returns (address); /** * @dev Sets whether a loan factory is valid * @param addr Address of loan factory */ function setLoanFactory(address addr) external; function setPoolFactory(address addr) external; function setQueryLib(address addr) external; function setPoolLib(address addr) external; function setLoanLib(address addr) external; function getLoanFactory() external view returns (address); function getPoolFactory() external view returns (address); function getQueryLib() external view returns (address); function getLoanLib() external view returns (address); function getPoolLib() external view returns (address); function setPoolAdminWallet(address addr) external; function getPoolAdminWallet() external view returns (address); /** * @dev Sets the ToSAcceptanceRegistry for the protocol * @param addr Address of registry */ function setToSAcceptanceRegistry(address addr) external; /** * @dev Sets supported liquidity assets for the protocol. Callable by the operator. * @param addr Address of liquidity asset * @param value Whether supported or not */ function setLiquidityAsset(address addr, bool value) external; function getServiceAddressList() external view returns (SerivceAddressList memory setLoanFactoryerivceAddressList); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "./IServiceConfiguration.sol"; struct SerivceAddressListV3 { address[] liquidityAssets; address tosAcceptanceRegistry; address loanFactory; address poolFactoryAddress; address poolFactoryFlexAddress; address queryLibAddress; address poolLibAddress; address poolLibFlexAddress; address loanLibAddress; address poolControllerFactoryAddress; address withdrawControllerFactoryAddress; address vaultFactoryAddress; address poolAccessControlFactoryAddress; address poolControllerFactoryFlexAddress; address withdrawDepositControllerFactoryFlexAddress; address poolRegistryAddress; } enum IFactoryType { PoolFactory, LoanFactory, VaultFactory, PoolFactoryFlex, PoolControllerFactory, PoolLibFlex, PoolControllerFactoryFlex, WithdrawDepositControllerFactoryFlex, WithdrawControllerFactory, PoolAccessControlFactory } struct LegacyFactoryStruct { IFactoryType factoryType; address factoryAddress; } /** * @title The protocol global Service Configuration */ interface IServiceConfigurationV3 is IServiceConfiguration { event PoolFactoryFlexSet(address indexed factory); event PoolLibFlexSet(address indexed factory); event PoolRegistrySet(address indexed factory); function version() external pure returns (uint16); function isAutomation(address addr) external view returns (bool); function setPoolFactoryFlex(address addr) external; function setPoolLibFlex(address addr) external; function setPoolRegistry(address addr) external; function getPoolRegistry() external view returns (address); function getPoolFactoryFlex() external view returns (address); function getPoolLibFlex() external view returns (address); function getLegacyFactories() external view returns (LegacyFactoryStruct[] memory legacyFactories); function getServiceAddressListV3() external view returns (SerivceAddressListV3 memory addressList); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; /** * @title Interface for the Vault. * @dev Vaults simply hold a balance, and allow withdrawals by the Vault's owner. */ interface IVault { /** * @dev Emitted on ERC20 withdrawals */ event WithdrewERC20( address indexed asset, uint256 amount, address indexed receiver ); /** * @dev Emitted on ERC721 withdrawals */ event WithdrewERC721( address indexed asset, uint256 tokenId, address receiver ); /** * @dev Withdraws ERC20 of a given asset */ function withdrawERC20( address asset, uint256 amount, address receiver ) external; /** * @dev Withdraws ERC20 of a given asset */ function withdrawERC20ToBorrowerWallet( address asset, uint256 amount ) external; function payFees(address asset, uint256 amount) external; function repayLoan(address asset, uint256 amount) external; /** * @dev Withdraws ERC721 with specified tokenId */ function withdrawERC721( address asset, uint256 tokenId, address receiver ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @title BeaconImplementation base contract * @dev Base contract that overrides the constructor to disable initialization. */ abstract contract BeaconImplementation is Initializable { /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } }
{ "optimizer": { "enabled": true, "runs": 10 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"NotOperator","type":"error"},{"inputs":[],"name":"NotPoolAdmin","type":"error"},{"inputs":[],"name":"NotPoolsCalendar","type":"error"},{"inputs":[],"name":"TransferInOverflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"AddHoliday","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"inputs":[{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"addHoliday","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_timestamp","type":"uint64"},{"internalType":"uint256","name":"cutoffTime","type":"uint256"},{"internalType":"uint256","name":"transferBusinessDays","type":"uint256"}],"name":"businessDaysToCalendarDays","outputs":[{"internalType":"uint8","name":"numberOfDays","type":"uint8"},{"internalType":"uint256","name":"transferDayTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddr","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"isBusinessDay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"isHoliday","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isHolidayKeys","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"isWeekDay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"nonBusinessDays","outputs":[{"internalType":"uint64[]","name":"","type":"uint64[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_timestamp","type":"uint64"}],"name":"toMidnight","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"_timestamps","type":"uint64[]"}],"name":"updateNonBusinessDays","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b610d47806100ec6000396000f3fe608060405234801561001057600080fd5b506004361061008e5760003560e01c806316bc64f414610093578063231cfef9146100a85780633c3cb08b146100d057806353ee58e7146100fb57806380cba6561461010e5780638406cc8d14610121578063c3ccd92414610134578063c4d66de814610147578063cc0797a81461015a578063e38ab46c14610186575b600080fd5b6100a66100a13660046109ce565b61019b565b005b6100bb6100b6366004610a92565b610345565b60405190151581526020015b60405180910390f35b6100e36100de366004610a92565b61039a565b6040516001600160401b0390911681526020016100c7565b6100bb610109366004610a92565b6103b9565b6100bb61011c366004610a92565b6103ee565b6100e361012f366004610ab4565b61041c565b6100a6610142366004610a92565b610459565b6100a6610155366004610ae5565b6105fc565b61016d610168366004610b02565b610722565b6040805160ff90931683526020830191909152016100c7565b61018e610912565b6040516100c79190610b35565b6003546001600160a01b031633146101c65760405163c942a59b60e01b815260040160405180910390fd5b60025460005b8181101561023a5760016000600283815481106101eb576101eb610b82565b6000918252602080832060048304015460039092166008026101000a9091046001600160401b031683528201929092526040019020805460ff191690558061023281610bae565b9150506101cc565b5060005b8181101561029a57600280548061025757610257610bc7565b60008281526020902060046000199092019182040180546001600160401b03600860038516026101000a021916905590558061029281610bae565b91505061023e565b5060005b82518110156103405760006102cb8483815181106102be576102be610b82565b602002602001015161039a565b6001600160401b0390811660008181526001602081905260408220805460ff19168217905560028054918201815590915260048104600080516020610cf283398151915201805460086003909316929092026101000a928302929093021916179055508061033881610bae565b91505061029e565b505050565b6000806103556201518084610bf3565b905060006007610366836004610c19565b6103709190610c40565b90506001600160401b03811615806103915750806001600160401b03166006145b15949350505050565b60006103a96201518083610c40565b6103b39083610c66565b92915050565b60006103c482610345565b6103d057506000919050565b6103d9826103ee565b156103e657506000919050565b506001919050565b6000806103fa8361039a565b6001600160401b031660009081526001602052604090205460ff169392505050565b6002818154811061042c57600080fd5b9060005260206000209060049182820401919006600802915054906101000a90046001600160401b031681565b600360009054906101000a90046001600160a01b03166001600160a01b0316631311b7bf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d09190610c86565b604051637be53ca160e01b81523360048201526001600160a01b039190911690637be53ca190602401602060405180830381865afa158015610516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053a9190610ca3565b6105565760405162b145b560e31b815260040160405180910390fd5b60006105618261039a565b6001600160401b038181166000818152600160208181526040808420805460ff191684179055600280549384018155909352600080516020610cf28339815191526004830401805460039093166008026101000a95860219909216948402949094179055519081529192507f60ee73d3c5be9adbc8563d8b13f308bbd44cac7b3379e9e237b2d89c2bd7e03791015b60405180910390a15050565b600054610100900460ff161580801561061c5750600054600160ff909116105b806106365750303b158015610636575060005460ff166001145b61069e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156106c1576000805461ff0019166101001790555b600380546001600160a01b0319166001600160a01b038416179055801561071e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020016105f0565b5050565b600080600583106107755760405162461bcd60e51b815260206004820152601e60248201527f42443a207472616e73666572496e427573696e65737344617973203e203500006044820152606401610695565b60006107808661039a565b905060006107916201518088610c40565b6001600160401b031690508581101561083d576107b16201518083610c66565b6001600160401b03169250600093506000805b600a811015610836576107d6846103b9565b156107f9578682036107eb575050505061090a565b6107f6600183610cc5565b91505b6108066201518086610cc5565b94506108156201518085610c19565b9350610822600187610cd8565b95508061082e81610bae565b9150506107c4565b50506108f1565b600093506001600160401b038216925061085a6201518084610cc5565b92506108696201518083610c19565b9150610876600185610cd8565b93506000805b600a8110156108ee5761088e846103b9565b156108b1578682036108a3575050505061090a565b6108ae600183610cc5565b91505b6108be6201518086610cc5565b94506108cd6201518085610c19565b93506108da600187610cd8565b9550806108e681610bae565b91505061087c565b50505b6040516303b6aaf160e21b815260040160405180910390fd5b935093915050565b6060600280548060200260200160405190810160405280929190818152602001828054801561099257602002820191906000526020600020906000905b82829054906101000a90046001600160401b03166001600160401b03168152602001906008019060208260070104928301926001038202915080841161094f5790505b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b80356001600160401b03811681146109c957600080fd5b919050565b600060208083850312156109e157600080fd5b82356001600160401b03808211156109f857600080fd5b818501915085601f830112610a0c57600080fd5b813581811115610a1e57610a1e61099c565b8060051b604051601f19603f83011681018181108582111715610a4357610a4361099c565b604052918252848201925083810185019188831115610a6157600080fd5b938501935b82851015610a8657610a77856109b2565b84529385019392850192610a66565b98975050505050505050565b600060208284031215610aa457600080fd5b610aad826109b2565b9392505050565b600060208284031215610ac657600080fd5b5035919050565b6001600160a01b0381168114610ae257600080fd5b50565b600060208284031215610af757600080fd5b8135610aad81610acd565b600080600060608486031215610b1757600080fd5b610b20846109b2565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015610b765783516001600160401b031683529284019291840191600101610b51565b50909695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610bc057610bc0610b98565b5060010190565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b60006001600160401b0383811680610c0d57610c0d610bdd565b92169190910492915050565b6001600160401b03818116838216019080821115610c3957610c39610b98565b5092915050565b60006001600160401b0383811680610c5a57610c5a610bdd565b92169190910692915050565b6001600160401b03828116828216039080821115610c3957610c39610b98565b600060208284031215610c9857600080fd5b8151610aad81610acd565b600060208284031215610cb557600080fd5b81518015158114610aad57600080fd5b808201808211156103b3576103b3610b98565b60ff81811683821601908111156103b3576103b3610b9856fe405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acea26469706673582212207520ba07f81fd2363016f31f2747a4fcce97eb2b955de9660feb23a249cc486f64736f6c63430008100033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061008e5760003560e01c806316bc64f414610093578063231cfef9146100a85780633c3cb08b146100d057806353ee58e7146100fb57806380cba6561461010e5780638406cc8d14610121578063c3ccd92414610134578063c4d66de814610147578063cc0797a81461015a578063e38ab46c14610186575b600080fd5b6100a66100a13660046109ce565b61019b565b005b6100bb6100b6366004610a92565b610345565b60405190151581526020015b60405180910390f35b6100e36100de366004610a92565b61039a565b6040516001600160401b0390911681526020016100c7565b6100bb610109366004610a92565b6103b9565b6100bb61011c366004610a92565b6103ee565b6100e361012f366004610ab4565b61041c565b6100a6610142366004610a92565b610459565b6100a6610155366004610ae5565b6105fc565b61016d610168366004610b02565b610722565b6040805160ff90931683526020830191909152016100c7565b61018e610912565b6040516100c79190610b35565b6003546001600160a01b031633146101c65760405163c942a59b60e01b815260040160405180910390fd5b60025460005b8181101561023a5760016000600283815481106101eb576101eb610b82565b6000918252602080832060048304015460039092166008026101000a9091046001600160401b031683528201929092526040019020805460ff191690558061023281610bae565b9150506101cc565b5060005b8181101561029a57600280548061025757610257610bc7565b60008281526020902060046000199092019182040180546001600160401b03600860038516026101000a021916905590558061029281610bae565b91505061023e565b5060005b82518110156103405760006102cb8483815181106102be576102be610b82565b602002602001015161039a565b6001600160401b0390811660008181526001602081905260408220805460ff19168217905560028054918201815590915260048104600080516020610cf283398151915201805460086003909316929092026101000a928302929093021916179055508061033881610bae565b91505061029e565b505050565b6000806103556201518084610bf3565b905060006007610366836004610c19565b6103709190610c40565b90506001600160401b03811615806103915750806001600160401b03166006145b15949350505050565b60006103a96201518083610c40565b6103b39083610c66565b92915050565b60006103c482610345565b6103d057506000919050565b6103d9826103ee565b156103e657506000919050565b506001919050565b6000806103fa8361039a565b6001600160401b031660009081526001602052604090205460ff169392505050565b6002818154811061042c57600080fd5b9060005260206000209060049182820401919006600802915054906101000a90046001600160401b031681565b600360009054906101000a90046001600160a01b03166001600160a01b0316631311b7bf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d09190610c86565b604051637be53ca160e01b81523360048201526001600160a01b039190911690637be53ca190602401602060405180830381865afa158015610516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053a9190610ca3565b6105565760405162b145b560e31b815260040160405180910390fd5b60006105618261039a565b6001600160401b038181166000818152600160208181526040808420805460ff191684179055600280549384018155909352600080516020610cf28339815191526004830401805460039093166008026101000a95860219909216948402949094179055519081529192507f60ee73d3c5be9adbc8563d8b13f308bbd44cac7b3379e9e237b2d89c2bd7e03791015b60405180910390a15050565b600054610100900460ff161580801561061c5750600054600160ff909116105b806106365750303b158015610636575060005460ff166001145b61069e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156106c1576000805461ff0019166101001790555b600380546001600160a01b0319166001600160a01b038416179055801561071e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020016105f0565b5050565b600080600583106107755760405162461bcd60e51b815260206004820152601e60248201527f42443a207472616e73666572496e427573696e65737344617973203e203500006044820152606401610695565b60006107808661039a565b905060006107916201518088610c40565b6001600160401b031690508581101561083d576107b16201518083610c66565b6001600160401b03169250600093506000805b600a811015610836576107d6846103b9565b156107f9578682036107eb575050505061090a565b6107f6600183610cc5565b91505b6108066201518086610cc5565b94506108156201518085610c19565b9350610822600187610cd8565b95508061082e81610bae565b9150506107c4565b50506108f1565b600093506001600160401b038216925061085a6201518084610cc5565b92506108696201518083610c19565b9150610876600185610cd8565b93506000805b600a8110156108ee5761088e846103b9565b156108b1578682036108a3575050505061090a565b6108ae600183610cc5565b91505b6108be6201518086610cc5565b94506108cd6201518085610c19565b93506108da600187610cd8565b9550806108e681610bae565b91505061087c565b50505b6040516303b6aaf160e21b815260040160405180910390fd5b935093915050565b6060600280548060200260200160405190810160405280929190818152602001828054801561099257602002820191906000526020600020906000905b82829054906101000a90046001600160401b03166001600160401b03168152602001906008019060208260070104928301926001038202915080841161094f5790505b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b80356001600160401b03811681146109c957600080fd5b919050565b600060208083850312156109e157600080fd5b82356001600160401b03808211156109f857600080fd5b818501915085601f830112610a0c57600080fd5b813581811115610a1e57610a1e61099c565b8060051b604051601f19603f83011681018181108582111715610a4357610a4361099c565b604052918252848201925083810185019188831115610a6157600080fd5b938501935b82851015610a8657610a77856109b2565b84529385019392850192610a66565b98975050505050505050565b600060208284031215610aa457600080fd5b610aad826109b2565b9392505050565b600060208284031215610ac657600080fd5b5035919050565b6001600160a01b0381168114610ae257600080fd5b50565b600060208284031215610af757600080fd5b8135610aad81610acd565b600080600060608486031215610b1757600080fd5b610b20846109b2565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015610b765783516001600160401b031683529284019291840191600101610b51565b50909695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610bc057610bc0610b98565b5060010190565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b60006001600160401b0383811680610c0d57610c0d610bdd565b92169190910492915050565b6001600160401b03818116838216019080821115610c3957610c39610b98565b5092915050565b60006001600160401b0383811680610c5a57610c5a610bdd565b92169190910692915050565b6001600160401b03828116828216039080821115610c3957610c39610b98565b600060208284031215610c9857600080fd5b8151610aad81610acd565b600060208284031215610cb557600080fd5b81518015158114610aad57600080fd5b808201808211156103b3576103b3610b98565b60ff81811683821601908111156103b3576103b3610b9856fe405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acea26469706673582212207520ba07f81fd2363016f31f2747a4fcce97eb2b955de9660feb23a249cc486f64736f6c63430008100033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.