Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 2 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19732456 | 124 days ago | Contract Creation | 0 ETH | |||
19332490 | 180 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
BusinessDayRegistryFactory
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/IBusinessDayRegistryFactory.sol"; import "../interfaces/IServiceConfigurationV3.sol"; import "../BusinessDayRegistry.sol"; import "../upgrades/BeaconProxyFactory.sol"; import {BeaconProxy} from "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol"; /** * @title BusinessDayRegistryFactory * @dev Allows permissioning of pool participants through trusted verifications of */ contract BusinessDayRegistryFactory is IBusinessDayRegistryFactory, // Add this line BeaconProxyFactory { /** * @dev Constructor * @param serviceConfiguration Reference to the permissioned version * of the service configuration. */ constructor(address serviceConfiguration) { _serviceConfiguration = IServiceConfigurationV3(serviceConfiguration); } /** * @inheritdoc IBusinessDayRegistryFactory */ function create(address pool) external virtual override returns (address) { require(implementation != address(0), "BusinessDayRegistry no impl"); BeaconProxy proxy = new BeaconProxy( address(this), abi.encodeWithSelector( BusinessDayRegistry.initialize.selector, pool ) ); return address(proxy); } }
// 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 // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol) pragma solidity ^0.8.0; import "./IBeacon.sol"; import "../Proxy.sol"; import "../ERC1967/ERC1967Upgrade.sol"; /** * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}. * * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't * conflict with the storage layout of the implementation behind the proxy. * * _Available since v3.4._ */ contract BeaconProxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the proxy with `beacon`. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity * constructor. * * Requirements: * * - `beacon` must be a contract with the interface {IBeacon}. */ constructor(address beacon, bytes memory data) payable { _upgradeBeaconToAndCall(beacon, data, false); } /** * @dev Returns the current beacon address. */ function _beacon() internal view virtual returns (address) { return _getBeacon(); } /** * @dev Returns the current implementation address of the associated beacon. */ function _implementation() internal view virtual override returns (address) { return IBeacon(_getBeacon()).implementation(); } /** * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}. * * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. * * Requirements: * * - `beacon` must be a contract. * - The implementation returned by `beacon` must be a contract. */ function _setBeacon(address beacon, bytes memory data) internal virtual { _upgradeBeaconToAndCall(beacon, data, false); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/IERC1967.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967Upgrade is IERC1967 { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overridden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} }
// 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 Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * 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.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// 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 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 An interface for a factory that creates BusinessDayRegistry contracts. */ interface IBusinessDayRegistryFactory { /** * @dev Creates a new BusinessDayRegistry */ function create(address pool) external returns (address); }
// 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(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "../interfaces/IServiceConfigurationV3.sol"; import "./interfaces/IBeacon.sol"; /** * @title Factory for emitting beacon proxies. * @dev Base contract for emitting new Beacon proxy contracts. Allows setting new * implementations by the global deployer. */ abstract contract BeaconProxyFactory is IBeacon { /** * @dev Address of the protocol service configuration */ IServiceConfigurationV3 internal _serviceConfiguration; /** * @dev Modifier that requires that the sender is registered as a protocol deployer. */ modifier onlyDeployer() { require( _serviceConfiguration.isDeployer(msg.sender), "Upgrade: unauthorized" ); _; } /** * @inheritdoc IBeacon */ address public implementation; /** * @inheritdoc IBeacon */ function setImplementation( address newImplementation ) external onlyDeployer { implementation = newImplementation; emit ImplementationSet(newImplementation); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; /** * @title Interface for Beacon contracts. * @dev Holds a reference to the implementation, and allows setting new ones. */ interface IBeacon { /** * @dev Emitted when a new implementation is set. */ event ImplementationSet(address indexed implementation); /** * @dev Returns an address used by BeaconProxy contracts for delegated calls. */ function implementation() external view returns (address); /** * @dev Updates the implementation. */ function setImplementation(address implementation) external; }
{ "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":[{"internalType":"address","name":"serviceConfiguration","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"ImplementationSet","type":"event"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"create","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"setImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50604051610d14380380610d1483398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b610c81806100936000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80635c60da1b146100465780639ed933181461006f578063d784d42614610082575b600080fd5b600154610059906001600160a01b031681565b6040516100669190610289565b60405180910390f35b61005961007d36600461029d565b610097565b61009561009036600461029d565b61017d565b005b6001546000906001600160a01b03166100f55760405162461bcd60e51b815260206004820152601b60248201527a109d5cda5b995cdcd1185e549959da5cdd1c9e481b9bc81a5b5c1b602a1b60448201526064015b60405180910390fd5b60003063c4d66de860e01b846040516024016101119190610289565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161014e9061027c565b6101599291906102cd565b604051809103906000f080158015610175573d6000803e3d6000fd5b509392505050565b600054604051631430d62960e21b81526001600160a01b03909116906350c358a4906101ad903390600401610289565b602060405180830381865afa1580156101ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ee919061032b565b6102325760405162461bcd60e51b8152602060048201526015602482015274155c19dc9859194e881d5b985d5d1a1bdc9a5e9959605a1b60448201526064016100ec565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d1390600090a250565b6108fe8061034e83390190565b6001600160a01b0391909116815260200190565b6000602082840312156102af57600080fd5b81356001600160a01b03811681146102c657600080fd5b9392505050565b60018060a01b038316815260006020604081840152835180604085015260005b81811015610309578581018301518582016060015282016102ed565b506000606082860101526060601f19601f830116850101925050509392505050565b60006020828403121561033d57600080fd5b815180151581146102c657600080fdfe60806040526040516108fe3803806108fe8339810160408190526100229161045b565b61002e82826000610035565b5050610585565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e9919061051b565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d7919061051b565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108d7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe9190610536565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c95782516000036103c2576001600160a01b0385163b6103c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d3565b6103d383836103db565b949350505050565b8151156103eb5781518083602001fd5b8060405162461bcd60e51b81526004016101699190610552565b80516001600160a01b038116811461041c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561045257818101518382015260200161043a565b50506000910152565b6000806040838503121561046e57600080fd5b61047783610405565b60208401519092506001600160401b038082111561049457600080fd5b818501915085601f8301126104a857600080fd5b8151818111156104ba576104ba610421565b604051601f8201601f19908116603f011681019083821181831017156104e2576104e2610421565b816040528281528860208487010111156104fb57600080fd5b61050c836020830160208801610437565b80955050505050509250929050565b60006020828403121561052d57600080fd5b6102c882610405565b60008251610548818460208701610437565b9190910192915050565b6020815260008251806020840152610571816040850160208701610437565b601f01601f19169190910160400192915050565b610343806105946000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102e760279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb919061024a565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b0316856040516101419190610297565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020e578251600003610207576101b685610055565b6102075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610218565b6102188383610220565b949350505050565b8151156102305781518083602001fd5b8060405162461bcd60e51b81526004016101fe91906102b3565b60006020828403121561025c57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028e578181015183820152602001610276565b50506000910152565b600082516102a9818460208701610273565b9190910192915050565b60208152600082518060208401526102d2816040850160208701610273565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d7ce1835befd5faecbfea1c57664062796dc15afe2c20b368807d14fc6aa703b64736f6c63430008100033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200aaafdc1f6ea24f3d12622435911ff9c4da0f3cce49c428e961065fb1348c98864736f6c63430008100033000000000000000000000000ec4f65e0a0268ff38ecec711ad5159b96dabab98
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100415760003560e01c80635c60da1b146100465780639ed933181461006f578063d784d42614610082575b600080fd5b600154610059906001600160a01b031681565b6040516100669190610289565b60405180910390f35b61005961007d36600461029d565b610097565b61009561009036600461029d565b61017d565b005b6001546000906001600160a01b03166100f55760405162461bcd60e51b815260206004820152601b60248201527a109d5cda5b995cdcd1185e549959da5cdd1c9e481b9bc81a5b5c1b602a1b60448201526064015b60405180910390fd5b60003063c4d66de860e01b846040516024016101119190610289565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161014e9061027c565b6101599291906102cd565b604051809103906000f080158015610175573d6000803e3d6000fd5b509392505050565b600054604051631430d62960e21b81526001600160a01b03909116906350c358a4906101ad903390600401610289565b602060405180830381865afa1580156101ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ee919061032b565b6102325760405162461bcd60e51b8152602060048201526015602482015274155c19dc9859194e881d5b985d5d1a1bdc9a5e9959605a1b60448201526064016100ec565b600180546001600160a01b0319166001600160a01b0383169081179091556040517fab64f92ab780ecbf4f3866f57cee465ff36c89450dcce20237ca7a8d81fb7d1390600090a250565b6108fe8061034e83390190565b6001600160a01b0391909116815260200190565b6000602082840312156102af57600080fd5b81356001600160a01b03811681146102c657600080fd5b9392505050565b60018060a01b038316815260006020604081840152835180604085015260005b81811015610309578581018301518582016060015282016102ed565b506000606082860101526060601f19601f830116850101925050509392505050565b60006020828403121561033d57600080fd5b815180151581146102c657600080fdfe60806040526040516108fe3803806108fe8339810160408190526100229161045b565b61002e82826000610035565b5050610585565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e9919061051b565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d7919061051b565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108d7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe9190610536565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c95782516000036103c2576001600160a01b0385163b6103c25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d3565b6103d383836103db565b949350505050565b8151156103eb5781518083602001fd5b8060405162461bcd60e51b81526004016101699190610552565b80516001600160a01b038116811461041c57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561045257818101518382015260200161043a565b50506000910152565b6000806040838503121561046e57600080fd5b61047783610405565b60208401519092506001600160401b038082111561049457600080fd5b818501915085601f8301126104a857600080fd5b8151818111156104ba576104ba610421565b604051601f8201601f19908116603f011681019083821181831017156104e2576104e2610421565b816040528281528860208487010111156104fb57600080fd5b61050c836020830160208801610437565b80955050505050509250929050565b60006020828403121561052d57600080fd5b6102c882610405565b60008251610548818460208701610437565b9190910192915050565b6020815260008251806020840152610571816040850160208701610437565b601f01601f19169190910160400192915050565b610343806105946000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102e760279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb919061024a565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b0316856040516101419190610297565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020e578251600003610207576101b685610055565b6102075760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610218565b6102188383610220565b949350505050565b8151156102305781518083602001fd5b8060405162461bcd60e51b81526004016101fe91906102b3565b60006020828403121561025c57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028e578181015183820152602001610276565b50506000910152565b600082516102a9818460208701610273565b9190910192915050565b60208152600082518060208401526102d2816040850160208701610273565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d7ce1835befd5faecbfea1c57664062796dc15afe2c20b368807d14fc6aa703b64736f6c63430008100033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200aaafdc1f6ea24f3d12622435911ff9c4da0f3cce49c428e961065fb1348c98864736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ec4f65e0a0268ff38ecec711ad5159b96dabab98
-----Decoded View---------------
Arg [0] : serviceConfiguration (address): 0xec4F65e0A0268ff38ECEc711AD5159b96dAbaB98
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ec4f65e0a0268ff38ecec711ad5159b96dabab98
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.