fluid-contracts-public/deployments/mainnet/solcInputs/ccdaae20343501c61bda498819423fe2.json

573 lines
1.1 MiB
JSON
Raw Permalink Normal View History

{
"language": "Solidity",
"sources": {
"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInit
},
"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n"
},
"@openzeppelin/contracts/interfaces/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n"
},
"@openzeppelin/contracts/interfaces/IERC4626.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC4626.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\nimport \"../token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @dev Interface of the ERC4626 \"Tokenized Vault Standard\", as defined in\n * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].\n *\n * _Available since v4.7._\n */\ninterface IERC4626 is IERC20, IERC20Metadata {\n event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);\n\n event Withdraw(\n address indexed sender,\n address indexed receiver,\n address indexed owner,\n uint256 assets,\n uint256 shares\n );\n\n /**\n * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\n *\n * - MUST be an ERC-20 token contract.\n * - MUST NOT revert.\n */\n function asset() external view returns (address assetTokenAddress);\n\n /**\n * @dev Returns the total amount of the underlying asset that is “managed” by Vault.\n *\n * - SHOULD include any compounding that occurs from yield.\n * - MUST be inclusive of any fees that are charged against assets in the Vault.\n * - MUST NOT revert.\n */\n function totalAssets() external view returns (uint256 totalManagedAssets);\n\n /**\n * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\n * scenario where all the conditions are met.\n *\n * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n * - MUST NOT show any variations depending on the caller.\n * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n * - MUST NOT revert.\n *\n * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n * “average-users” price-per-share, meaning what the average user should expect to see when exchanging to and\n * from.\n */\n function convertToShares(uint256 assets) external view returns (uint256 shares);\n\n /**\n * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\n * scenario where all the conditions are met.\n *\n * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n * - MUST NOT show any variations depending on the caller.\n * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n * - MUST NOT revert.\n *\n * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n * “average-users” price-per-share, meaning what the average user should expect to see when exchanging to and\n * from.\n */\n function convertToAssets(uint256 shares) external view returns (uint256 assets);\n\n /**\n * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\n * through a deposit call.\n *\n * - MUST return a limited value if receiver is subject to some deposit limit.\n * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\n * - MUST NOT revert.\n */\n function maxDeposit(address receiver) external view returns (uint256 maxAssets);\n\n /**\n * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\n * current on-chain conditions.\n *\n * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\n * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\n * in the same transaction.\n * - MUST NOT account for deposit limits like those returned from maxDeposit
},
"@openzeppelin/contracts/proxy/beacon/IBeacon.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n"
},
"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n"
},
"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the a
},
"@openzeppelin/contracts/proxy/Proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n"
},
"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeTo(address newImplementation) external virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access c
},
"@openzeppelin/contracts/security/ReentrancyGuard.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC20/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-al
},
"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/cryptography/EIP712.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
},
"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n"
},
"@openzeppelin/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n"
},
"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implem
},
"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n /**\n * @dev Returns the total amount of tokens stored by the contract.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\n\n /**\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n * Use along with {totalSupply} to enumerate all tokens.\n */\n function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
},
"@openzeppelin/contracts/token/ERC721/IERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approv
},
"@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory err
},
"@openzeppelin/contracts/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"
},
"@openzeppelin/contracts/utils/Counters.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n"
},
"@openzeppelin/contracts/utils/cryptography/ECDSA.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` sho
},
"@openzeppelin/contracts/utils/cryptography/EIP712.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with
},
"@openzeppelin/contracts/utils/introspection/IERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts/utils/math/Math.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes on
},
"@openzeppelin/contracts/utils/math/SafeCast.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n
},
"@openzeppelin/contracts/utils/StorageSlot.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n"
},
"@openzeppelin/contracts/utils/Strings.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"@openzeppelin/contracts/utils/structs/EnumerableSet.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set
},
"contracts/config/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Error {\n error FluidConfigError(uint256 errorId_);\n}\n"
},
"contracts/config/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | LiquidityConfigHandler | \n |__________________________________*/\n\n /// @notice thrown when an input address is zero\n uint256 internal constant LiquidityConfigHandler__AddressZero = 100001;\n\n /// @notice thrown when an unauthorized `msg.sender` calls a protected method\n uint256 internal constant LiquidityConfigHandler__Unauthorized = 100002;\n\n /// @notice thrown when invalid params are passed into a method\n uint256 internal constant LiquidityConfigHandler__InvalidParams = 100003;\n\n /// @notice thrown when no update is currently needed\n uint256 internal constant LiquidityConfigHandler__NoUpdate = 100004;\n\n /// @notice thrown when slot is not used, e.g. when borrow token is 0 there is no borrow data\n uint256 internal constant LiquidityConfigHandler__SlotDoesNotExist = 100005;\n}\n"
},
"contracts/config/liquidityConfigHandler.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLiquidity } from \"../liquidity/interfaces/iLiquidity.sol\";\nimport { LiquiditySlotsLink } from \"../libraries/liquiditySlotsLink.sol\";\nimport { BigMathMinified } from \"../libraries/bigMathMinified.sol\";\nimport { IFluidReserveContract } from \"../reserve/interfaces/iReserveContract.sol\";\nimport { Structs as AdminModuleStructs } from \"../liquidity/adminModule/structs.sol\";\nimport { Error } from \"./error.sol\";\nimport { ErrorTypes } from \"./errorTypes.sol\";\n\nabstract contract Constants {\n IFluidReserveContract public immutable RESERVE_CONTRACT;\n IFluidLiquidity public immutable LIQUIDITY;\n address public immutable PROTOCOL;\n address public immutable WITHDRAW_TOKEN;\n address public immutable BORROW_TOKEN;\n\n uint256 public immutable BORROW_CHECKPOINT1;\n uint256 public immutable BORROW_CHECKPOINT2;\n uint256 public immutable BORROW_CHECKPOINT3;\n uint256 public immutable BORROW_EXPAND_UNTIL_CHECKPOINT1;\n uint256 public immutable BORROW_EXPAND_UNTIL_CHECKPOINT2;\n uint256 public immutable BORROW_EXPAND_UNTIL_CHECKPOINT3;\n uint256 public immutable BORROW_EXPAND_ABOVE_CHECKPOINT3;\n\n uint256 public immutable WITHDRAW_CHECKPOINT1;\n uint256 public immutable WITHDRAW_CHECKPOINT2;\n uint256 public immutable WITHDRAW_CHECKPOINT3;\n uint256 public immutable WITHDRAW_EXPAND_UNTIL_CHECKPOINT1;\n uint256 public immutable WITHDRAW_EXPAND_UNTIL_CHECKPOINT2;\n uint256 public immutable WITHDRAW_EXPAND_UNTIL_CHECKPOINT3;\n uint256 public immutable WITHDRAW_EXPAND_ABOVE_CHECKPOINT3;\n\n bytes32 internal immutable _LIQUDITY_WITHDRAW_TOKEN_EXCHANGE_PRICES_SLOT;\n bytes32 internal immutable _LIQUDITY_BORROW_TOKEN_EXCHANGE_PRICES_SLOT;\n\n bytes32 internal immutable _LIQUDITY_PROTOCOL_SUPPLY_SLOT;\n bytes32 internal immutable _LIQUDITY_PROTOCOL_BORROW_SLOT;\n\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xff;\n\n uint256 internal constant X14 = 0x3fff;\n uint256 internal constant X18 = 0x3ffff;\n uint256 internal constant X24 = 0xffffff;\n uint256 internal constant X64 = 0xffffffffffffffff;\n}\n\nabstract contract Events {\n /// @notice emitted when withdraw limit expand percent is updated\n event LogUpdateWithdrawLimitExpansion(uint256 supply, uint256 oldExpandPercent, uint256 newExpandPercent);\n /// @notice emitted when borrow limit expand percent is updated\n event LogUpdateBorrowLimitExpansion(uint256 borrow, uint256 oldExpandPercent, uint256 newExpandPercent);\n}\n\nabstract contract Structs {\n struct LimitCheckPoints {\n uint256 tvlCheckPoint1; // e.g. 20M\n uint256 expandPercentUntilCheckPoint1; // e.g. 25%\n uint256 tvlCheckPoint2; // e.g. 30M\n uint256 expandPercentUntilCheckPoint2; // e.g. 20%\n uint256 tvlCheckPoint3; // e.g. 40M\n uint256 expandPercentUntilCheckPoint3; // e.g. 15%\n uint256 expandPercentAboveCheckPoint3; // e.g. 10%\n }\n}\n\n/// @notice Sets limits on Liquidity for a protocol based on TVL checkpoints.\ncontract FluidLiquidityConfigHandler is Constants, Error, Events, Structs {\n /// @dev Validates that an address is not the zero address\n modifier validAddress(address value_) {\n if (value_ == address(0)) {\n revert FluidConfigError(ErrorTypes.LiquidityConfigHandler__AddressZero);\n }\n _;\n }\n\n /// @dev Validates that an address is a rebalancer (taken from reserve contract)\n modifier onlyRebalancer() {\n if (!RESERVE_CONTRACT.isRebalancer(msg.sender)) {\n revert FluidConfigError(ErrorTypes.LiquidityConfigHandler__Unauthorized);\n }\n _;\n }\n\n constructor(\n IFluidReserveContract reserveContract_,\n IFluidLiquidity liquidity_,\n address protocol_,\n address withdrawToken_, // can be unused in some cases (e.g. StETH)\n address borrowToken_, // can be unused
},
"contracts/infiniteProxy/error.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ncontract Error {\n error FluidInfiniteProxyError(uint256 errorId_);\n}\n"
},
"contracts/infiniteProxy/errorTypes.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | Infinite proxy | \n |__________________________________*/\n\n /// @notice thrown when an implementation does not exist\n uint256 internal constant InfiniteProxy__ImplementationNotExist = 50001;\n}\n"
},
"contracts/infiniteProxy/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Events {\n /// @notice emitted when a new admin is set\n event LogSetAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /// @notice emitted when a new dummy implementation is set\n event LogSetDummyImplementation(address indexed oldDummyImplementation, address indexed newDummyImplementation);\n\n /// @notice emitted when a new implementation is set with certain sigs\n event LogSetImplementation(address indexed implementation, bytes4[] sigs);\n\n /// @notice emitted when an implementation is removed\n event LogRemoveImplementation(address indexed implementation);\n}\n"
},
"contracts/infiniteProxy/interfaces/iProxy.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IProxy {\n function setAdmin(address newAdmin_) external;\n\n function setDummyImplementation(address newDummyImplementation_) external;\n\n function addImplementation(address implementation_, bytes4[] calldata sigs_) external;\n\n function removeImplementation(address implementation_) external;\n\n function getAdmin() external view returns (address);\n\n function getDummyImplementation() external view returns (address);\n\n function getImplementationSigs(address impl_) external view returns (bytes4[] memory);\n\n function getSigsImplementation(bytes4 sig_) external view returns (address);\n\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\n}\n"
},
"contracts/infiniteProxy/proxy.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { Events } from \"./events.sol\";\nimport { ErrorTypes } from \"./errorTypes.sol\";\nimport { Error } from \"./error.sol\";\nimport { StorageRead } from \"../libraries/storageRead.sol\";\n\ncontract CoreInternals is StorageRead, Events, Error {\n struct SigsSlot {\n bytes4[] value;\n }\n\n /// @dev Storage slot with the admin of the contract.\n /// This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n /// validated in the constructor.\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /// @dev Storage slot with the address of the current dummy-implementation.\n /// This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n /// validated in the constructor.\n bytes32 internal constant _DUMMY_IMPLEMENTATION_SLOT =\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /// @dev use EIP1967 proxy slot (see _DUMMY_IMPLEMENTATION_SLOT) except for first 4 bytes,\n // which are set to 0. This is combined with a sig which will be set in those first 4 bytes\n bytes32 internal constant _SIG_SLOT_BASE = 0x000000003ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /// @dev Returns the storage slot which stores the sigs array set for the implementation.\n function _getSlotImplSigsSlot(address implementation_) internal pure returns (bytes32) {\n return keccak256(abi.encode(\"eip1967.proxy.implementation\", implementation_));\n }\n\n /// @dev Returns the storage slot which stores the implementation address for the function sig.\n function _getSlotSigsImplSlot(bytes4 sig_) internal pure returns (bytes32 result_) {\n assembly {\n // or operator sets sig_ in first 4 bytes with rest of bytes32 having default value of _SIG_SLOT_BASE\n result_ := or(_SIG_SLOT_BASE, sig_)\n }\n }\n\n /// @dev Returns an address `data_` located at `slot_`.\n function _getAddressSlot(bytes32 slot_) internal view returns (address data_) {\n assembly {\n data_ := sload(slot_)\n }\n }\n\n /// @dev Sets an address `data_` located at `slot_`.\n function _setAddressSlot(bytes32 slot_, address data_) internal {\n assembly {\n sstore(slot_, data_)\n }\n }\n\n /// @dev Returns an `SigsSlot` with member `value` located at `slot`.\n function _getSigsSlot(bytes32 slot_) internal pure returns (SigsSlot storage _r) {\n assembly {\n _r.slot := slot_\n }\n }\n\n /// @dev Sets new implementation and adds mapping from implementation to sigs and sig to implementation.\n function _setImplementationSigs(address implementation_, bytes4[] memory sigs_) internal {\n require(sigs_.length != 0, \"no-sigs\");\n bytes32 slot_ = _getSlotImplSigsSlot(implementation_);\n bytes4[] memory sigsCheck_ = _getSigsSlot(slot_).value;\n require(sigsCheck_.length == 0, \"implementation-already-exist\");\n\n for (uint256 i; i < sigs_.length; i++) {\n bytes32 sigSlot_ = _getSlotSigsImplSlot(sigs_[i]);\n require(_getAddressSlot(sigSlot_) == address(0), \"sig-already-exist\");\n _setAddressSlot(sigSlot_, implementation_);\n }\n\n _getSigsSlot(slot_).value = sigs_;\n emit LogSetImplementation(implementation_, sigs_);\n }\n\n /// @dev Removes implementation and the mappings corresponding to it.\n function _removeImplementationSigs(address implementation_) internal {\n bytes32 slot_ = _getSlotImplSigsSlot(implementation_);\n bytes4[] memory sigs_ = _getSigsSlot(slot_).value;\n require(sigs_.length != 0, \"implementation-not-exist\");\n\n for (uint256 i; i < sigs_.length; i++) {\n bytes32 sigSlot_ = _getSlotSigsImplSlot(sigs_[i]);\n _setAddressSlot(sigSlot_, address(0));\n }\n\n delete _getSigsSlot(sl
},
"contracts/libraries/bigMathMinified.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @title library that represents a number in BigNumber(coefficient and exponent) format to store in smaller bits.\n/// @notice the number is divided into two parts: a coefficient and an exponent. This comes at a cost of losing some precision\n/// at the end of the number because the exponent simply fills it with zeroes. This precision is oftentimes negligible and can\n/// result in significant gas cost reduction due to storage space reduction.\n/// Also note, a valid big number is as follows: if the exponent is > 0, then coefficient last bits should be occupied to have max precision.\n/// @dev roundUp is more like a increase 1, which happens everytime for the same number.\n/// roundDown simply sets trailing digits after coefficientSize to zero (floor), only once for the same number.\nlibrary BigMathMinified {\n /// @dev constants to use for `roundUp` input param to increase readability\n bool internal constant ROUND_DOWN = false;\n bool internal constant ROUND_UP = true;\n\n /// @dev converts `normal` number to BigNumber with `exponent` and `coefficient` (or precision).\n /// e.g.:\n /// 5035703444687813576399599 (normal) = (coefficient[32bits], exponent[8bits])[40bits]\n /// 5035703444687813576399599 (decimal) => 10000101010010110100000011111011110010100110100000000011100101001101001101011101111 (binary)\n /// => 10000101010010110100000011111011000000000000000000000000000000000000000000000000000\n /// ^-------------------- 51(exponent) -------------- ^\n /// coefficient = 1000,0101,0100,1011,0100,0000,1111,1011 (2236301563)\n /// exponent = 0011,0011 (51)\n /// bigNumber = 1000,0101,0100,1011,0100,0000,1111,1011,0011,0011 (572493200179)\n ///\n /// @param normal number which needs to be converted into Big Number\n /// @param coefficientSize at max how many bits of precision there should be (64 = uint64 (64 bits precision))\n /// @param exponentSize at max how many bits of exponent there should be (8 = uint8 (8 bits exponent))\n /// @param roundUp signals if result should be rounded down or up\n /// @return bigNumber converted bigNumber (coefficient << exponent)\n function toBigNumber(\n uint256 normal,\n uint256 coefficientSize,\n uint256 exponentSize,\n bool roundUp\n ) internal pure returns (uint256 bigNumber) {\n assembly {\n let lastBit_\n let number_ := normal\n if gt(number_, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n number_ := shr(0x80, number_)\n lastBit_ := 0x80\n }\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\n number_ := shr(0x40, number_)\n lastBit_ := add(lastBit_, 0x40)\n }\n if gt(number_, 0xFFFFFFFF) {\n number_ := shr(0x20, number_)\n lastBit_ := add(lastBit_, 0x20)\n }\n if gt(number_, 0xFFFF) {\n number_ := shr(0x10, number_)\n lastBit_ := add(lastBit_, 0x10)\n }\n if gt(number_, 0xFF) {\n number_ := shr(0x8, number_)\n lastBit_ := add(lastBit_, 0x8)\n }\n if gt(number_, 0xF) {\n number_ := shr(0x4, number_)\n lastBit_ := add(lastBit_, 0x4)\n }\n if gt(number_, 0x3) {\n number_ := shr(0x2, number_)\n lastBit_ := add(lastBit_, 0x2)\n }\n if gt(number_, 0x1) {\n lastBit_ := add(lastBit_, 1)\n }\n if gt(number_, 0) {\n lastBit_ := add(lastBit_, 1)\n }\n if lt(lastBit_, coefficientSize) {\n // for throw exception\n lastBit_ := coefficientSize\n }\n let
},
"contracts/libraries/bigMathUnsafe.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n// todo: decide for license\n\n// Note: It's advised to use BigMathMinified which covers +90% of use cases, other functions need more thorough audits and testing\n\n/// @title library that represents a number in BigNumber(coefficient and exponent) format to store in smaller bits.\n/// @notice the number is divided into two parts: a coefficient and an exponent. This comes at a cost of losing some precision\n/// at the end of the number because the exponent simply fills it with zeroes. This precision is oftentimes negligible and can\n/// result in significant gas cost reduction due to storage space reduction.\n/// Also note, Valid big number is as follows: if the exponent is > 0, then coefficient last bits should be occupied to have max precision\n/// @dev roundUp is more like a increase 1, which happens everytime for the same number.\n/// roundDown simply sets trailing digits after coefficientSize to zero (floor), only once to the same number.\nlibrary BigMathUnsafe {\n /// @dev constants to use for `roundUp` input param to increase readability\n bool internal constant ROUND_DOWN = false;\n bool internal constant ROUND_UP = true;\n\n /// @dev converts `normal` number to BigNumber with `exponent` and `coefficient` (or precision).\n /// e.g.:\n /// 5035703444687813576399599 (normal) = (coefficient[32bits], exponent[8bits])[40bits]\n /// 5035703444687813576399599 (decimal) => 10000101010010110100000011111011110010100110100000000011100101001101001101011101111 (binary)\n /// => 10000101010010110100000011111011000000000000000000000000000000000000000000000000000\n /// ^-------------------- 51(exponent) -------------- ^\n /// coefficient = 1000,0101,0100,1011,0100,0000,1111,1011 (2236301563)\n /// exponent = 0011,0011 (51)\n /// bigNumber = 1000,0101,0100,1011,0100,0000,1111,1011,0011,0011 (572493200179)\n ///\n /// @param normal number which needs to be converted into Big Number\n /// @param coefficientSize at max how many bits of precision there should be (64 = uint64 (64 bits precision))\n /// @param exponentSize at max how many bits of exponent there should be (8 = uint8 (8 bits exponent))\n /// @param roundUp signals if result should be rounded down or up\n /// @return bigNumber converted bigNumber (coefficient << exponent)\n function toBigNumber(\n uint256 normal,\n uint256 coefficientSize,\n uint256 exponentSize,\n bool roundUp\n ) internal pure returns (uint256 bigNumber) {\n assembly {\n let lastBit_\n let number_ := normal\n if gt(number_, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) {\n number_ := shr(0x80, number_)\n lastBit_ := 0x80\n }\n if gt(number_, 0xFFFFFFFFFFFFFFFF) {\n number_ := shr(0x40, number_)\n lastBit_ := add(lastBit_, 0x40)\n }\n if gt(number_, 0xFFFFFFFF) {\n number_ := shr(0x20, number_)\n lastBit_ := add(lastBit_, 0x20)\n }\n if gt(number_, 0xFFFF) {\n number_ := shr(0x10, number_)\n lastBit_ := add(lastBit_, 0x10)\n }\n if gt(number_, 0xFF) {\n number_ := shr(0x8, number_)\n lastBit_ := add(lastBit_, 0x8)\n }\n if gt(number_, 0xF) {\n number_ := shr(0x4, number_)\n lastBit_ := add(lastBit_, 0x4)\n }\n if gt(number_, 0x3) {\n number_ := shr(0x2, number_)\n lastBit_ := add(lastBit_, 0x2)\n }\n if gt(number_, 0x1) {\n lastBit_ := add(lastBit_, 1)\n }\n if gt(number_, 0) {\n lastBit_ := add(lastBit_, 1)\n }\n
},
"contracts/libraries/bigMathVault.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { BigMathMinified } from \"./bigMathMinified.sol\";\n\n/// @title Extended version of BigMathMinified. Implements functions for normal operators (*, /, etc) modified to interact with big numbers.\n/// @notice this is an optimized version mainly created by taking Fluid vault's codebase into consideration so it's use is limited for other cases.\nlibrary BigMathVault {\n uint private constant COEFFICIENT_SIZE_DEBT_FACTOR = 35;\n uint private constant EXPONENT_SIZE_DEBT_FACTOR = 15;\n uint private constant COEFFICIENT_MAX_DEBT_FACTOR = (1 << COEFFICIENT_SIZE_DEBT_FACTOR) - 1;\n uint private constant EXPONENT_MAX_DEBT_FACTOR = (1 << EXPONENT_SIZE_DEBT_FACTOR) - 1;\n uint private constant DECIMALS_DEBT_FACTOR = 16384;\n uint internal constant MAX_MASK_DEBT_FACTOR = (1 << (COEFFICIENT_SIZE_DEBT_FACTOR + EXPONENT_SIZE_DEBT_FACTOR)) - 1;\n\n // Having precision as 2**64 on vault\n uint internal constant PRECISION = 64;\n uint internal constant TWO_POWER_64 = 1 << PRECISION;\n // Max bit for 35 bits * 35 bits number will be 70\n // why do we use 69 then here instead of 70\n uint internal constant TWO_POWER_69_MINUS_1 = (1 << 69) - 1;\n\n uint private constant COEFFICIENT_PLUS_PRECISION = COEFFICIENT_SIZE_DEBT_FACTOR + PRECISION; // 99\n uint private constant COEFFICIENT_PLUS_PRECISION_MINUS_1 = COEFFICIENT_PLUS_PRECISION - 1; // 98\n uint private constant TWO_POWER_COEFFICIENT_PLUS_PRECISION_MINUS_1 = (1 << COEFFICIENT_PLUS_PRECISION_MINUS_1) - 1; // (1 << 98) - 1;\n uint private constant TWO_POWER_COEFFICIENT_PLUS_PRECISION_MINUS_1_MINUS_1 =\n (1 << (COEFFICIENT_PLUS_PRECISION_MINUS_1 - 1)) - 1; // (1 << 97) - 1;\n\n /// @dev multiplies a `normal` number with a `bigNumber1` and then divides by `bigNumber2`.\n /// @dev For vault's use case MUST always:\n /// - bigNumbers have exponent size 15 bits\n /// - bigNumbers have coefficient size 35 bits and have 35th bit always 1 (when exponent > 0 BigMath numbers have max precision)\n /// so coefficients must always be in range 17179869184 <= coefficient <= 34359738367.\n /// - bigNumber1 (debt factor) always have exponent >= 1 & <= 16384\n /// - bigNumber2 (connection factor) always have exponent >= 1 & <= 32767 (15 bits)\n /// - bigNumber2 always >= bigNumber1 (connection factor can never be < base branch debt factor)\n /// - as a result of previous points, numbers must never be 0\n /// - normal is positionRawDebt and is always within 10000 and type(int128).max\n /// @return normal * bigNumber1 / bigNumber2\n function mulDivNormal(uint256 normal, uint256 bigNumber1, uint256 bigNumber2) internal pure returns (uint256) {\n unchecked {\n // exponent2_ - exponent1_\n uint netExponent_ = (bigNumber2 & EXPONENT_MAX_DEBT_FACTOR) - (bigNumber1 & EXPONENT_MAX_DEBT_FACTOR);\n if (netExponent_ < 129) {\n // (normal * coefficient1_) / (coefficient2_ << netExponent_);\n return ((normal * (bigNumber1 >> EXPONENT_SIZE_DEBT_FACTOR)) /\n ((bigNumber2 >> EXPONENT_SIZE_DEBT_FACTOR) << netExponent_));\n }\n // else:\n // biggest possible nominator: type(int128).max * 35bits max = 5846006549323611672814739330865132078589370433536\n // smallest possible denominator: 17179869184 << 129 (= 1 << 163) = 11692013098647223345629478661730264157247460343808\n // -> can only ever be 0\n return 0;\n }\n }\n\n /// @dev multiplies a `bigNumber` with normal `number1` and then divides by `TWO_POWER_64`.\n /// @dev For vault's use case (calculating new branch debt factor after liquidation):\n /// - number1 is debtFactor, intialized as TWO_POWER_64 and reduced from there, hence it's always <= TWO_POWER_64 and always > 0.\n /// - bigNumber is branch debt factor, which starts as ((X35 << 15) | (1 << 14)) and reduces
},
"contracts/libraries/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary LibsErrorTypes {\n /***********************************|\n | LiquidityCalcs | \n |__________________________________*/\n\n /// @notice thrown when supply or borrow exchange price is zero at calc token data (token not configured yet)\n uint256 internal constant LiquidityCalcs__ExchangePriceZero = 70001;\n\n /// @notice thrown when rate data is set to a version that is not implemented\n uint256 internal constant LiquidityCalcs__UnsupportedRateVersion = 70002;\n\n /***********************************|\n | SafeTransfer | \n |__________________________________*/\n\n /// @notice thrown when safe transfer from for an ERC20 fails\n uint256 internal constant SafeTransfer__TransferFromFailed = 71001;\n\n /// @notice thrown when safe transfer for an ERC20 fails\n uint256 internal constant SafeTransfer__TransferFailed = 71002;\n}\n"
},
"contracts/libraries/liquidityCalcs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { LibsErrorTypes as ErrorTypes } from \"./errorTypes.sol\";\nimport { LiquiditySlotsLink } from \"./liquiditySlotsLink.sol\";\nimport { BigMathMinified } from \"./bigMathMinified.sol\";\n\n/// @notice implements calculation methods used for Fluid liquidity such as updated exchange prices,\n/// borrow rate, withdrawal / borrow limits, revenue amount.\nlibrary LiquidityCalcs {\n error FluidLiquidityCalcsError(uint256 errorId_);\n\n /// @notice emitted if the calculated borrow rate surpassed max borrow rate (16 bits) and was capped at maximum value 65535\n event BorrowRateMaxCap();\n\n /// @dev constants as from Liquidity variables.sol\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n\n /// @dev Ignoring leap years\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\n // constants used for BigMath conversion from and to storage\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;\n\n uint256 internal constant FOUR_DECIMALS = 1e4;\n uint256 internal constant TWELVE_DECIMALS = 1e12;\n uint256 internal constant X14 = 0x3fff;\n uint256 internal constant X15 = 0x7fff;\n uint256 internal constant X16 = 0xffff;\n uint256 internal constant X18 = 0x3ffff;\n uint256 internal constant X24 = 0xffffff;\n uint256 internal constant X33 = 0x1ffffffff;\n uint256 internal constant X64 = 0xffffffffffffffff;\n\n ///////////////////////////////////////////////////////////////////////////\n ////////// CALC EXCHANGE PRICES /////////\n ///////////////////////////////////////////////////////////////////////////\n\n /// @dev calculates interest (exchange prices) for a token given its' exchangePricesAndConfig from storage.\n /// @param exchangePricesAndConfig_ exchange prices and config packed uint256 read from storage\n /// @return supplyExchangePrice_ updated supplyExchangePrice\n /// @return borrowExchangePrice_ updated borrowExchangePrice\n function calcExchangePrices(\n uint256 exchangePricesAndConfig_\n ) internal view returns (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) {\n // Extracting exchange prices\n supplyExchangePrice_ =\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE) &\n X64;\n borrowExchangePrice_ =\n (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE) &\n X64;\n\n if (supplyExchangePrice_ == 0 || borrowExchangePrice_ == 0) {\n revert FluidLiquidityCalcsError(ErrorTypes.LiquidityCalcs__ExchangePriceZero);\n }\n\n uint256 temp_ = exchangePricesAndConfig_ & X16; // temp_ = borrowRate\n\n unchecked {\n // last timestamp can not be > current timestamp\n uint256 secondsSinceLastUpdate_ = block.timestamp -\n ((exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_LAST_TIMESTAMP) & X33);\n\n uint256 borrowRatio_ = (exchangePricesAndConfig_ >> LiquiditySlotsLink.BITS_EXCHANGE_PRICES_BORROW_RATIO) &\n X15;\n if (secondsSinceLastUpdate_ == 0 || temp_ == 0 || borrowRatio_ == 1) {\n // if no time passed, borrow rate is 0, or no raw borrowings: no exchange price update needed\n // (if borrowRatio_ == 1 means there is only borrowInterestFree, as first bit is 1 and rest is 0)\n return (supplyExchangePrice_, borrowExchangePrice_);\n }\n\n // calculate new borrow exchange price.\n // formula borrowExchangePriceIncrease: previous price * borrow rate * secondsSinceLastUpdate_.\n // nominator is max uint112 (uint64 * uint16 * uint32). Divisor can not be 0.\n borrowExchangePrice_ +=\n (borrowExchangePrice_ * temp_ * secondsSinceLastUpdate_) /\n (SECO
},
"contracts/libraries/liquiditySlotsLink.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @notice library that helps in reading / working with storage slot data of Fluid Liquidity.\n/// @dev as all data for Fluid Liquidity is internal, any data must be fetched directly through manual\n/// slot reading through this library or, if gas usage is less important, through the FluidLiquidityResolver.\nlibrary LiquiditySlotsLink {\n /// @dev storage slot for status at Liquidity\n uint256 internal constant LIQUIDITY_STATUS_SLOT = 1;\n /// @dev storage slot for auths mapping at Liquidity\n uint256 internal constant LIQUIDITY_AUTHS_MAPPING_SLOT = 2;\n /// @dev storage slot for guardians mapping at Liquidity\n uint256 internal constant LIQUIDITY_GUARDIANS_MAPPING_SLOT = 3;\n /// @dev storage slot for user class mapping at Liquidity\n uint256 internal constant LIQUIDITY_USER_CLASS_MAPPING_SLOT = 4;\n /// @dev storage slot for exchangePricesAndConfig mapping at Liquidity\n uint256 internal constant LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT = 5;\n /// @dev storage slot for rateData mapping at Liquidity\n uint256 internal constant LIQUIDITY_RATE_DATA_MAPPING_SLOT = 6;\n /// @dev storage slot for totalAmounts mapping at Liquidity\n uint256 internal constant LIQUIDITY_TOTAL_AMOUNTS_MAPPING_SLOT = 7;\n /// @dev storage slot for user supply double mapping at Liquidity\n uint256 internal constant LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT = 8;\n /// @dev storage slot for user borrow double mapping at Liquidity\n uint256 internal constant LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT = 9;\n /// @dev storage slot for listed tokens array at Liquidity\n uint256 internal constant LIQUIDITY_LISTED_TOKENS_ARRAY_SLOT = 10;\n\n // --------------------------------\n // @dev stacked uint256 storage slots bits position data for each:\n\n // ExchangePricesAndConfig\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATE = 0;\n uint256 internal constant BITS_EXCHANGE_PRICES_FEE = 16;\n uint256 internal constant BITS_EXCHANGE_PRICES_UTILIZATION = 30;\n uint256 internal constant BITS_EXCHANGE_PRICES_UPDATE_THRESHOLD = 44;\n uint256 internal constant BITS_EXCHANGE_PRICES_LAST_TIMESTAMP = 58;\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_EXCHANGE_PRICE = 91;\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_EXCHANGE_PRICE = 155;\n uint256 internal constant BITS_EXCHANGE_PRICES_SUPPLY_RATIO = 219;\n uint256 internal constant BITS_EXCHANGE_PRICES_BORROW_RATIO = 234;\n\n // RateData:\n uint256 internal constant BITS_RATE_DATA_VERSION = 0;\n // RateData: V1\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_ZERO = 4;\n uint256 internal constant BITS_RATE_DATA_V1_UTILIZATION_AT_KINK = 20;\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_KINK = 36;\n uint256 internal constant BITS_RATE_DATA_V1_RATE_AT_UTILIZATION_MAX = 52;\n // RateData: V2\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_ZERO = 4;\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK1 = 20;\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK1 = 36;\n uint256 internal constant BITS_RATE_DATA_V2_UTILIZATION_AT_KINK2 = 52;\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_KINK2 = 68;\n uint256 internal constant BITS_RATE_DATA_V2_RATE_AT_UTILIZATION_MAX = 84;\n\n // TotalAmounts\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_WITH_INTEREST = 0;\n uint256 internal constant BITS_TOTAL_AMOUNTS_SUPPLY_INTEREST_FREE = 64;\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_WITH_INTEREST = 128;\n uint256 internal constant BITS_TOTAL_AMOUNTS_BORROW_INTEREST_FREE = 192;\n\n // UserSupplyData\n uint256 internal constant BITS_USER_SUPPLY_MODE = 0;\n uint256 internal constant BITS_USER_SUPPLY_AMOUNT = 1;\n uint256 internal constant BITS_USER_SUPPLY_PREVIOUS_WITHDRAWAL_LIMIT = 65;\n uint256 internal constant BITS_USER_SUPPLY_LAST_UPDATE
},
"contracts/libraries/safeTransfer.sol": {
"content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity 0.8.21;\n\nimport { LibsErrorTypes as ErrorTypes } from \"./errorTypes.sol\";\n\n/// @notice provides minimalistic methods for safe transfers, e.g. ERC20 safeTransferFrom\nlibrary SafeTransfer {\n error FluidSafeTransferError(uint256 errorId_);\n\n /// @dev Transfer `amount_` of `token_` from `from_` to `to_`, spending the approval given by `from_` to the\n /// calling contract. If `token_` returns no value, non-reverting calls are assumed to be successful.\n /// Minimally modified from Solmate SafeTransferLib (address as input param for token, Custom Error):\n /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L31-L63\n function safeTransferFrom(address token_, address from_, address to_, uint256 amount_) internal {\n bool success_;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), and(from_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"from_\" argument.\n mstore(add(freeMemoryPointer, 36), and(to_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to_\" argument.\n mstore(add(freeMemoryPointer, 68), amount_) // Append the \"amount_\" argument. Masking not required as it's a full 32 byte type.\n\n success_ := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.\n // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n // Counterintuitively, this call must be positioned second to the or() call in the\n // surrounding and() call or else returndatasize() will be zero during the computation.\n call(gas(), token_, 0, freeMemoryPointer, 100, 0, 32)\n )\n }\n\n if (!success_) {\n revert FluidSafeTransferError(ErrorTypes.SafeTransfer__TransferFromFailed);\n }\n }\n\n /// @dev Transfer `amount_` of `token_` to `to_`.\n /// If `token_` returns no value, non-reverting calls are assumed to be successful.\n /// Minimally modified from Solmate SafeTransferLib (address as input param for token, Custom Error):\n /// https://github.com/transmissions11/solmate/blob/50e15bb566f98b7174da9b0066126a4c3e75e0fd/src/utils/SafeTransferLib.sol#L65-L95\n function safeTransfer(address token_, address to_, uint256 amount_) internal {\n bool success_;\n\n /// @solidity memory-safe-assembly\n assembly {\n // Get a pointer to some free memory.\n let freeMemoryPointer := mload(0x40)\n\n // Write the abi-encoded calldata into memory, beginning with the function selector.\n mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n mstore(add(freeMemoryPointer, 4), and(to_, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the \"to_\" argument.\n mstore(add(freeMemoryPointer, 36), amount_) // Append the \"amount_\" argument. Masking not required as it's a full 32 byte type.\n\n success_ := and(\n // Set success to whether the call reverted, if not we check it either\n // returned exactly 1 (can't just be non-zero data), or had no return data.\n or(and(eq(mload(0), 1), gt(returndatasize
},
"contracts/libraries/storageRead.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @notice implements a method to read uint256 data from storage at a bytes32 storage slot key.\ncontract StorageRead {\n function readFromStorage(bytes32 slot_) public view returns (uint256 result_) {\n assembly {\n result_ := sload(slot_) // read value from the storage slot\n }\n }\n}\n"
},
"contracts/libraries/tickMath.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @title library that calculates number \"tick\" and \"ratioX96\" from this: ratioX96 = (1.0015^tick) * 2^96\n/// @notice this library is used in Fluid Vault protocol for optimiziation.\n/// @dev \"tick\" supports between -32767 and 32767. \"ratioX96\" supports between 37075072 and 169307877264527972847801929085841449095838922544595\nlibrary TickMath {\n /// The minimum tick that can be passed in getRatioAtTick. 1.0015**-32767\n int24 internal constant MIN_TICK = -32767;\n /// The maximum tick that can be passed in getRatioAtTick. 1.0015**32767\n int24 internal constant MAX_TICK = 32767;\n\n uint256 internal constant FACTOR00 = 0x100000000000000000000000000000000;\n uint256 internal constant FACTOR01 = 0xff9dd7de423466c20352b1246ce4856f; // 2^128/1.0015**1 = 339772707859149738855091969477551883631\n uint256 internal constant FACTOR02 = 0xff3bd55f4488ad277531fa1c725a66d0; // 2^128/1.0015**2 = 339263812140938331358054887146831636176\n uint256 internal constant FACTOR03 = 0xfe78410fd6498b73cb96a6917f853259; // 2^128/1.0015**4 = 338248306163758188337119769319392490073\n uint256 internal constant FACTOR04 = 0xfcf2d9987c9be178ad5bfeffaa123273; // 2^128/1.0015**8 = 336226404141693512316971918999264834163\n uint256 internal constant FACTOR05 = 0xf9ef02c4529258b057769680fc6601b3; // 2^128/1.0015**16 = 332218786018727629051611634067491389875\n uint256 internal constant FACTOR06 = 0xf402d288133a85a17784a411f7aba082; // 2^128/1.0015**32 = 324346285652234375371948336458280706178\n uint256 internal constant FACTOR07 = 0xe895615b5beb6386553757b0352bda90; // 2^128/1.0015**64 = 309156521885964218294057947947195947664\n uint256 internal constant FACTOR08 = 0xd34f17a00ffa00a8309940a15930391a; // 2^128/1.0015**128 = 280877777739312896540849703637713172762 \n uint256 internal constant FACTOR09 = 0xae6b7961714e20548d88ea5123f9a0ff; // 2^128/1.0015**256 = 231843708922198649176471782639349113087\n uint256 internal constant FACTOR10 = 0x76d6461f27082d74e0feed3b388c0ca1; // 2^128/1.0015**512 = 157961477267171621126394973980180876449\n uint256 internal constant FACTOR11 = 0x372a3bfe0745d8b6b19d985d9a8b85bb; // 2^128/1.0015**1024 = 73326833024599564193373530205717235131\n uint256 internal constant FACTOR12 = 0x0be32cbee48979763cf7247dd7bb539d; // 2^128/1.0015**2048 = 15801066890623697521348224657638773661\n uint256 internal constant FACTOR13 = 0x8d4f70c9ff4924dac37612d1e2921e; // 2^128/1.0015**4096 = 733725103481409245883800626999235102\n uint256 internal constant FACTOR14 = 0x4e009ae5519380809a02ca7aec77; // 2^128/1.0015**8192 = 1582075887005588088019997442108535\n uint256 internal constant FACTOR15 = 0x17c45e641b6e95dee056ff10; // 2^128/1.0015**16384 = 7355550435635883087458926352\n\n /// The minimum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MIN_TICK). ~ Equivalent to `(1 << 96) * (1.0015**-32767)`\n uint256 internal constant MIN_RATIOX96 = 37075072;\n /// The maximum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MAX_TICK).\n /// ~ Equivalent to `(1 << 96) * (1.0015**32767)`, rounding etc. leading to minor difference\n uint256 internal constant MAX_RATIOX96 = 169307877264527972847801929085841449095838922544595;\n\n uint256 internal constant ZERO_TICK_SCALED_RATIO = 0x1000000000000000000000000; // 1 << 96 // 79228162514264337593543950336\n uint256 internal constant _1E26 = 1e26;\n\n /// @notice ratioX96 = (1.0015^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return ratioX96 ratio = (debt amount/collateral amount)\n function getRatioAtTick(int tick) internal pure returns (uint256 ratioX96) {\n assembly {\n let absTick_ := sub(xor(tick, sar(255, tick)), sar(255, tick))\n\n if gt(absTick_, MAX_TICK) {\n revert(0, 0)\n }\n let factor_ := FACTOR00\n if
},
"contracts/liquidity/adminModule/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Structs } from \"./structs.sol\";\n\ncontract Events is Structs {\n /// @notice emitted when allowed auths are updated\n event LogUpdateAuths(AddressBool[] authsStatus);\n\n /// @notice emitted when allowed guardians are updated\n event LogUpdateGuardians(AddressBool[] guardiansStatus);\n\n /// @notice emitted when revenue collector address is updated\n event LogUpdateRevenueCollector(address indexed revenueCollector);\n\n /// @notice emitted when status is changed (paused / unpaused)\n event LogChangeStatus(uint256 indexed newStatus);\n\n /// @notice emitted when user classes are updated\n event LogUpdateUserClasses(AddressUint256[] userClasses);\n\n /// @notice emitted when token configs are updated\n event LogUpdateTokenConfigs(TokenConfig[] tokenConfigs);\n\n /// @notice emitted when user supply configs are updated\n event LogUpdateUserSupplyConfigs(UserSupplyConfig[] userSupplyConfigs);\n\n /// @notice emitted when user borrow configs are updated\n event LogUpdateUserBorrowConfigs(UserBorrowConfig[] userBorrowConfigs);\n\n /// @notice emitted when a user gets certain tokens paused\n event LogPauseUser(address user, address[] supplyTokens, address[] borrowTokens);\n\n /// @notice emitted when a user gets certain tokens unpaused\n event LogUnpauseUser(address user, address[] supplyTokens, address[] borrowTokens);\n\n /// @notice emitted when token rate data is updated with rate data v1\n event LogUpdateRateDataV1s(RateDataV1Params[] tokenRateDatas);\n\n /// @notice emitted when token rate data is updated with rate data v2\n event LogUpdateRateDataV2s(RateDataV2Params[] tokenRateDatas);\n\n /// @notice emitted when revenue is collected\n event LogCollectRevenue(address indexed token, uint256 indexed amount);\n\n /// @notice emitted when exchange prices and borrow rate are updated\n event LogUpdateExchangePrices(\n address indexed token,\n uint256 indexed supplyExchangePrice,\n uint256 indexed borrowExchangePrice,\n uint256 borrowRate,\n uint256 utilization\n );\n}\n"
},
"contracts/liquidity/adminModule/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { FixedPointMathLib } from \"solmate/src/utils/FixedPointMathLib.sol\";\n\nimport { BigMathMinified } from \"../../libraries/bigMathMinified.sol\";\nimport { LiquidityCalcs } from \"../../libraries/liquidityCalcs.sol\";\nimport { LiquiditySlotsLink } from \"../../libraries/liquiditySlotsLink.sol\";\nimport { Events } from \"./events.sol\";\nimport { Structs } from \"./structs.sol\";\nimport { CommonHelpers } from \"../common/helpers.sol\";\nimport { IFluidLiquidityAdmin } from \"../interfaces/iLiquidity.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\n\nabstract contract AdminModuleConstants is Error {\n /// @dev hard cap value for max borrow limit, used as sanity check. Usually 10x of total supply.\n uint256 public immutable NATIVE_TOKEN_MAX_BORROW_LIMIT_CAP;\n\n constructor(uint256 nativeTokenMaxBorrowLimitCap_) {\n if (nativeTokenMaxBorrowLimitCap_ == 0) {\n revert FluidLiquidityError(ErrorTypes.AdminModule__InvalidParams);\n }\n\n NATIVE_TOKEN_MAX_BORROW_LIMIT_CAP = nativeTokenMaxBorrowLimitCap_;\n }\n}\n\n/// @notice Fluid Liquidity Governance only related methods\nabstract contract GovernanceModule is IFluidLiquidityAdmin, CommonHelpers, Events, AdminModuleConstants {\n /// @notice only governance guard\n modifier onlyGovernance() {\n if (_getGovernanceAddr() != msg.sender) {\n revert FluidLiquidityError(ErrorTypes.AdminModule__OnlyGovernance);\n }\n _;\n }\n\n /// @dev checks that `value_` is a valid address (not zero address)\n function _checkValidAddress(address value_) internal pure {\n if (value_ == address(0)) {\n revert FluidLiquidityError(ErrorTypes.AdminModule__AddressZero);\n }\n }\n\n /// @dev checks that `value_` address is a contract (which includes address zero check)\n function _checkIsContractOrNativeAddress(address value_) internal view {\n if (value_.code.length == 0 && value_ != NATIVE_TOKEN_ADDRESS) {\n revert FluidLiquidityError(ErrorTypes.AdminModule__AddressNotAContract);\n }\n }\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateAuths(AddressBool[] calldata authsStatus_) external onlyGovernance {\n uint256 length_ = authsStatus_.length;\n for (uint256 i; i < length_; ) {\n _checkValidAddress(authsStatus_[i].addr);\n\n _isAuth[authsStatus_[i].addr] = authsStatus_[i].value ? 1 : 0;\n\n unchecked {\n ++i;\n }\n }\n\n emit LogUpdateAuths(authsStatus_);\n }\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateGuardians(AddressBool[] calldata guardiansStatus_) external onlyGovernance {\n uint256 length_ = guardiansStatus_.length;\n for (uint256 i; i < length_; ) {\n _checkValidAddress(guardiansStatus_[i].addr);\n\n _isGuardian[guardiansStatus_[i].addr] = guardiansStatus_[i].value ? 1 : 0;\n\n unchecked {\n ++i;\n }\n }\n\n emit LogUpdateGuardians(guardiansStatus_);\n }\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateRevenueCollector(address revenueCollector_) external onlyGovernance {\n _checkValidAddress(revenueCollector_);\n\n _revenueCollector = revenueCollector_;\n\n emit LogUpdateRevenueCollector(revenueCollector_);\n }\n}\n\nabstract contract AuthInternals is Error, CommonHelpers, Events {\n /// @dev computes rata data packed uint256 for version 1 rate input params telling desired values\n /// at different uzilitation points (0%, kink, 100%)\n /// @param rataDataV1Params_ rata data params for a given token\n /// @return
},
"contracts/liquidity/adminModule/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Structs {\n struct AddressBool {\n address addr;\n bool value;\n }\n\n struct AddressUint256 {\n address addr;\n uint256 value;\n }\n\n /// @notice struct to set borrow rate data for version 1\n struct RateDataV1Params {\n ///\n /// @param token for rate data\n address token;\n ///\n /// @param kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\n /// utilization below kink usually means slow increase in rate, once utilization is above kink borrow rate increases fast\n uint256 kink;\n ///\n /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100\n /// i.e. constant minimum borrow rate\n /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)\n uint256 rateAtUtilizationZero;\n ///\n /// @param rateAtUtilizationKink borrow rate when utilization is at kink. in 1e2: 100% = 10_000; 1% = 100\n /// e.g. when rate should be 7% at kink then rateAtUtilizationKink would be 700\n uint256 rateAtUtilizationKink;\n ///\n /// @param rateAtUtilizationMax borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100\n /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500\n uint256 rateAtUtilizationMax;\n }\n\n /// @notice struct to set borrow rate data for version 2\n struct RateDataV2Params {\n ///\n /// @param token for rate data\n address token;\n ///\n /// @param kink1 first kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\n /// utilization below kink 1 usually means slow increase in rate, once utilization is above kink 1 borrow rate increases faster\n uint256 kink1;\n ///\n /// @param kink2 second kink in borrow rate. in 1e2: 100% = 10_000; 1% = 100\n /// utilization below kink 2 usually means slow / medium increase in rate, once utilization is above kink 2 borrow rate increases fast\n uint256 kink2;\n ///\n /// @param rateAtUtilizationZero desired borrow rate when utilization is zero. in 1e2: 100% = 10_000; 1% = 100\n /// i.e. constant minimum borrow rate\n /// e.g. at utilization = 0.01% rate could still be at least 4% (rateAtUtilizationZero would be 400 then)\n uint256 rateAtUtilizationZero;\n ///\n /// @param rateAtUtilizationKink1 desired borrow rate when utilization is at first kink. in 1e2: 100% = 10_000; 1% = 100\n /// e.g. when rate should be 7% at first kink then rateAtUtilizationKink would be 700\n uint256 rateAtUtilizationKink1;\n ///\n /// @param rateAtUtilizationKink2 desired borrow rate when utilization is at second kink. in 1e2: 100% = 10_000; 1% = 100\n /// e.g. when rate should be 7% at second kink then rateAtUtilizationKink would be 1_200\n uint256 rateAtUtilizationKink2;\n ///\n /// @param rateAtUtilizationMax desired borrow rate when utilization is maximum at 100%. in 1e2: 100% = 10_000; 1% = 100\n /// e.g. when rate should be 125% at 100% then rateAtUtilizationMax would be 12_500\n uint256 rateAtUtilizationMax;\n }\n\n /// @notice struct to set token config\n struct TokenConfig {\n ///\n /// @param token address\n address token;\n ///\n /// @param fee charges on borrower's interest. in 1e2: 100% = 10_000; 1% = 100\n uint256 fee;\n ///\n /// @param threshold on when to update the storage slot. in 1e2: 100% = 10_000; 1% = 100\n uint256 threshold;\n }\n\n /// @notice struct to set user supply & withdrawal config\n struct UserSupplyConfig {\n ///\n /// @param user address\n address user;\n ///\n /// @param token address\n address token;\n ///\n
},
"contracts/liquidity/common/helpers.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Variables } from \"./variables.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\n\n/// @dev ReentrancyGuard based on OpenZeppelin implementation.\n/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.8/contracts/security/ReentrancyGuard.sol\nabstract contract ReentrancyGuard is Variables, Error {\n uint8 internal constant REENTRANCY_NOT_ENTERED = 1;\n uint8 internal constant REENTRANCY_ENTERED = 2;\n\n constructor() {\n _status = REENTRANCY_NOT_ENTERED;\n }\n\n /// @dev Prevents a contract from calling itself, directly or indirectly.\n /// See OpenZeppelin implementation for more info\n modifier reentrancy() {\n // On the first call to nonReentrant, _status will be NOT_ENTERED\n if (_status == REENTRANCY_ENTERED) {\n revert FluidLiquidityError(ErrorTypes.LiquidityHelpers__Reentrancy);\n }\n\n // Any calls to nonReentrant after this point will fail\n _status = REENTRANCY_ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = REENTRANCY_NOT_ENTERED;\n }\n}\n\nabstract contract CommonHelpers is ReentrancyGuard {\n /// @dev Returns the current admin (governance).\n function _getGovernanceAddr() internal view returns (address governance_) {\n assembly {\n governance_ := sload(GOVERNANCE_SLOT)\n }\n }\n}\n"
},
"contracts/liquidity/common/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract ConstantVariables {\n /// @dev Storage slot with the admin of the contract. Logic from \"proxy.sol\".\n /// This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is validated in the constructor.\n bytes32 internal constant GOVERNANCE_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n\n /// @dev address that is mapped to the chain native token\n address internal constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n /// @dev limit for triggering a revert if sent along excess `msg.value` is bigger than this amount\n uint256 internal constant NATIVE_AMOUNT_EXCESS_LIMIT = 1e9;\n\n /// @dev Ignoring leap years\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\n\n /// @dev limit any total amount to be half of type(uint128).max (~3.4e38) at type(int128).max (~1.7e38) as safety\n /// measure for any potential overflows / unexpected outcomes. This is checked for total borrow / supply.\n uint256 internal constant MAX_TOKEN_AMOUNT_CAP = uint256(uint128(type(int128).max));\n\n /// @dev time after which a write to storage of exchangePricesAndConfig will happen always.\n uint256 internal constant FORCE_STORAGE_WRITE_AFTER_TIME = 1 days;\n\n /// @dev constants used for BigMath conversion from and to storage\n uint256 internal constant SMALL_COEFFICIENT_SIZE = 10;\n uint256 internal constant DEFAULT_COEFFICIENT_SIZE = 56;\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;\n\n /// @dev constants to increase readability for using bit masks\n uint256 internal constant FOUR_DECIMALS = 1e4;\n uint256 internal constant TWELVE_DECIMALS = 1e12;\n uint256 internal constant X8 = 0xff;\n uint256 internal constant X14 = 0x3fff;\n uint256 internal constant X15 = 0x7fff;\n uint256 internal constant X16 = 0xffff;\n uint256 internal constant X18 = 0x3ffff;\n uint256 internal constant X24 = 0xffffff;\n uint256 internal constant X33 = 0x1ffffffff;\n uint256 internal constant X64 = 0xffffffffffffffff;\n}\n\ncontract Variables is ConstantVariables {\n /// @dev address of contract that gets sent the revenue. Configurable by governance\n address internal _revenueCollector;\n\n // 12 bytes empty\n\n // ----- storage slot 1 ------\n\n /// @dev paused status: status = 1 -> normal. status = 2 -> paused.\n /// not tightly packed with revenueCollector address to allow for potential changes later that improve gas more\n /// (revenueCollector is only rarely used by admin methods, where optimization is not as important).\n /// to be replaced with transient storage once EIP-1153 Transient storage becomes available with dencun upgrade.\n uint256 internal _status;\n\n // ----- storage slot 2 ------\n\n /// @dev Auths can set most config values. E.g. contracts that automate certain flows like e.g. adding a new fToken.\n /// Governance can add/remove auths.\n /// Governance is auth by default\n mapping(address => uint256) internal _isAuth;\n\n // ----- storage slot 3 ------\n\n /// @dev Guardians can pause lower class users\n /// Governance can add/remove guardians\n /// Governance is guardian by default\n mapping(address => uint256) internal _isGuardian;\n\n // ----- storage slot 4 ------\n\n /// @dev class defines which protocols can be paused by guardians\n /// Currently there are 2 classes: 0 can be paused by guardians. 1 cannot be paused by guardians.\n /// New protocols are added as class 0 and will be upgraded to 1 over time.\n mapping(address => uint256) internal _userClass;\n\n // ----- storage slot 5 ------\n\n /// @dev exchange prices and token config per token: token -> exchange prices & config\n /// First 16 bits => 0- 15 => borrow rate (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /
},
"contracts/liquidity/dummyImpl.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLiquidityLogic, IFluidLiquidityAdmin } from \"./interfaces/iLiquidity.sol\";\nimport { Structs as AdminModuleStructs } from \"./adminModule/structs.sol\";\n\n/// @notice Liquidity dummy implementation used for Fluid Liquidity infinite proxy.\n/// @dev see https://github.com/Instadapp/infinite-proxy?tab=readme-ov-file#dummy-implementation\ncontract FluidLiquidityDummyImpl is IFluidLiquidityLogic {\n /// @inheritdoc IFluidLiquidityAdmin\n function updateAuths(AdminModuleStructs.AddressBool[] calldata authsStatus_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateGuardians(AdminModuleStructs.AddressBool[] calldata guardiansStatus_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateRevenueCollector(address revenueCollector_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function changeStatus(uint256 newStatus_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateRateDataV1s(AdminModuleStructs.RateDataV1Params[] calldata tokensRateData_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateRateDataV2s(AdminModuleStructs.RateDataV2Params[] calldata tokensRateData_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateTokenConfigs(AdminModuleStructs.TokenConfig[] calldata tokenConfigs_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateUserClasses(AdminModuleStructs.AddressUint256[] calldata userClasses_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateUserSupplyConfigs(AdminModuleStructs.UserSupplyConfig[] memory userSupplyConfigs_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateUserBorrowConfigs(AdminModuleStructs.UserBorrowConfig[] memory userBorrowConfigs_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function pauseUser(address user_, address[] calldata supplyTokens_, address[] calldata borrowTokens_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function unpauseUser(address user_, address[] calldata supplyTokens_, address[] calldata borrowTokens_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function collectRevenue(address[] calldata tokens_) external {}\n\n /// @inheritdoc IFluidLiquidityAdmin\n function updateExchangePrices(\n address[] calldata tokens_\n ) external returns (uint256[] memory supplyExchangePrices_, uint256[] memory borrowExchangePrices_) {}\n\n /// @inheritdoc IFluidLiquidityLogic\n function operate(\n address token_,\n int256 supplyAmount_,\n int256 borrowAmount_,\n address withdrawTo_,\n address borrowTo_,\n bytes calldata callbackData_\n ) external payable returns (uint256 memVar3_, uint256 memVar4_) {}\n}\n"
},
"contracts/liquidity/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Error {\n error FluidLiquidityError(uint256 errorId_);\n}\n"
},
"contracts/liquidity/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | Admin Module | \n |__________________________________*/\n\n /// @notice thrown when an input address is zero\n uint256 internal constant AdminModule__AddressZero = 10001;\n\n /// @notice thrown when msg.sender is not governance\n uint256 internal constant AdminModule__OnlyGovernance = 10002;\n\n /// @notice thrown when msg.sender is not auth\n uint256 internal constant AdminModule__OnlyAuths = 10003;\n\n /// @notice thrown when msg.sender is not guardian\n uint256 internal constant AdminModule__OnlyGuardians = 10004;\n\n /// @notice thrown when base withdrawal limit, base debt limit or max withdrawal limit is sent as 0\n uint256 internal constant AdminModule__LimitZero = 10005;\n\n /// @notice thrown whenever an invalid input param is given\n uint256 internal constant AdminModule__InvalidParams = 10006;\n\n /// @notice thrown if user class 1 is paused (can not be paused)\n uint256 internal constant AdminModule__UserNotPausable = 10007;\n\n /// @notice thrown if user is tried to be unpaused but is not paused in the first place\n uint256 internal constant AdminModule__UserNotPaused = 10008;\n\n /// @notice thrown if user is not defined yet: Governance didn't yet set any config for this user on a particular token\n uint256 internal constant AdminModule__UserNotDefined = 10009;\n\n /// @notice thrown if a token is configured in an invalid order: 1. Set rate config for token 2. Set token config 3. allow any user.\n uint256 internal constant AdminModule__InvalidConfigOrder = 10010;\n\n /// @notice thrown if revenue is collected when revenue collector address is not set\n uint256 internal constant AdminModule__RevenueCollectorNotSet = 10011;\n\n /// @notice all ValueOverflow errors below are thrown if a certain input param overflows the allowed storage size\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_ZERO = 10012;\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_KINK = 10013;\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_MAX = 10014;\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_KINK1 = 10015;\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_KINK2 = 10016;\n uint256 internal constant AdminModule__ValueOverflow__RATE_AT_UTIL_MAX_V2 = 10017;\n uint256 internal constant AdminModule__ValueOverflow__FEE = 10018;\n uint256 internal constant AdminModule__ValueOverflow__THRESHOLD = 10019;\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_PERCENT = 10020;\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_DURATION = 10021;\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_PERCENT_BORROW = 10022;\n uint256 internal constant AdminModule__ValueOverflow__EXPAND_DURATION_BORROW = 10023;\n uint256 internal constant AdminModule__ValueOverflow__EXCHANGE_PRICES = 10024;\n uint256 internal constant AdminModule__ValueOverflow__UTILIZATION = 10025;\n\n /// @notice thrown when an address is not a contract\n uint256 internal constant AdminModule__AddressNotAContract = 10026;\n\n /***********************************|\n | User Module | \n |__________________________________*/\n\n /// @notice thrown when user operations are paused for an interacted token\n uint256 internal constant UserModule__UserNotDefined = 11001;\n\n /// @notice thrown when user operations are paused for an interacted token\n uint256 internal constant UserModule__UserPaused = 11002;\n\n /// @notice thrown when user's try to withdraw below withdrawal limit\n uint256 internal constant UserModule__WithdrawalLimitReached = 11003;\n\n /// @notice thrown when user's try to borrow above borrow limit\n uint256 internal constant UserModule__BorrowLimitReached = 11004;\n\n /// @notice thrown when u
},
"contracts/liquidity/interfaces/iLiquidity.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IProxy } from \"../../infiniteProxy/interfaces/iProxy.sol\";\nimport { Structs as AdminModuleStructs } from \"../adminModule/structs.sol\";\n\ninterface IFluidLiquidityAdmin {\n /// @notice adds/removes auths. Auths generally could be contracts which can have restricted actions defined on contract.\n /// auths can be helpful in reducing governance overhead where it's not needed.\n /// @param authsStatus_ array of structs setting allowed status for an address.\n /// status true => add auth, false => remove auth\n function updateAuths(AdminModuleStructs.AddressBool[] calldata authsStatus_) external;\n\n /// @notice adds/removes guardians. Only callable by Governance.\n /// @param guardiansStatus_ array of structs setting allowed status for an address.\n /// status true => add guardian, false => remove guardian\n function updateGuardians(AdminModuleStructs.AddressBool[] calldata guardiansStatus_) external;\n\n /// @notice changes the revenue collector address (contract that is sent revenue). Only callable by Governance.\n /// @param revenueCollector_ new revenue collector address\n function updateRevenueCollector(address revenueCollector_) external;\n\n /// @notice changes current status, e.g. for pausing or unpausing all user operations. Only callable by Auths.\n /// @param newStatus_ new status\n /// status = 2 -> pause, status = 1 -> resume.\n function changeStatus(uint256 newStatus_) external;\n\n /// @notice update tokens rate data version 1. Only callable by Auths.\n /// @param tokensRateData_ array of RateDataV1Params with rate data to set for each token\n function updateRateDataV1s(AdminModuleStructs.RateDataV1Params[] calldata tokensRateData_) external;\n\n /// @notice update tokens rate data version 2. Only callable by Auths.\n /// @param tokensRateData_ array of RateDataV2Params with rate data to set for each token\n function updateRateDataV2s(AdminModuleStructs.RateDataV2Params[] calldata tokensRateData_) external;\n\n /// @notice updates token configs: fee charge on borrowers interest & storage update utilization threshold.\n /// Only callable by Auths.\n /// @param tokenConfigs_ contains token address, fee & utilization threshold\n function updateTokenConfigs(AdminModuleStructs.TokenConfig[] calldata tokenConfigs_) external;\n\n /// @notice updates user classes: 0 is for new protocols, 1 is for established protocols.\n /// Only callable by Auths.\n /// @param userClasses_ struct array of uint256 value to assign for each user address\n function updateUserClasses(AdminModuleStructs.AddressUint256[] calldata userClasses_) external;\n\n /// @notice sets user supply configs per token basis. Eg: with interest or interest-free and automated limits.\n /// Only callable by Auths.\n /// @param userSupplyConfigs_ struct array containing user supply config, see `UserSupplyConfig` struct for more info\n function updateUserSupplyConfigs(AdminModuleStructs.UserSupplyConfig[] memory userSupplyConfigs_) external;\n\n /// @notice setting user borrow configs per token basis. Eg: with interest or interest-free and automated limits.\n /// Only callable by Auths.\n /// @param userBorrowConfigs_ struct array containing user borrow config, see `UserBorrowConfig` struct for more info\n function updateUserBorrowConfigs(AdminModuleStructs.UserBorrowConfig[] memory userBorrowConfigs_) external;\n\n /// @notice pause operations for a particular user in class 0 (class 1 users can't be paused by guardians).\n /// Only callable by Guardians.\n /// @param user_ address of user to pause operations for\n /// @param supplyTokens_ token addresses to pause withdrawals for\n /// @param borrowTokens_ token addresses to pause borrowings for\n function pauseUser(address user_, address[] calldata su
},
"contracts/liquidity/proxy.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Proxy } from \"../infiniteProxy/proxy.sol\";\n\n/// @notice Fluid Liquidity infinte proxy.\n/// Liquidity is the central point of the Instadapp Fluid architecture, it is the core interaction point\n/// for all allow-listed protocols, such as fTokens, Vault, Flashloan, StETH protocol, DEX protocol etc.\ncontract FluidLiquidityProxy is Proxy {\n constructor(address admin_, address dummyImplementation_) Proxy(admin_, dummyImplementation_) {}\n}\n"
},
"contracts/liquidity/userModule/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Events {\n /// @notice emitted on any `operate()` execution: deposit / supply / withdraw / borrow.\n /// includes info related to the executed operation, new total amounts (packed uint256 of BigMath numbers as in storage)\n /// and exchange prices (packed uint256 as in storage).\n /// @param user protocol that triggered this operation (e.g. via an fToken or via Vault protocol)\n /// @param token token address for which this operation was executed\n /// @param supplyAmount supply amount for the operation. if >0 then a deposit happened, if <0 then a withdrawal happened.\n /// if 0 then nothing.\n /// @param borrowAmount borrow amount for the operation. if >0 then a borrow happened, if <0 then a payback happened.\n /// if 0 then nothing.\n /// @param withdrawTo address that funds where withdrawn to (if supplyAmount <0)\n /// @param borrowTo address that funds where borrowed to (if borrowAmount >0)\n /// @param totalAmounts updated total amounts, stacked uint256 as written to storage:\n /// First 64 bits => 0- 63 => total supply with interest in raw (totalSupply = totalSupplyRaw * supplyExchangePrice); BigMath: 56 | 8\n /// Next 64 bits => 64-127 => total interest free supply in normal token amount (totalSupply = totalSupply); BigMath: 56 | 8\n /// Next 64 bits => 128-191 => total borrow with interest in raw (totalBorrow = totalBorrowRaw * borrowExchangePrice); BigMath: 56 | 8\n /// Next 64 bits => 192-255 => total interest free borrow in normal token amount (totalBorrow = totalBorrow); BigMath: 56 | 8\n /// @param exchangePricesAndConfig updated exchange prices and configs storage slot. Contains updated supply & borrow exchange price:\n /// First 16 bits => 0- 15 => borrow rate (in 1e2: 100% = 10_000; 1% = 100 -> max value 65535)\n /// Next 14 bits => 16- 29 => fee on interest from borrowers to lenders (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383). configurable.\n /// Next 14 bits => 30- 43 => last stored utilization (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\n /// Next 14 bits => 44- 57 => update on storage threshold (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383). configurable.\n /// Next 33 bits => 58- 90 => last update timestamp (enough until 16 March 2242 -> max value 8589934591)\n /// Next 64 bits => 91-154 => supply exchange price (1e12 -> max value 18_446_744,073709551615)\n /// Next 64 bits => 155-218 => borrow exchange price (1e12 -> max value 18_446_744,073709551615)\n /// Next 1 bit => 219-219 => if 0 then ratio is supplyInterestFree / supplyWithInterest else ratio is supplyWithInterest / supplyInterestFree\n /// Next 14 bits => 220-233 => supplyRatio: supplyInterestFree / supplyWithInterest (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\n /// Next 1 bit => 234-234 => if 0 then ratio is borrowInterestFree / borrowWithInterest else ratio is borrowWithInterest / borrowInterestFree\n /// Next 14 bits => 235-248 => borrowRatio: borrowInterestFree / borrowWithInterest (in 1e2: 100% = 10_000; 1% = 100 -> max value 16_383)\n event LogOperate(\n address indexed user,\n address indexed token,\n int256 supplyAmount,\n int256 borrowAmount,\n address withdrawTo,\n address borrowTo,\n uint256 totalAmounts,\n uint256 exchangePricesAndConfig\n );\n}\n"
},
"contracts/liquidity/userModule/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { FixedPointMathLib } from \"solmate/src/utils/FixedPointMathLib.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport { BigMathMinified } from \"../../libraries/bigMathMinified.sol\";\nimport { LiquidityCalcs } from \"../../libraries/liquidityCalcs.sol\";\nimport { LiquiditySlotsLink } from \"../../libraries/liquiditySlotsLink.sol\";\nimport { CommonHelpers } from \"../common/helpers.sol\";\nimport { Events } from \"./events.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\n\ninterface IProtocol {\n function liquidityCallback(address token_, uint256 amount_, bytes calldata data_) external;\n}\n\nabstract contract CoreInternals is Error, CommonHelpers, Events {\n using BigMathMinified for uint256;\n\n /// @dev supply or withdraw for both with interest & interest free.\n /// positive `amount_` is deposit, negative `amount_` is withdraw.\n function _supplyOrWithdraw(\n address token_,\n int256 amount_,\n uint256 supplyExchangePrice_\n ) internal returns (int256 newSupplyInterestRaw_, int256 newSupplyInterestFree_) {\n uint256 userSupplyData_ = _userSupplyData[msg.sender][token_];\n\n if (userSupplyData_ == 0) {\n revert FluidLiquidityError(ErrorTypes.UserModule__UserNotDefined);\n }\n if ((userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_IS_PAUSED) & 1 == 1) {\n revert FluidLiquidityError(ErrorTypes.UserModule__UserPaused);\n }\n\n // extract user supply amount\n uint256 userSupply_ = (userSupplyData_ >> LiquiditySlotsLink.BITS_USER_SUPPLY_AMOUNT) & X64;\n userSupply_ = (userSupply_ >> DEFAULT_EXPONENT_SIZE) << (userSupply_ & DEFAULT_EXPONENT_MASK);\n\n // calculate current, updated (expanded etc.) withdrawal limit\n uint256 newWithdrawalLimit_ = LiquidityCalcs.calcWithdrawalLimitBeforeOperate(userSupplyData_, userSupply_);\n\n // calculate updated user supply amount\n if (userSupplyData_ & 1 == 1) {\n // mode: with interest\n if (amount_ > 0) {\n // convert amount from normal to raw (divide by exchange price) -> round down for deposit\n newSupplyInterestRaw_ = (amount_ * int256(EXCHANGE_PRICES_PRECISION)) / int256(supplyExchangePrice_);\n userSupply_ = userSupply_ + uint256(newSupplyInterestRaw_);\n } else {\n // convert amount from normal to raw (divide by exchange price) -> round up for withdraw\n newSupplyInterestRaw_ = -int256(\n FixedPointMathLib.mulDivUp(uint256(-amount_), EXCHANGE_PRICES_PRECISION, supplyExchangePrice_)\n );\n // if withdrawal is more than user's supply then solidity will throw here\n userSupply_ = userSupply_ - uint256(-newSupplyInterestRaw_);\n }\n } else {\n // mode: without interest\n newSupplyInterestFree_ = amount_;\n if (newSupplyInterestFree_ > 0) {\n userSupply_ = userSupply_ + uint256(newSupplyInterestFree_);\n } else {\n // if withdrawal is more than user's supply then solidity will throw here\n userSupply_ = userSupply_ - uint256(-newSupplyInterestFree_);\n }\n }\n\n if (amount_ < 0 && userSupply_ < newWithdrawalLimit_) {\n // if withdraw, then check the user supply after withdrawal is above withdrawal limit\n revert FluidLiquidityError(ErrorTypes.UserModule__WithdrawalLimitReached);\n }\n\n // calculate withdrawal limit to store as previous withdrawal limit in storage\n newWithdrawalLimit_ = LiquidityCalcs.calcWithdrawalLimitAfterOperate(\n userSupplyDat
},
"contracts/mocks/emptyImplementation.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract EmptyImplementation {}\n"
},
"contracts/mocks/emptyImplementationUUPS.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\n\n/// @dev generic empty contract that can be set for UUPS proxies as initial logic contract, to avoid it affecting\n/// the deterministic contract address. upgrade is auth-gated via an immutable owner set in constructor, to\n/// not affect the storage layout.\ncontract EmptyImplementationUUPS is UUPSUpgradeable {\n /// @dev used to auth-gate upgrade triggering\n address public immutable OWNER;\n\n error Unauthorized();\n\n constructor(address owner_) {\n OWNER = owner_;\n }\n\n function _authorizeUpgrade(address) internal override {\n if (msg.sender != OWNER) {\n revert Unauthorized();\n }\n }\n}\n"
},
"contracts/mocks/mockERC721.sol": {
"content": "pragma solidity 0.8.21;\n\nimport { IERC721Enumerable } from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\ncontract MockonERC721Received {\n error ERC721Error();\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4) {\n if (data.length != 0) {\n address owner = abi.decode(data, (address));\n\n require(owner == operator, \"owner-not-same\");\n if (operator != from) revert ERC721Error();\n\n address child = address(new MockonERC721ReceivedChild());\n\n // Transfer to Child contract\n IERC721Enumerable(msg.sender).safeTransferFrom(address(this), child, tokenId, data);\n\n // Transfer to owner back.\n IERC721Enumerable(msg.sender).safeTransferFrom(address(this), operator, tokenId);\n }\n\n return MockonERC721Received(address(this)).onERC721Received.selector;\n }\n}\n\ncontract MockonERC721ReceivedChild {\n error ERC721Error();\n\n address immutable FACTORY;\n constructor () {\n FACTORY = msg.sender;\n }\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4) {\n (address toTransfer) = abi.decode(data, (address));\n\n if (operator != from) revert ERC721Error();\n\n IERC721Enumerable(msg.sender).safeTransferFrom(address(this), FACTORY, tokenId);\n\n return MockonERC721Received(address(this)).onERC721Received.selector;\n }\n}\n\n"
},
"contracts/mocks/mockFLA.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface InstaFlashInterface {\n function flashLoan(address[] memory tokens, uint256[] memory amts, uint route, bytes memory data, bytes memory extraData) external;\n}\n\ninterface InstaFlashReceiverInterface {\n function executeOperation(\n address[] calldata assets,\n uint256[] calldata amounts,\n uint256[] calldata premiums,\n address initiator,\n bytes calldata _data\n ) external returns (bool);\n}\n\ncontract MockFLA {\n using SafeERC20 for IERC20;\n \n function flashLoan(address[] memory tokens, uint256[] memory amts, uint route, bytes memory data, bytes memory extraData) external {\n uint256[] memory premiums = new uint256[](1);\n premiums[0] = 0;\n IERC20(tokens[0]).safeTransfer(msg.sender, amts[0]);\n InstaFlashReceiverInterface(msg.sender).executeOperation(\n tokens,\n amts,\n premiums,\n msg.sender,\n data\n );\n }\n}"
},
"contracts/mocks/mockOracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidOracle } from \"../oracle/fluidOracle.sol\";\n\n/// @notice Mock Oracle for testing\ncontract MockOracle is FluidOracle {\n uint256 public price;\n\n // Price is in 1e27 decimals between 2 tokens.\n // For example: if 1 ETH = 2000 USDC, that means 1e18 of ETH = 2000 * 1e6 of USDC\n // debt per col = 2000 * 1e6 * 1e27 / 1e18;\n\n // debt price w.r.t to col in 1e27\n /// @inheritdoc FluidOracle\n function getExchangeRate() external view override returns (uint256 exchangeRate_) {\n return price;\n }\n\n function setPrice(uint256 price_) external {\n price = price_;\n }\n}\n"
},
"contracts/mocks/mockProtocol.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport { FluidLiquidityUserModule } from \"../liquidity/userModule/main.sol\";\nimport { IFluidLiquidity } from \"../liquidity/interfaces/iLiquidity.sol\";\n\n/// @title Mock Protocol\n/// @notice Mock protocol for testing, implements:\n/// function liquidityCallback(address token_, uint256 amount_, bytes calldata data_) external;\n/// This callback method MUST transferFrom data_ decoded from address to the liquidity contract\ncontract MockProtocol {\n using SafeERC20 for IERC20;\n\n /// @dev address that is mapped to the chain native token\n address internal constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n address public immutable liquidityContract;\n\n /// @notice thrown when liquidity callback is called for a native token operation\n error MockProtocol__UnexpectedLiquidityCallback();\n\n bool transferInsufficientMode = false;\n bool transferExcessMode = false;\n bool reentrancyFromCallback = false;\n address transferFromAddress;\n\n /// @notice Construct a new MockProtocol\n /// @param liquidityContract_ The address of the liquidity contract\n constructor(address liquidityContract_) {\n liquidityContract = liquidityContract_;\n }\n\n receive() external payable {}\n\n function setTransferInsufficientMode(bool transferInsufficientMode_) public {\n transferInsufficientMode = transferInsufficientMode_;\n }\n\n function setTransferExcessMode(bool transferExcessMode_) public {\n transferExcessMode = transferExcessMode_;\n }\n\n function setReentrancyFromCallback(bool reentrancyFromCallback_) public {\n reentrancyFromCallback = reentrancyFromCallback_;\n }\n\n function setTransferFromAddress(address transferFromAddress_) public {\n transferFromAddress = transferFromAddress_;\n }\n\n /// @notice Mock liquidity callback\n /// @param token_ The token being transferred\n /// @param amount_ The amount being transferred\n function liquidityCallback(address token_, uint256 amount_, bytes memory data_) external {\n if (reentrancyFromCallback) {\n // call operate with some random values (should not matter as it reverts anyway)\n IFluidLiquidity(liquidityContract).operate(token_, 10, 0, address(0), address(0), abi.encode(address(this)));\n }\n\n if (token_ == NATIVE_TOKEN_ADDRESS) {\n revert MockProtocol__UnexpectedLiquidityCallback();\n }\n\n address from_;\n if (transferFromAddress == address(0)) {\n // take the last 20 bytes of data_ and decode them to address. Gives more flexibility in type of\n // data that can be passed in to Liquidity at mock calls while ensuring mock Protocol can do what it\n // is supposed to do: transfer amount of token to liquidity.\n assembly {\n from_ := mload(\n add(\n // add padding for length as present for dynamic arrays in memory\n add(data_, 32),\n // assembly expects address with leading zeros / left padded so need to use 32 as length here\n sub(mload(data_), 32)\n )\n )\n }\n } else {\n from_ = transferFromAddress;\n }\n\n if (amount_ > 0) {\n if (transferExcessMode) {\n amount_ += 1e6;\n } else if (transferInsufficientMode) {\n amount_ -= 1;\n }\n }\n\n if (from_ == address(this)) {\n // use approve and transferFrom for more consistent testing of methods called\n // (always transferFrom instead of transfer)\n IERC20(token_).safeApprove(address(th
},
"contracts/mocks/mockSwap.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\ncontract MockSwap {\n using SafeERC20 for IERC20;\n \n function swap(address buy_, address sell_, uint256 buyAmount_, uint256 sellAmount_) external payable {\n if (sell_ == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n // nothing\n } else {\n IERC20(sell_).safeTransferFrom(msg.sender, address(this), sellAmount_);\n }\n\n if (buy_ == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n Address.sendValue(payable(msg.sender), buyAmount_);\n } else {\n IERC20(buy_).safeTransfer(msg.sender, buyAmount_);\n }\n }\n}"
},
"contracts/mocks/mockWETH.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\n\ncontract MockWETH is ERC20 {\n constructor () ERC20(\"WETH\", \"WETH\") {}\n\n function deposit() external payable {\n _mint(msg.sender, msg.value);\n }\n\n function withdraw(uint256 amount) external {\n _burn(msg.sender, amount);\n Address.sendValue(payable(msg.sender), amount);\n }\n}"
},
"contracts/oracle/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Error {\n error FluidOracleError(uint256 errorId_);\n}\n"
},
"contracts/oracle/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | UniV3CheckCLRSOracle | \n |__________________________________*/\n\n /// @notice thrown when the delta between main price source and check rate source is exceeding the allowed delta\n uint256 internal constant UniV3CheckCLRSOracle__InvalidPrice = 60001;\n\n /// @notice thrown when an invalid parameter is passed to a method\n uint256 internal constant UniV3CheckCLRSOracle__InvalidParams = 60002;\n\n /// @notice thrown when the exchange rate is zero, even after all possible fallbacks depending on config\n uint256 internal constant UniV3CheckCLRSOracle__ExchangeRateZero = 60003;\n\n /***********************************|\n | Chainlink Oracle | \n |__________________________________*/\n\n /// @notice thrown when an invalid parameter is passed to a method\n uint256 internal constant ChainlinkOracle__InvalidParams = 61001;\n\n /***********************************|\n | UniswapV3 Oracle | \n |__________________________________*/\n\n /// @notice thrown when an invalid parameter is passed to a method\n uint256 internal constant UniV3Oracle__InvalidParams = 62001;\n\n /// @notice thrown when constructor is called with invalid ordered seconds agos values\n uint256 internal constant UniV3Oracle__InvalidSecondsAgos = 62002;\n\n /// @notice thrown when constructor is called with invalid delta values > 100%\n uint256 internal constant UniV3Oracle__InvalidDeltas = 62003;\n\n /***********************************|\n | WstETh Oracle | \n |__________________________________*/\n\n /// @notice thrown when an invalid parameter is passed to a method\n uint256 internal constant WstETHOracle__InvalidParams = 63001;\n\n /***********************************|\n | Redstone Oracle | \n |__________________________________*/\n\n /// @notice thrown when an invalid parameter is passed to a method\n uint256 internal constant RedstoneOracle__InvalidParams = 64001;\n\n /***********************************|\n | Fallback Oracle | \n |__________________________________*/\n\n /// @notice thrown when an invalid parameter is passed to a method\n uint256 internal constant FallbackOracle__InvalidParams = 65001;\n\n /***********************************|\n | FallbackCLRSOracle | \n |__________________________________*/\n\n /// @notice thrown when the exchange rate is zero, even for the fallback oracle source (if enabled)\n uint256 internal constant FallbackCLRSOracle__ExchangeRateZero = 66001;\n\n /***********************************|\n | WstETHCLRSOracle | \n |__________________________________*/\n\n /// @notice thrown when the exchange rate is zero, even for the fallback oracle source (if enabled)\n uint256 internal constant WstETHCLRSOracle__ExchangeRateZero = 67001;\n\n /***********************************|\n | CLFallbackUniV3Oracle | \n |__________________________________*/\n\n /// @notice thrown when the exchange rate is zero, even for the uniV3 rate\n uint256 internal constant CLFallbackUniV3Oracle__ExchangeRateZero = 68001;\n\n /***********************************|\n | WstETHCLRS2UniV3CheckCLRSOracle | \n |__________________________________*/\n\n /// @notice thrown when the exchange rate is zero, even for the uniV3 rate\n uint256 internal constant WstETHCLRS2UniV3CheckCLRSOracle__ExchangeRateZero = 69001;\n}\n"
},
"contracts/oracle/fluidOracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidOracle } from \"./interfaces/iFluidOracle.sol\";\n\n/// @title FluidOracle\n/// @notice Base contract that any Fluid Oracle must implement\nabstract contract FluidOracle is IFluidOracle {\n /// @inheritdoc IFluidOracle\n function getExchangeRate() external view virtual returns (uint256 exchangeRate_);\n}\n"
},
"contracts/oracle/implementations/chainlinkOracleImpl.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { IChainlinkAggregatorV3 } from \"../interfaces/external/IChainlinkAggregatorV3.sol\";\nimport { Error as OracleError } from \"../error.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\nimport { ChainlinkStructs } from \"./structs.sol\";\n\n/// @title Chainlink Oracle implementation\n/// @notice This contract is used to get the exchange rate via up to 3 hops at Chainlink price feeds.\n/// The rate is multiplied with the previous rate at each hop.\n/// E.g. to go from wBTC to USDC (assuming rates for example):\n/// 1. wBTC -> BTC https://data.chain.link/ethereum/mainnet/crypto-other/wbtc-btc, rate: 0.92.\n/// 2. BTC -> USD https://data.chain.link/ethereum/mainnet/crypto-usd/btc-usd rate: 30,000.\n/// 3. USD -> USDC https://data.chain.link/ethereum/mainnet/stablecoins/usdc-usd rate: 0.98. Must invert feed: 1.02\n/// finale rate would be: 0.92 * 30,000 * 1.02 = 28,152\nabstract contract ChainlinkOracleImpl is OracleError, ChainlinkStructs {\n /// @notice Chainlink price feed 1 to check for the exchange rate\n IChainlinkAggregatorV3 internal immutable _CHAINLINK_FEED1;\n /// @notice Chainlink price feed 2 to check for the exchange rate\n IChainlinkAggregatorV3 internal immutable _CHAINLINK_FEED2;\n /// @notice Chainlink price feed 3 to check for the exchange rate\n IChainlinkAggregatorV3 internal immutable _CHAINLINK_FEED3;\n\n /// @notice Flag to invert the price or not for feed 1 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _CHAINLINK_INVERT_RATE1;\n /// @notice Flag to invert the price or not for feed 2 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _CHAINLINK_INVERT_RATE2;\n /// @notice Flag to invert the price or not for feed 3 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _CHAINLINK_INVERT_RATE3;\n\n /// @notice constant value for price scaling to reduce gas usage for feed 1\n uint256 internal immutable _CHAINLINK_PRICE_SCALER_MULTIPLIER1;\n /// @notice constant value for inverting price to reduce gas usage for feed 1\n uint256 internal immutable _CHAINLINK_INVERT_PRICE_DIVIDEND1;\n\n /// @notice constant value for price scaling to reduce gas usage for feed 2\n uint256 internal immutable _CHAINLINK_PRICE_SCALER_MULTIPLIER2;\n /// @notice constant value for inverting price to reduce gas usage for feed 2\n uint256 internal immutable _CHAINLINK_INVERT_PRICE_DIVIDEND2;\n\n /// @notice constant value for price scaling to reduce gas usage for feed 3\n uint256 internal immutable _CHAINLINK_PRICE_SCALER_MULTIPLIER3;\n /// @notice constant value for inverting price to reduce gas usage for feed 3\n uint256 internal immutable _CHAINLINK_INVERT_PRICE_DIVIDEND3;\n\n /// @notice constructor sets the Chainlink price feed and invertRate flag for each hop.\n /// E.g. `invertRate_` should be true if for the USDC/ETH pool it's expected that the oracle returns USDC per 1 ETH\n constructor(ChainlinkConstructorParams memory params_) {\n if (\n (params_.hops < 1 || params_.hops > 3) || // hops must be 1, 2 or 3\n (address(params_.feed1.feed) == address(0) || params_.feed1.token0Decimals == 0) || // first feed must always be defined\n (params_.hops > 1 && (address(params_.feed2.feed) == address(0) || params_.feed2.token0Decimals == 0)) || // if hops > 1, feed 2 must be defined\n (params_.hops > 2 && (address(params_.feed3.feed) == address(0) || params_.feed3.token0Decimals == 0)) // if hops > 2, feed 3 must be defined\n ) {\n revert FluidOracleError(ErrorTypes.ChainlinkOracle__InvalidParams);\n }\n\n _CHAINLINK_FEED1 = params_.feed1.feed;\n _CHAINLINK_FEED2 = params_.feed2.feed;\n _CHAINLINK_FEED3 = params_.feed3.feed;\n\n _
},
"contracts/oracle/implementations/chainlinkOracleImpl2.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { IChainlinkAggregatorV3 } from \"../interfaces/external/IChainlinkAggregatorV3.sol\";\nimport { Error as OracleError } from \"../error.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\nimport { ChainlinkStructs } from \"./structs.sol\";\n\n// @dev Exact same contract as ChainlinkOracleImpl, just with all vars, immutables etc. renamed with a \"2\" to avoid\n// conflicts when ChainlinkOracleImpl would have to be inherited twice.\n\n/// @title Chainlink Oracle implementation.\n/// @notice This contract is used to get the exchange rate via up to 3 hops at Chainlink price feeds.\n/// The rate is multiplied with the previous rate at each hop.\n/// E.g. to go from wBTC to USDC (assuming rates for example):\n/// 1. wBTC -> BTC https://data.chain.link/ethereum/mainnet/crypto-other/wbtc-btc, rate: 0.92.\n/// 2. BTC -> USD https://data.chain.link/ethereum/mainnet/crypto-usd/btc-usd rate: 30,000.\n/// 3. USD -> USDC https://data.chain.link/ethereum/mainnet/stablecoins/usdc-usd rate: 0.98. Must invert feed: 1.02\n/// finale rate would be: 0.92 * 30,000 * 1.02 = 28,152\nabstract contract ChainlinkOracleImpl2 is OracleError, ChainlinkStructs {\n /// @notice Chainlink price feed 1 to check for the exchange rate\n IChainlinkAggregatorV3 internal immutable _CHAINLINK2_FEED1;\n /// @notice Chainlink price feed 2 to check for the exchange rate\n IChainlinkAggregatorV3 internal immutable _CHAINLINK2_FEED2;\n /// @notice Chainlink price feed 3 to check for the exchange rate\n IChainlinkAggregatorV3 internal immutable _CHAINLINK2_FEED3;\n\n /// @notice Flag to invert the price or not for feed 1 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _CHAINLINK2_INVERT_RATE1;\n /// @notice Flag to invert the price or not for feed 2 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _CHAINLINK2_INVERT_RATE2;\n /// @notice Flag to invert the price or not for feed 3 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _CHAINLINK2_INVERT_RATE3;\n\n /// @notice constant value for price scaling to reduce gas usage for feed 1\n uint256 internal immutable _CHAINLINK2_PRICE_SCALER_MULTIPLIER1;\n /// @notice constant value for inverting price to reduce gas usage for feed 1\n uint256 internal immutable _CHAINLINK2_INVERT_PRICE_DIVIDEND1;\n\n /// @notice constant value for price scaling to reduce gas usage for feed 2\n uint256 internal immutable _CHAINLINK2_PRICE_SCALER_MULTIPLIER2;\n /// @notice constant value for inverting price to reduce gas usage for feed 2\n uint256 internal immutable _CHAINLINK2_INVERT_PRICE_DIVIDEND2;\n\n /// @notice constant value for price scaling to reduce gas usage for feed 3\n uint256 internal immutable _CHAINLINK2_PRICE_SCALER_MULTIPLIER3;\n /// @notice constant value for inverting price to reduce gas usage for feed 3\n uint256 internal immutable _CHAINLINK2_INVERT_PRICE_DIVIDEND3;\n\n /// @notice constructor sets the Chainlink price feed and invertRate flag for each hop.\n /// E.g. `invertRate_` should be true if for the USDC/ETH pool it's expected that the oracle returns USDC per 1 ETH\n constructor(ChainlinkConstructorParams memory params_) {\n if (\n (params_.hops < 1 || params_.hops > 3) || // hops must be 1, 2 or 3\n (address(params_.feed1.feed) == address(0) || params_.feed1.token0Decimals == 0) || // first feed must always be defined\n (params_.hops > 1 && (address(params_.feed2.feed) == address(0) || params_.feed2.token0Decimals == 0)) || // if hops > 1, feed 2 must be defined\n (params_.hops > 2 && (address(params_.feed3.feed) == address(0) || params_.feed3.token0Decimals == 0)) // if hops > 2, feed 3 must be defined\n ) {\n revert FluidOr
},
"contracts/oracle/implementations/fallbackOracleImpl.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { IRedstoneOracle } from \"../interfaces/external/IRedstoneOracle.sol\";\nimport { Error as OracleError } from \"../error.sol\";\nimport { ChainlinkOracleImpl } from \"./chainlinkOracleImpl.sol\";\nimport { RedstoneOracleImpl } from \"./redstoneOracleImpl.sol\";\n\n/// @title Fallback Oracle implementation\n/// @notice This contract is used to get the exchange rate from a main oracle feed and a fallback oracle feed.\n//\n// @dev inheriting contracts should implement a view method to expose `_FALLBACK_ORACLE_MAIN_SOURCE`\nabstract contract FallbackOracleImpl is OracleError, RedstoneOracleImpl, ChainlinkOracleImpl {\n /// @dev which oracle to use as main source:\n /// - 1 = Chainlink ONLY (no fallback)\n /// - 2 = Chainlink with Redstone Fallback\n /// - 3 = Redstone with Chainlink Fallback\n uint8 internal immutable _FALLBACK_ORACLE_MAIN_SOURCE;\n\n /// @notice sets the main source, Chainlink Oracle and Redstone Oracle data.\n /// @param mainSource_ which oracle to use as main source:\n /// - 1 = Chainlink ONLY (no fallback)\n /// - 2 = Chainlink with Redstone Fallback\n /// - 3 = Redstone with Chainlink Fallback\n /// @param chainlinkParams_ chainlink Oracle constructor params struct.\n /// @param redstoneOracle_ Redstone Oracle data. (address can be set to zero address if using Chainlink only)\n constructor(\n uint8 mainSource_,\n ChainlinkConstructorParams memory chainlinkParams_,\n RedstoneOracleData memory redstoneOracle_\n )\n ChainlinkOracleImpl(chainlinkParams_)\n RedstoneOracleImpl(\n address(redstoneOracle_.oracle) == address(0)\n ? RedstoneOracleData(IRedstoneOracle(_REDSTONE_ORACLE_NOT_SET_ADDRESS), false, 1)\n : redstoneOracle_\n )\n {\n if (mainSource_ < 1 || mainSource_ > 3) {\n revert FluidOracleError(ErrorTypes.FallbackOracle__InvalidParams);\n }\n _FALLBACK_ORACLE_MAIN_SOURCE = mainSource_;\n }\n\n /// @dev returns the exchange rate for the main oracle source, or the fallback source (if configured) if the main exchange rate\n /// fails to be fetched. If returned rate is 0, fetching rate failed or something went wrong.\n /// @return exchangeRate_ exchange rate\n /// @return fallback_ whether fallback was necessary or not\n function _getRateWithFallback() internal view returns (uint256 exchangeRate_, bool fallback_) {\n if (_FALLBACK_ORACLE_MAIN_SOURCE == 1) {\n // 1 = Chainlink ONLY (no fallback)\n exchangeRate_ = _getChainlinkExchangeRate();\n } else if (_FALLBACK_ORACLE_MAIN_SOURCE == 2) {\n // 2 = Chainlink with Redstone Fallback\n exchangeRate_ = _getChainlinkExchangeRate();\n if (exchangeRate_ == 0) {\n fallback_ = true;\n exchangeRate_ = _getRedstoneExchangeRate();\n }\n } else {\n // 3 = Redstone with Chainlink Fallback\n exchangeRate_ = _getRedstoneExchangeRate();\n if (exchangeRate_ == 0) {\n fallback_ = true;\n exchangeRate_ = _getChainlinkExchangeRate();\n }\n }\n }\n\n /// @dev returns the exchange rate for Chainlink, or Redstone if configured & Chainlink fails.\n function _getChainlinkOrRedstoneAsFallback() internal view returns (uint256 exchangeRate_) {\n exchangeRate_ = _getChainlinkExchangeRate();\n\n if (exchangeRate_ == 0 && _FALLBACK_ORACLE_MAIN_SOURCE != 1) {\n // Chainlink failed but Redstone is configured too -> try Redstone\n exchangeRate_ = _getRedstoneExchangeRate();\n }\n }\n}\n"
},
"contracts/oracle/implementations/fallbackOracleImpl2.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { IRedstoneOracle } from \"../interfaces/external/IRedstoneOracle.sol\";\nimport { Error as OracleError } from \"../error.sol\";\nimport { ChainlinkOracleImpl2 } from \"./chainlinkOracleImpl2.sol\";\nimport { RedstoneOracleImpl2 } from \"./redstoneOracleImpl2.sol\";\n\n// @dev Exact same contract as FallbackOracleImpl, just with all vars, immutables etc. renamed with a \"2\" and inheriting\n// to ChainlinkOracleImpl2 and RedstoneOracleImpl2 to avoid conflicts when FallbackOracleImpl would have to be inherited twice.\n\n/// @title Fallback Oracle implementation\n/// @notice This contract is used to get the exchange rate from a main oracle feed and a fallback oracle feed.\n//\n// @dev inheriting contracts should implement a view method to expose `_FALLBACK_ORACLE2_MAIN_SOURCE`\nabstract contract FallbackOracleImpl2 is OracleError, RedstoneOracleImpl2, ChainlinkOracleImpl2 {\n /// @dev which oracle to use as main source:\n /// - 1 = Chainlink ONLY (no fallback)\n /// - 2 = Chainlink with Redstone Fallback\n /// - 3 = Redstone with Chainlink Fallback\n uint8 internal immutable _FALLBACK_ORACLE2_MAIN_SOURCE;\n\n /// @notice sets the main source, Chainlink Oracle and Redstone Oracle data.\n /// @param mainSource_ which oracle to use as main source:\n /// - 1 = Chainlink ONLY (no fallback)\n /// - 2 = Chainlink with Redstone Fallback\n /// - 3 = Redstone with Chainlink Fallback\n /// @param chainlinkParams_ chainlink Oracle constructor params struct.\n /// @param redstoneOracle_ Redstone Oracle data. (address can be set to zero address if using Chainlink only)\n constructor(\n uint8 mainSource_,\n ChainlinkConstructorParams memory chainlinkParams_,\n RedstoneOracleData memory redstoneOracle_\n )\n ChainlinkOracleImpl2(chainlinkParams_)\n RedstoneOracleImpl2(\n address(redstoneOracle_.oracle) == address(0)\n ? RedstoneOracleData(IRedstoneOracle(_REDSTONE2_ORACLE_NOT_SET_ADDRESS), false, 1)\n : redstoneOracle_\n )\n {\n if (mainSource_ < 1 || mainSource_ > 3) {\n revert FluidOracleError(ErrorTypes.FallbackOracle__InvalidParams);\n }\n _FALLBACK_ORACLE2_MAIN_SOURCE = mainSource_;\n }\n\n /// @dev returns the exchange rate for the main oracle source, or the fallback source (if configured) if the main exchange rate\n /// fails to be fetched. If returned rate is 0, fetching rate failed or something went wrong.\n /// @return exchangeRate_ exchange rate\n /// @return fallback_ whether fallback was necessary or not\n function _getRateWithFallback2() internal view returns (uint256 exchangeRate_, bool fallback_) {\n if (_FALLBACK_ORACLE2_MAIN_SOURCE == 1) {\n // 1 = Chainlink ONLY (no fallback)\n exchangeRate_ = _getChainlinkExchangeRate2();\n } else if (_FALLBACK_ORACLE2_MAIN_SOURCE == 2) {\n // 2 = Chainlink with Redstone Fallback\n exchangeRate_ = _getChainlinkExchangeRate2();\n if (exchangeRate_ == 0) {\n fallback_ = true;\n exchangeRate_ = _getRedstoneExchangeRate2();\n }\n } else {\n // 3 = Redstone with Chainlink Fallback\n exchangeRate_ = _getRedstoneExchangeRate2();\n if (exchangeRate_ == 0) {\n fallback_ = true;\n exchangeRate_ = _getChainlinkExchangeRate2();\n }\n }\n }\n\n /// @dev returns the exchange rate for Chainlink, or Redstone if configured & Chainlink fails.\n function _getChainlinkOrRedstoneAsFallback2() internal view returns (uint256 exchangeRate_) {\n exchangeRate_ = _getChainlinkExchangeRate2();\n\n if (exchangeRate_ == 0 && _FA
},
"contracts/oracle/implementations/redstoneOracleImpl.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { IRedstoneOracle } from \"../interfaces/external/IRedstoneOracle.sol\";\nimport { Error as OracleError } from \"../error.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\nimport { RedstoneStructs } from \"./structs.sol\";\n\n/// @title Redstone Oracle implementation\n/// @notice This contract is used to get the exchange rate from a Redstone Oracle\nabstract contract RedstoneOracleImpl is OracleError, RedstoneStructs {\n /// @notice Redstone price oracle to check for the exchange rate\n IRedstoneOracle internal immutable _REDSTONE_ORACLE;\n /// @notice Flag to invert the price or not (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _REDSTONE_INVERT_RATE;\n\n /// @notice constant value for price scaling to reduce gas usage\n uint256 internal immutable _REDSTONE_PRICE_SCALER_MULTIPLIER;\n /// @notice constant value for inverting price to reduce gas usage\n uint256 internal immutable _REDSTONE_INVERT_PRICE_DIVIDEND;\n\n address internal immutable _REDSTONE_ORACLE_NOT_SET_ADDRESS = 0x000000000000000000000000000000000000dEaD;\n\n /// @notice constructor sets the Redstone oracle data\n constructor(RedstoneOracleData memory oracleData_) {\n if (address(oracleData_.oracle) == address(0) || oracleData_.token0Decimals == 0) {\n revert FluidOracleError(ErrorTypes.RedstoneOracle__InvalidParams);\n }\n\n _REDSTONE_ORACLE = oracleData_.oracle;\n _REDSTONE_INVERT_RATE = oracleData_.invertRate;\n\n // for explanation on how to get to scaler multiplier and dividend see `chainlinkOracleImpl.sol`.\n // no support for token1Decimals with more than OracleUtils.RATE_OUTPUT_DECIMALS decimals for now as extremely unlikely case\n _REDSTONE_PRICE_SCALER_MULTIPLIER = address(oracleData_.oracle) == _REDSTONE_ORACLE_NOT_SET_ADDRESS\n ? 1\n : 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - oracleData_.token0Decimals);\n _REDSTONE_INVERT_PRICE_DIVIDEND = address(oracleData_.oracle) == _REDSTONE_ORACLE_NOT_SET_ADDRESS\n ? 1\n : 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + oracleData_.token0Decimals);\n }\n\n /// @dev Get the exchange rate from Redstone oracle\n /// @param rate_ The exchange rate in `_REDSTONE_OUTPUT_DECIMALS`\n function _getRedstoneExchangeRate() internal view returns (uint256 rate_) {\n try _REDSTONE_ORACLE.getExchangeRate() returns (uint256 exchangeRate_) {\n // Return the price in `_REDSTONE_OUTPUT_DECIMALS`\n if (_REDSTONE_INVERT_RATE) {\n // invert the price\n return _REDSTONE_INVERT_PRICE_DIVIDEND / exchangeRate_;\n } else {\n return exchangeRate_ * _REDSTONE_PRICE_SCALER_MULTIPLIER;\n }\n } catch {\n return 0;\n }\n }\n\n /// @notice returns all Redstone oracle related data as utility for easy off-chain use / block explorer in a single view method\n function redstoneOracleData()\n public\n view\n returns (uint256 redstoneExchangeRate_, IRedstoneOracle redstoneOracle_, bool redstoneInvertRate_)\n {\n return (\n address(_REDSTONE_ORACLE) == _REDSTONE_ORACLE_NOT_SET_ADDRESS ? 0 : _getRedstoneExchangeRate(),\n _REDSTONE_ORACLE,\n _REDSTONE_INVERT_RATE\n );\n }\n}\n"
},
"contracts/oracle/implementations/redstoneOracleImpl2.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { IRedstoneOracle } from \"../interfaces/external/IRedstoneOracle.sol\";\nimport { Error as OracleError } from \"../error.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\nimport { RedstoneStructs } from \"./structs.sol\";\n\n// @dev Exact same contract as RedstoneOracleImpl, just with all vars, immutables etc. renamed with a \"2\" to avoid\n// conflicts when RedstoneOracleImpl would have to be inherited twice.\n\n/// @title Redstone Oracle implementation\n/// @notice This contract is used to get the exchange rate from a Redstone Oracle\nabstract contract RedstoneOracleImpl2 is OracleError, RedstoneStructs {\n /// @notice Redstone price oracle to check for the exchange rate\n IRedstoneOracle internal immutable _REDSTONE2_ORACLE;\n /// @notice Flag to invert the price or not (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _REDSTONE2_INVERT_RATE;\n\n /// @notice constant value for price scaling to reduce gas usage\n uint256 internal immutable _REDSTONE2_PRICE_SCALER_MULTIPLIER;\n /// @notice constant value for inverting price to reduce gas usage\n uint256 internal immutable _REDSTONE2_INVERT_PRICE_DIVIDEND;\n\n address internal immutable _REDSTONE2_ORACLE_NOT_SET_ADDRESS = 0x000000000000000000000000000000000000dEaD;\n\n /// @notice constructor sets the Redstone oracle data\n constructor(RedstoneOracleData memory oracleData_) {\n if (address(oracleData_.oracle) == address(0) || oracleData_.token0Decimals == 0) {\n revert FluidOracleError(ErrorTypes.RedstoneOracle__InvalidParams);\n }\n\n _REDSTONE2_ORACLE = oracleData_.oracle;\n _REDSTONE2_INVERT_RATE = oracleData_.invertRate;\n\n // for explanation on how to get to scaler multiplier and dividend see `chainlinkOracleImpl.sol`.\n // no support for token1Decimals with more than OracleUtils.RATE_OUTPUT_DECIMALS decimals for now as extremely unlikely case\n _REDSTONE2_PRICE_SCALER_MULTIPLIER = address(oracleData_.oracle) == _REDSTONE2_ORACLE_NOT_SET_ADDRESS\n ? 1\n : 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - oracleData_.token0Decimals);\n _REDSTONE2_INVERT_PRICE_DIVIDEND = address(oracleData_.oracle) == _REDSTONE2_ORACLE_NOT_SET_ADDRESS\n ? 1\n : 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + oracleData_.token0Decimals);\n }\n\n /// @dev Get the exchange rate from Redstone oracle\n /// @param rate_ The exchange rate in `_REDSTONE2_OUTPUT_DECIMALS`\n function _getRedstoneExchangeRate2() internal view returns (uint256 rate_) {\n try _REDSTONE2_ORACLE.getExchangeRate() returns (uint256 exchangeRate_) {\n // Return the price in `_REDSTONE2_OUTPUT_DECIMALS`\n if (_REDSTONE2_INVERT_RATE) {\n // invert the price\n return _REDSTONE2_INVERT_PRICE_DIVIDEND / exchangeRate_;\n } else {\n return exchangeRate_ * _REDSTONE2_PRICE_SCALER_MULTIPLIER;\n }\n } catch {\n return 0;\n }\n }\n\n /// @notice returns all Redstone oracle related data as utility for easy off-chain use / block explorer in a single view method\n function redstoneOracleData2()\n public\n view\n returns (uint256 redstoneExchangeRate_, IRedstoneOracle redstoneOracle_, bool redstoneInvertRate_)\n {\n return (\n address(_REDSTONE2_ORACLE) == _REDSTONE2_ORACLE_NOT_SET_ADDRESS ? 0 : _getRedstoneExchangeRate2(),\n _REDSTONE2_ORACLE,\n _REDSTONE2_INVERT_RATE\n );\n }\n}\n"
},
"contracts/oracle/implementations/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IChainlinkAggregatorV3 } from \"../interfaces/external/IChainlinkAggregatorV3.sol\";\nimport { IRedstoneOracle } from \"../interfaces/external/IRedstoneOracle.sol\";\n\nabstract contract ChainlinkStructs {\n struct ChainlinkFeedData {\n /// @param feed address of Chainlink feed.\n IChainlinkAggregatorV3 feed;\n /// @param invertRate true if rate read from price feed must be inverted.\n bool invertRate;\n /// @param token0Decimals decimals of asset 0. E.g. for a USDC/ETH feed, USDC is token0 and has 6 decimals.\n /// (token1Decimals are available directly via Chainlink `FEED.decimals()`)\n uint256 token0Decimals;\n }\n\n struct ChainlinkConstructorParams {\n /// @param param hops count of hops, used for sanity checks. Must be 1, 2 or 3.\n uint8 hops;\n /// @param feed1 Chainlink feed 1 data. Required.\n ChainlinkFeedData feed1;\n /// @param feed2 Chainlink feed 2 data. Required if hops > 1.\n ChainlinkFeedData feed2;\n /// @param feed3 Chainlink feed 3 data. Required if hops > 2.\n ChainlinkFeedData feed3;\n }\n}\n\nabstract contract RedstoneStructs {\n struct RedstoneOracleData {\n /// @param oracle address of Redstone oracle.\n IRedstoneOracle oracle;\n /// @param invertRate true if rate read from price feed must be inverted.\n bool invertRate;\n /// @param token0Decimals decimals of asset 0. E.g. for a USDC/ETH feed, USDC is token0 and has 6 decimals.\n /// (token1Decimals are available directly via Redstone `Oracle.decimals()`)\n uint256 token0Decimals;\n }\n}\n"
},
"contracts/oracle/implementations/uniV3OracleImpl.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { FullMath } from \"../libraries/FullMath.sol\";\nimport { TickMath } from \"../libraries/TickMath.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\nimport { IUniswapV3Pool } from \"../interfaces/external/IUniswapV3Pool.sol\";\nimport { Error as OracleError } from \"../error.sol\";\n\n/// @title Uniswap V3 Oracle implementation\n/// @notice This contract is used to get the exchange rate from from a Uniswap V3 Pool,\n/// including logic to check against TWAP max deltas.\n/// @dev Uses 5 secondsAgos[] values and 3 TWAP maxDeltas:\n/// e.g. [240, 60, 15, 1, 0] -> [price240to60, price60to15, price 15to1, currentPrice]\n/// delta checks: price240to60 vs currentPrice, price60to15 vs currentPrice and 15to1 vs currentPrice.\nabstract contract UniV3OracleImpl is OracleError {\n /// @dev Uniswap V3 Pool to check for the exchange rate\n IUniswapV3Pool internal immutable _POOL;\n\n /// @dev Flag to invert the price or not (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\n bool internal immutable _UNIV3_INVERT_RATE;\n\n /// @dev Uniswap oracle delta for TWAP1 in 1e2 percent. If uniswap price TWAP1 is out of this delta,\n /// current price fetching reverts. E.g. for delta of TWAP 240 -> 60 vs current price\n uint256 internal immutable _UNI_TWAP1_MAX_DELTA_PERCENT;\n /// @dev Uniswap oracle delta for TWAP2 in 1e2 percent. If uniswap price TWAP2 is out of this delta,\n /// current price fetching reverts. E.g. for delta of TWAP 60 -> 15 vs current price\n uint256 internal immutable _UNI_TWAP2_MAX_DELTA_PERCENT;\n /// @dev Uniswap oracle delta for TWAP3 in 1e2 percent. If uniswap price TWAP3 is out of this delta,\n /// current price fetching reverts. E.g. for delta of TWAP 15 -> 1 vs current price\n uint256 internal immutable _UNI_TWAP3_MAX_DELTA_PERCENT;\n\n /// @dev Uniswap oracle seconds ago for twap, 1. value, e.g. 240\n uint256 internal immutable _UNI_SECONDS_AGO_1;\n /// @dev Uniswap oracle seconds ago for twap, 2. value, e.g. 60\n uint256 internal immutable _UNI_SECONDS_AGO_2;\n /// @dev Uniswap oracle seconds ago for twap, 3. value, e.g. 15\n uint256 internal immutable _UNI_SECONDS_AGO_3;\n /// @dev Uniswap oracle seconds ago for twap, 4. value, e.g. 1\n uint256 internal immutable _UNI_SECONDS_AGO_4;\n /// @dev Uniswap oracle seconds ago for twap, 5. value, e.g. 0\n uint256 internal immutable _UNI_SECONDS_AGO_5;\n\n /// @dev Uniswap TWAP1 interval duration.\n int256 internal immutable _UNI_TWAP1_INTERVAL;\n /// @dev Uniswap TWAP2 interval duration.\n int256 internal immutable _UNI_TWAP2_INTERVAL;\n /// @dev Uniswap TWAP3 interval duration.\n int256 internal immutable _UNI_TWAP3_INTERVAL;\n /// @dev Uniswap TWAP4 interval duration.\n int256 internal immutable _UNI_TWAP4_INTERVAL;\n\n /// @dev stored array lengths to optimize gas\n uint256 internal constant _SECONDS_AGOS_LENGTH = 5;\n uint256 internal constant _TWAP_DELTAS_LENGTH = 3;\n\n /// @dev constant value for price scaling to reduce gas usage\n uint256 internal immutable _UNIV3_PRICE_SCALER_MULTIPLIER;\n /// @dev constant value for inverting price to reduce gas usage\n uint256 internal immutable _UNIV3_INVERT_PRICE_DIVIDEND;\n\n struct UniV3ConstructorParams {\n /// @param pool Uniswap V3 Pool to check for the exchange rate\n IUniswapV3Pool pool;\n /// @param invertRate Flag to invert the Uniswap price or not\n bool invertRate;\n /// @param tWAPMaxDeltaPercents Uniswap oracle delta for TWAP1-2-3 in 1e2 percent\n uint256[_TWAP_DELTAS_LENGTH] tWAPMaxDeltaPercents;\n /// @param secondsAgos Uniswap oracle seconds ago for the 3 TWAP values, from oldest to newest, e.g. [240, 60, 15, 1, 0]\n uint32[_SECONDS_AGOS_LENGTH] secondsAgos;\n }\n\n /// @notice constructor
},
"contracts/oracle/implementations/wstETHOracleImpl.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IWstETH } from \"../interfaces/external/IWstETH.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error as OracleError } from \"../error.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\n\n/// @title wstETH Oracle Implementation\n/// @notice This contract is used to get the exchange rate between wstETH and stETH\nabstract contract WstETHOracleImpl is OracleError {\n /// @notice constant value for price scaling to reduce gas usage\n uint256 internal immutable _WSTETH_PRICE_SCALER_MULTIPLIER;\n\n /// @notice WSTETH contract, e.g. on mainnet 0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0\n IWstETH internal immutable _WSTETH;\n\n /// @notice constructor sets the wstETH `wstETH_` token address.\n constructor(IWstETH wstETH_) {\n if (address(wstETH_) == address(0)) {\n revert FluidOracleError(ErrorTypes.WstETHOracle__InvalidParams);\n }\n\n _WSTETH = wstETH_;\n\n _WSTETH_PRICE_SCALER_MULTIPLIER = 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - 18); // e.g. 1e9\n }\n\n /// @notice Get the exchange rate from wstETH contract\n /// @return rate_ The exchange rate in `WSTETH_OUTPUT_DECIMALS`\n function _getWstETHExchangeRate() internal view returns (uint256 rate_) {\n return _WSTETH.stEthPerToken() * _WSTETH_PRICE_SCALER_MULTIPLIER;\n }\n\n /// @notice returns all wWtETH oracle related data as utility for easy off-chain use / block explorer in a single view method\n function wstETHOracleData() public view returns (uint256 wstETHExchangeRate_, IWstETH wstETH_) {\n return (_getWstETHExchangeRate(), _WSTETH);\n }\n}\n"
},
"contracts/oracle/interfaces/external/IChainlinkAggregatorV3.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// from https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\n/// Copyright (c) 2018 SmartContract ChainLink, Ltd.\n\ninterface IChainlinkAggregatorV3 {\n /// @notice represents the number of decimals the aggregator responses represent.\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n"
},
"contracts/oracle/interfaces/external/IRedstoneOracle.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IRedstoneOracle {\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset\n // @dev custom Redstone adapter for Instadapp implementation\n function getExchangeRate() external view returns (uint256 exchangeRate_);\n\n /**\n * @notice Returns the number of decimals for the price feed\n * @dev By default, RedStone uses 8 decimals for data feeds\n * @return decimals The number of decimals in the price feed values\n */\n // see https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/on-chain-relayer/contracts/price-feeds/PriceFeedBase.sol#L51C12-L51C20\n function decimals() external view returns (uint8);\n}\n"
},
"contracts/oracle/interfaces/external/IUniswapV3Pool.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity 0.8.21;\n\n/// from https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces.\n/// Copyright (c) 2022 Uniswap Labs\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3PoolImmutables {\n /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface\n /// @return The contract address\n function factory() external view returns (address);\n\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n\n /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6\n /// @return The fee\n function fee() external view returns (uint24);\n\n /// @notice The pool tick spacing\n /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive\n /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ...\n /// This value is an int24 to avoid casting even though it is always positive.\n /// @return The tick spacing\n function tickSpacing() external view returns (int24);\n\n /// @notice The maximum amount of position liquidity that can use any tick in the range\n /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and\n /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool\n /// @return The max amount of liquidity per tick\n function maxLiquidityPerTick() external view returns (uint128);\n}\n\n/// @title Pool state that is not stored\n/// @notice Contains view functions to provide information about the pool that is computed rather than stored on the\n/// blockchain. The functions here may have variable gas costs.\ninterface IUniswapV3PoolDerivedState {\n /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\n /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\n /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\n /// you must call it with secondsAgos = [3600, 0].\n /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\n /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\n /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\n /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\n /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\n /// timestamp\n function observe(\n uint32[] calldata secondsAgos\n ) external view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\n\n /// @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range\n /// @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed.\n /// I.e., snapshots cannot be compared if a position is not held for the entire period between when the first\n /// snapshot is taken and the second snapshot is taken.\n /// @param tickLower The lower tick of the range\n /// @param tickUpper The upper tick of the range\n /// @return tickCumulativeInside The snapshot of the tick accumulator for the range\n //
},
"contracts/oracle/interfaces/external/IWstETH.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IWstETH {\n /**\n * @notice Get amount of stETH for 1 wstETH\n * @return Amount of stETH for 1 wstETH\n */\n function stEthPerToken() external view returns (uint256);\n\n /**\n * @notice Get amount of wstETH for 1 stETH\n * @return Amount of wstETH for 1 stETH\n */\n function tokensPerStEth() external view returns (uint256);\n}\n"
},
"contracts/oracle/interfaces/iFluidOracle.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IFluidOracle {\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27\n function getExchangeRate() external view returns (uint256 exchangeRate_);\n}\n"
},
"contracts/oracle/libraries/FullMath.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @dev Modified from the original UniswapV3 library to support v0.8\n/// From: uint256 twos = -denominator & denominator;\n/// To: uint256 twos = (type(uint256).max - denominator + 1) & denominator;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n /// @param a The multiplicand\n /// @param b The multiplier\n /// @param denominator The divisor\n /// @return result The 256-bit result\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n function mulDiv(uint256 a, uint256 b, uint256 denominator) internal pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = a * b\n // Compute the product mod 2**256 and mod 2**256 - 1\n // then use the Chinese Remainder Theorem to reconstruct\n // the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(a, b, not(0))\n prod0 := mul(a, b)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256.\n // Also prevents denominator == 0\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0]\n // Compute remainder using mulmod\n uint256 remainder;\n assembly {\n remainder := mulmod(a, b, denominator)\n }\n // Subtract 256 bit number from 512 bit number\n assembly {\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator\n // Compute largest power of two divisor of denominator.\n // Always >= 1.\n /// @dev This line was modified for v0.8.x\n // uint256 twos = -denominator & denominator;\n uint256 twos = (type(uint256).max - denominator + 1) & denominator;\n // Divide denominator by power of two\n assembly {\n denominator := div(denominator, twos)\n }\n\n // Divide [prod1 prod0] by the factors of two\n assembly {\n prod0 := div(prod0, twos)\n }\n // Shift in bits from prod1 into prod0. For this we need\n // to flip `twos` such that it is 2**256 / twos.\n // If twos is zero, then it becomes one\n assembly {\n twos := add(div(sub(0, twos), twos), 1)\n }\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2**256\n // Now that denominator is an odd number, it has an inverse\n // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n // Compute the inverse by starting with a seed that is correct\n // correct for four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inv = (3 * denominator) ^ 2;\n // Now use Newton-Raphson iteration to improve the precision.\n // Thanks to Hensel's lifting lemma, this also works in modular\n // arithmetic, doubling the correct
},
"contracts/oracle/libraries/oracleUtils.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\n/// @title Oracle utils library\n/// @notice implements common utility methods for Fluid Oracles\nlibrary OracleUtils {\n /// @dev The scaler for max delta point math (100%)\n uint256 internal constant HUNDRED_PERCENT_DELTA_SCALER = 10_000;\n /// @dev output precision of rates\n uint256 internal constant RATE_OUTPUT_DECIMALS = 27;\n\n /// @dev checks if `mainSourceRate_` is within a `maxDeltaPercent_` of `checkSourceRate_`. Returns true if so.\n function isRateOutsideDelta(\n uint256 mainSourceRate_,\n uint256 checkSourceRate_,\n uint256 maxDeltaPercent_\n ) internal pure returns (bool) {\n uint256 offset_ = (checkSourceRate_ * maxDeltaPercent_) / HUNDRED_PERCENT_DELTA_SCALER;\n return (mainSourceRate_ > (checkSourceRate_ + offset_) || mainSourceRate_ < (checkSourceRate_ - offset_));\n }\n}\n"
},
"contracts/oracle/libraries/TickMath.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity 0.8.21;\n\n/// @dev Modified from the original UniswapV3 library to support v0.8\n/// From: require(absTick <= uint256(MAX_TICK), 'T');\n/// To: require(absTick <= uint256(int(MAX_TICK)), 'T');\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n int24 internal constant MIN_TICK = -887272;\n /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n int24 internal constant MAX_TICK = -MIN_TICK;\n\n /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n /// @notice Calculates sqrt(1.0001^tick) * 2^96\n /// @dev Throws if |tick| > max tick\n /// @param tick The input tick for the above formula\n /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n /// at the given tick\n function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n /// @dev This line was modified for v0.8.x\n // require(absTick <= uint256(MAX_TICK), 'T');\n require(absTick <= uint256(int(MAX_TICK)), \"T\");\n\n uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;\n if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n if (tick > 0) ratio = type(uint256).max / ratio;\n\n // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n // we then downcast because we know the result always fits within 160 bits due to o
},
"contracts/oracle/oracles/cLFallbackUniV3Oracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidOracle } from \"../fluidOracle.sol\";\nimport { ChainlinkOracleImpl } from \"../implementations/chainlinkOracleImpl.sol\";\nimport { UniV3OracleImpl } from \"../implementations/uniV3OracleImpl.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\n\n/// @title Chainlink with Fallback to UniV3 Oracle\n/// @notice Gets the exchange rate between the underlying asset and the peg asset by using:\n/// the price from a Chainlink price feed or, if that feed fails, the price from a UniV3 TWAP delta checked Oracle.\ncontract CLFallbackUniV3Oracle is FluidOracle, ChainlinkOracleImpl, UniV3OracleImpl {\n /// @notice sets the Chainlink and UniV3 Oracle configs.\n /// @param chainlinkParams_ ChainlinkOracle constructor params struct.\n /// @param uniV3Params_ UniV3Oracle constructor params struct.\n constructor(\n ChainlinkConstructorParams memory chainlinkParams_,\n UniV3ConstructorParams memory uniV3Params_\n ) ChainlinkOracleImpl(chainlinkParams_) UniV3OracleImpl(uniV3Params_) {}\n\n /// @inheritdoc FluidOracle\n function getExchangeRate() external view override returns (uint256 exchangeRate_) {\n exchangeRate_ = _getChainlinkExchangeRate();\n if (exchangeRate_ == 0) {\n // if Chainlink fails, use UniV3 rate (TWAP checked)\n exchangeRate_ = _getUniV3ExchangeRate();\n\n if (exchangeRate_ == 0) {\n revert FluidOracleError(ErrorTypes.CLFallbackUniV3Oracle__ExchangeRateZero);\n }\n }\n }\n}\n"
},
"contracts/oracle/oracles/fallbackCLRSOracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidOracle } from \"../fluidOracle.sol\";\nimport { FallbackOracleImpl } from \"../implementations/fallbackOracleImpl.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\n\n/// @title Chainlink / Redstone Oracle (with fallback)\n/// @notice Gets the exchange rate between the underlying asset and the peg asset by using:\n/// the price from a Chainlink price feed or a Redstone Oracle with one of them being used as main source and\n/// the other one acting as a fallback if the main source fails for any reason. Reverts if fetched rate is 0.\ncontract FallbackCLRSOracle is FluidOracle, FallbackOracleImpl {\n /// @notice sets the main source, Chainlink Oracle and Redstone Oracle data.\n /// @param mainSource_ which oracle to use as main source: 1 = Chainlink, 2 = Redstone (other one is fallback).\n /// @param chainlinkParams_ chainlink Oracle constructor params struct.\n /// @param redstoneOracle_ Redstone Oracle data. (address can be set to zero address if using Chainlink only)\n constructor(\n uint8 mainSource_,\n ChainlinkConstructorParams memory chainlinkParams_,\n RedstoneOracleData memory redstoneOracle_\n ) FallbackOracleImpl(mainSource_, chainlinkParams_, redstoneOracle_) {}\n\n /// @inheritdoc FluidOracle\n function getExchangeRate() external view override returns (uint256 exchangeRate_) {\n (exchangeRate_, ) = _getRateWithFallback();\n\n if (exchangeRate_ == 0) {\n revert FluidOracleError(ErrorTypes.FallbackCLRSOracle__ExchangeRateZero);\n }\n }\n\n /// @notice which oracle to use as main source: 1 = Chainlink, 2 = Redstone (other one is fallback).\n function FALLBACK_ORACLE_MAIN_SOURCE() public view returns (uint8) {\n return _FALLBACK_ORACLE_MAIN_SOURCE;\n }\n}\n"
},
"contracts/oracle/oracles/uniV3CheckCLRSOracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidOracle } from \"../fluidOracle.sol\";\nimport { FallbackOracleImpl } from \"../implementations/fallbackOracleImpl.sol\";\nimport { UniV3OracleImpl } from \"../implementations/uniV3OracleImpl.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\n\n/// @title UniswapV3 checked against Chainlink / Redstone Oracle. Either one reported as exchange rate.\n/// @notice Gets the exchange rate between the underlying asset and the peg asset by using:\n/// the price from a UniV3 pool (compared against 3 TWAPs) and (optionally) comparing it against a Chainlink\n/// or Redstone price (one of Chainlink or Redstone being the main source and the other one the fallback source).\n/// Alternatively it can also use Chainlink / Redstone as main price and use UniV3 as check price.\n/// @dev The process for getting the aggregate oracle price is:\n/// 1. Fetch the UniV3 TWAPS, the latest interval is used as the current price\n/// 2. Verify this price is within an acceptable DELTA from the Uniswap TWAPS e.g.:\n/// a. 240 to 60s\n/// b. 60 to 15s\n/// c. 15 to 1s (last block)\n/// d. 1 to 0s (current)\n/// 3. (unless UniV3 only mode): Verify this price is within an acceptable DELTA from the Chainlink / Redstone Oracle\n/// 4. If it passes all checks, return the price. Otherwise use fallbacks, usually to Chainlink. In extreme edge-cases revert.\n/// @dev For UniV3 with check mode, if fetching the check price fails, the UniV3 rate is used directly.\ncontract UniV3CheckCLRSOracle is FluidOracle, UniV3OracleImpl, FallbackOracleImpl {\n /// @dev Rate check oracle delta percent in 1e2 percent. If current uniswap price is out of this delta,\n /// current price fetching reverts.\n uint256 internal immutable _RATE_CHECK_MAX_DELTA_PERCENT;\n\n /// @dev which oracle to use as final rate source:\n /// - 1 = UniV3 ONLY (no check),\n /// - 2 = UniV3 with Chainlink / Redstone check\n /// - 3 = Chainlink / Redstone with UniV3 used as check.\n uint8 internal immutable _RATE_SOURCE;\n\n struct UniV3CheckCLRSConstructorParams {\n /// @param uniV3Params UniV3Oracle constructor params struct.\n UniV3ConstructorParams uniV3Params;\n /// @param chainlinkParams ChainlinkOracle constructor params struct for UniV3CheckCLRSOracle.\n ChainlinkConstructorParams chainlinkParams;\n /// @param redstoneOracle Redstone Oracle data for UniV3CheckCLRSOracle. (address can be set to zero address if using Chainlink only)\n RedstoneOracleData redstoneOracle;\n /// @param rateSource which oracle to use as final rate source for UniV3CheckCLRSOracle:\n /// - 1 = UniV3 ONLY (no check),\n /// - 2 = UniV3 with Chainlink / Redstone check\n /// - 3 = Chainlink / Redstone with UniV3 used as check.\n uint8 rateSource;\n /// @param fallbackMainSource which oracle to use as CL/RS main source for UniV3CheckCLRSOracle: see FallbackOracleImpl constructor `mainSource_`\n uint8 fallbackMainSource;\n /// @param rateCheckMaxDeltaPercent Rate check oracle delta in 1e2 percent for UniV3CheckCLRSOracle\n uint256 rateCheckMaxDeltaPercent;\n }\n\n constructor(\n UniV3CheckCLRSConstructorParams memory params_\n )\n UniV3OracleImpl(params_.uniV3Params)\n FallbackOracleImpl(params_.fallbackMainSource, params_.chainlinkParams, params_.redstoneOracle)\n {\n if (\n params_.rateSource < 1 ||\n params_.rateSource > 3 ||\n params_.rateCheckMaxDeltaPercent > OracleUtils.HUNDRED_PERCENT_DELTA_SCALER ||\n // Chainlink only O
},
"contracts/oracle/oracles/wstETHCLRS2UniV3CheckCLRSOracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidOracle } from \"../fluidOracle.sol\";\nimport { UniV3CheckCLRSOracle } from \"./uniV3CheckCLRSOracle.sol\";\nimport { WstETHOracleImpl } from \"../implementations/wstETHOracleImpl.sol\";\nimport { FallbackOracleImpl2 } from \"../implementations/fallbackOracleImpl2.sol\";\nimport { IWstETH } from \"../interfaces/external/IWstETH.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\n\n// @dev uses FallbackOracleImpl2 to avoid conflicts with already used ChainlinkOracleImpl, RedstoneOracleImpl and\n// FallbackOracleImpl in UniV3CheckCLRSOracle.\n\n/// @title wstETHCLRSOracle combined with a uniV3CheckCLRSOracle.\n/// @notice Gets the exchange rate between the underlying asset and the peg asset by using:\n/// 1. wstETH Oracle price in combination with rate from Chainlink price feeds (or Redstone as fallback).\n/// combining those two into one rate resulting in wstETH <> someToken\n/// 2. result from 1. combined with a uniV3CheckCLRSOracle to get from someToken <> someToken2\n/// e.g. when going from wstETH to USDC:\n/// 1. wstETH -> stETH wstETH Oracle, stETH -> ETH Chainlink feed.\n/// 2, ETH -> USDC via UniV3 ETH <> USDC pool checked against ETH -> USDC Chainlink feed.\ncontract WstETHCLRS2UniV3CheckCLRSOracle is FluidOracle, WstETHOracleImpl, FallbackOracleImpl2, UniV3CheckCLRSOracle {\n struct WstETHCLRS2ConstructorParams {\n /// @param wstETH address of the wstETH contract\n IWstETH wstETH;\n /// @param fallbackMainSource which oracle to use as main source for wstETH <> CLRS: 1 = Chainlink, 2 = Redstone (other one is fallback).\n uint8 fallbackMainSource;\n /// @param chainlinkParams chainlink Oracle constructor params struct for wstETH <> CLRS.\n ChainlinkConstructorParams chainlinkParams;\n /// @param redstoneOracle Redstone Oracle data for wstETH <> CLRS. (address can be set to zero address if using Chainlink only)\n RedstoneOracleData redstoneOracle;\n }\n\n /// @notice constructs a WstETHCLRS2UniV3CheckCLRSOracle with all inherited contracts\n /// @param wstETHCLRS2Params_ WstETHCLRS2ConstructorParams for wstETH <> CLRS Token2 conversion\n /// @param uniV3CheckCLRSParams_ UniV3CheckCLRSOracle constructor params\n constructor(\n WstETHCLRS2ConstructorParams memory wstETHCLRS2Params_,\n UniV3CheckCLRSConstructorParams memory uniV3CheckCLRSParams_\n )\n WstETHOracleImpl(wstETHCLRS2Params_.wstETH)\n FallbackOracleImpl2(\n wstETHCLRS2Params_.fallbackMainSource,\n wstETHCLRS2Params_.chainlinkParams,\n wstETHCLRS2Params_.redstoneOracle\n )\n UniV3CheckCLRSOracle(uniV3CheckCLRSParams_)\n {}\n\n /// @inheritdoc FluidOracle\n function getExchangeRate() public view override(FluidOracle, UniV3CheckCLRSOracle) returns (uint256 exchangeRate_) {\n // 1. get CLRS Oracle rate for stETH <> CLRS feed. uses FallbackOracleImpl2\n (exchangeRate_, ) = _getRateWithFallback2();\n if (exchangeRate_ == 0) {\n // revert if fetched exchange rate is 0\n revert FluidOracleError(ErrorTypes.WstETHCLRS2UniV3CheckCLRSOracle__ExchangeRateZero);\n }\n\n // 2. combine CLRS feed price with wstETH price to have wstETH <> stETH <> SomeToken fully converted\n exchangeRate_ = (_getWstETHExchangeRate() * exchangeRate_) / (10 ** OracleUtils.RATE_OUTPUT_DECIMALS);\n\n // 3. get rate from UniV3Check Oracle (likely uniV3 / Chainlink checked against for delta). This always returns\n // a price if some rate is valid, with multiple fallbacks. Can not return 0. Combine this rate with existing.\n // (super.getExchangeRate() returns UniV3CheckCLRSOracle rate, no other inherited contract has this.)\n
},
"contracts/oracle/oracles/wstETHCLRSOracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidOracle } from \"../fluidOracle.sol\";\nimport { WstETHOracleImpl } from \"../implementations/wstETHOracleImpl.sol\";\nimport { FallbackOracleImpl } from \"../implementations/fallbackOracleImpl.sol\";\nimport { IWstETH } from \"../interfaces/external/IWstETH.sol\";\nimport { OracleUtils } from \"../libraries/oracleUtils.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\n\n/// @title WstETH Chainlink / Redstone Oracle (with fallback)\n/// @notice Gets the exchange rate between the underlying asset and the peg asset by using:\n/// wstETH Oracle price in combination with rate from Chainlink price feeds (or Redstone as fallback),\n/// hopping the 2 rates into 1 rate.\n/// e.g. when going from wstETH to USDT:\n/// wstETH -> stETH wstETH Oracle, stETH -> ETH Chainlink feed, ETH -> USDT Chainlink feed.\ncontract WstETHCLRSOracle is FluidOracle, WstETHOracleImpl, FallbackOracleImpl {\n /// @notice sets the wstETH address, main source, Chainlink Oracle and Redstone Oracle data.\n /// @param wstETH_ address of the wstETH contract\n /// @param mainSource_ which oracle to use as main source: 1 = Chainlink, 2 = Redstone (other one is fallback).\n /// @param chainlinkParams_ chainlink Oracle constructor params struct.\n /// @param redstoneOracle_ Redstone Oracle data. (address can be set to zero address if using Chainlink only)\n constructor(\n IWstETH wstETH_,\n uint8 mainSource_,\n ChainlinkConstructorParams memory chainlinkParams_,\n RedstoneOracleData memory redstoneOracle_\n ) WstETHOracleImpl(wstETH_) FallbackOracleImpl(mainSource_, chainlinkParams_, redstoneOracle_) {}\n\n /// @inheritdoc FluidOracle\n function getExchangeRate() external view override returns (uint256 exchangeRate_) {\n (exchangeRate_, ) = _getRateWithFallback();\n\n if (exchangeRate_ == 0) {\n // revert if fetched exchange rate is 0\n revert FluidOracleError(ErrorTypes.WstETHCLRSOracle__ExchangeRateZero);\n }\n\n return (_getWstETHExchangeRate() * exchangeRate_) / (10 ** OracleUtils.RATE_OUTPUT_DECIMALS);\n }\n\n /// @notice which oracle to use as main source: 1 = Chainlink, 2 = Redstone (other one is fallback).\n function FALLBACK_ORACLE_MAIN_SOURCE() public view returns (uint8) {\n return _FALLBACK_ORACLE_MAIN_SOURCE;\n }\n}\n"
},
"contracts/oracle/oracles/wstETHOracle.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidOracle } from \"../fluidOracle.sol\";\nimport { WstETHOracleImpl } from \"../implementations/wstETHOracleImpl.sol\";\nimport { IWstETH } from \"../interfaces/external/IWstETH.sol\";\n\n/// @title WstETHOracle\n/// @notice Gets the exchange rate between wstETH and stETH directly from the wstETH contract.\ncontract WstETHOracle is FluidOracle, WstETHOracleImpl {\n /// @notice constructor sets the wstETH `wstETH_` token address.\n constructor(IWstETH wstETH_) WstETHOracleImpl(wstETH_) {}\n\n /// @inheritdoc FluidOracle\n function getExchangeRate() external view override returns (uint256 exchangeRate_) {\n return _getWstETHExchangeRate();\n }\n}\n"
},
"contracts/periphery/liquidation/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Owned } from \"solmate/src/auth/Owned.sol\";\n\nimport { IFluidVaultT1 } from \"../../protocols/vault/interfaces/iVaultT1.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { IWETH9 } from \"../../protocols/lending/interfaces/external/iWETH9.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\ninterface InstaFlashInterface {\n function flashLoan(address[] memory tokens, uint256[] memory amts, uint route, bytes memory data, bytes memory extraData) external;\n}\n\ninterface InstaFlashReceiverInterface {\n function executeOperation(\n address[] calldata assets,\n uint256[] calldata amounts,\n uint256[] calldata premiums,\n address initiator,\n bytes calldata _data\n ) external returns (bool);\n}\n\ncontract VaultT1Liquidator is Owned {\n using SafeERC20 for IERC20;\n\n address constant public ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n InstaFlashInterface immutable public FLA;\n IWETH9 immutable public WETH;\n\n mapping (address => bool) public rebalancer; \n\n error FluidVaultT1Liquidator__InvalidOperation();\n\n event Liquidated(\n address indexed vault,\n uint256 collateral,\n uint256 debt\n );\n\n event Withdraw(\n address indexed to,\n address indexed token,\n uint256 amount\n );\n\n event ToggleRebalancer(\n address indexed rebalancer,\n bool indexed status\n );\n\n struct LiquidationParams {\n address vault;\n address supply;\n address borrow;\n uint256 borrowAmount;\n uint256 colPerUnitDebt;\n bool absorb;\n address swapRouter;\n address swapApproval;\n bytes swapData;\n uint256 route;\n }\n\n constructor (\n address owner_,\n address fla_,\n address weth_,\n address[] memory rebalancers_\n ) Owned(owner_) {\n FLA = InstaFlashInterface(fla_);\n WETH = IWETH9(weth_);\n for (uint256 i = 0; i < rebalancers_.length; i++) {\n rebalancer[rebalancers_[i]] = true;\n emit ToggleRebalancer(rebalancers_[i], true);\n }\n }\n\n modifier isRebalancer() {\n if (!rebalancer[msg.sender] && msg.sender != owner) {\n revert FluidVaultT1Liquidator__InvalidOperation();\n }\n _;\n }\n\n function toggleRebalancer(address rebalancer_, bool status_) public onlyOwner {\n rebalancer[rebalancer_] = status_;\n emit ToggleRebalancer(rebalancer_, status_);\n }\n\n function spell(address[] memory targets_, bytes[] memory calldatas_) public onlyOwner {\n for (uint256 i = 0; i < targets_.length; i++) {\n Address.functionDelegateCall(targets_[i], calldatas_[i]);\n }\n }\n\n function withdraw(address to_, address[] memory tokens_, uint256[] memory amounts_) public onlyOwner {\n for (uint i = 0; i < tokens_.length; i++) {\n if (tokens_[i] == ETH_ADDRESS) {\n Address.sendValue(payable(to_), amounts_[i]);\n } else {\n IERC20(tokens_[i]).safeTransfer(to_, amounts_[i]);\n }\n emit Withdraw(to_, tokens_[i], amounts_[i]);\n }\n }\n \n function liquidation(LiquidationParams memory params_) public isRebalancer {\n address[] memory tokens = new address[](1);\n uint256[] memory amts = new uint256[](1);\n\n // Take flashloan in borrow token of the vault\n tokens[0] = params_.borrow == ETH_ADDRESS ? address(WETH) : params_.borrow;\n amts[0] = params_.borrowAmount;\n\n bytes memory data_ = abi.encode(params_);\n\n FLA.flashLoan(tokens, amts, params_.route, data_, abi.encode());\n\n }\n\n function executeOperation(\n address[] calldata assets,\n uint256[] cal
},
"contracts/periphery/resolvers/lending/iLendingResolver.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\nimport { IAllowanceTransfer } from \"../../../protocols/lending/interfaces/permit2/iAllowanceTransfer.sol\";\nimport { IFluidLendingFactory } from \"../../../protocols/lending/interfaces/iLendingFactory.sol\";\nimport { IFluidLendingRewardsRateModel } from \"../../../protocols/lending/interfaces/iLendingRewardsRateModel.sol\";\nimport { IFToken } from \"../../../protocols/lending/interfaces/iFToken.sol\";\nimport { Structs } from \"./structs.sol\";\nimport { IFluidLiquidityResolver } from \"../../../periphery/resolvers/liquidity/iLiquidityResolver.sol\";\n\ninterface IFluidLendingResolver {\n /// @notice returns the lending factory address\n function LENDING_FACTORY() external view returns (IFluidLendingFactory);\n\n /// @notice returns the liquidity resolver address\n function LIQUIDITY_RESOLVER() external view returns (IFluidLiquidityResolver);\n\n /// @notice returns all fToken types at the `LENDING_FACTORY`\n function getAllFTokenTypes() external view returns (string[] memory);\n\n /// @notice returns all created fTokens at the `LENDING_FACTORY`\n function getAllFTokens() external view returns (address[] memory);\n\n /// @notice reads if a certain `auth_` address is an allowed auth or not. Owner is auth by default.\n function isLendingFactoryAuth(address auth_) external view returns (bool);\n\n /// @notice reads if a certain `deployer_` address is an allowed deployer or not. Owner is deployer by default.\n function isLendingFactoryDeployer(address deployer_) external view returns (bool);\n\n /// @notice computes deterministic token address for `asset_` for a lending protocol\n /// @param asset_ address of the asset\n /// @param fTokenType_ type of fToken:\n /// - if underlying asset supports EIP-2612, the fToken should be type `EIP2612Deposits`\n /// - otherwise it should use `Permit2Deposits`\n /// - if it's the native token, it should use `NativeUnderlying`\n /// - could be more types available, check `fTokenTypes()`\n /// @return token_ detemrinistic address of the computed token\n function computeFToken(address asset_, string calldata fTokenType_) external view returns (address);\n\n /// @notice gets all public details for a certain `fToken_`, such as\n /// fToken type, name, symbol, decimals, underlying asset, total amounts, convertTo values, rewards.\n /// Note it also returns whether the fToken supports deposits / mints via EIP-2612, but it is not a 100% guarantee!\n /// To make sure, check for the underlying if it supports EIP-2612 manually.\n /// @param fToken_ the fToken to get the details for\n /// @return fTokenDetails_ retrieved FTokenDetails struct\n function getFTokenDetails(IFToken fToken_) external view returns (Structs.FTokenDetails memory fTokenDetails_);\n\n /// @notice returns config, rewards and exchange prices data of an fToken.\n /// @param fToken_ the fToken to get the data for\n /// @return liquidity_ address of the Liquidity contract.\n /// @return lendingFactory_ address of the Lending factory contract.\n /// @return lendingRewardsRateModel_ address of the rewards rate model contract. changeable by LendingFactory auths.\n /// @return permit2_ address of the Permit2 contract used for deposits / mint with signature\n /// @return rebalancer_ address of the rebalancer allowed to execute `rebalance()`\n /// @return rewardsActive_ true if rewards are currently active\n /// @return liquidityBalance_ current Liquidity supply balance of `address(this)` for the underyling asset\n /// @return liquidityExchangePrice_ (updated) exchange price for the underlying assset in the liquidity protocol (without rewards)\n /// @return tokenExchangePrice_ (updated) exchange price between fToken and the underlying assset (with rewards)\n function getFTokenInternalData(\n IFToken fToken_\n )\n ex
},
"contracts/periphery/resolvers/lending/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20Permit } from \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport { LiquidityCalcs } from \"../../../libraries/liquidityCalcs.sol\";\nimport { IFluidLendingFactory } from \"../../../protocols/lending/interfaces/iLendingFactory.sol\";\nimport { IFluidLendingRewardsRateModel } from \"../../../protocols/lending/interfaces/iLendingRewardsRateModel.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\nimport { IAllowanceTransfer } from \"../../../protocols/lending/interfaces/permit2/iAllowanceTransfer.sol\";\nimport { IFToken, IFTokenNativeUnderlying } from \"../../../protocols/lending/interfaces/iFToken.sol\";\nimport { IFluidLiquidityResolver } from \"../../../periphery/resolvers/liquidity/iLiquidityResolver.sol\";\nimport { Structs as LiquidityStructs } from \"../../../periphery/resolvers/liquidity/structs.sol\";\nimport { IFluidLendingResolver } from \"./iLendingResolver.sol\";\nimport { Structs } from \"./structs.sol\";\n\n/// @notice Fluid Lending protocol (fTokens) resolver\n/// Implements various view-only methods to give easy access to Lending protocol data.\ncontract FluidLendingResolver is IFluidLendingResolver, Structs {\n /// @dev address that is mapped to the chain native token\n address internal constant _NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /// @inheritdoc IFluidLendingResolver\n IFluidLendingFactory public immutable LENDING_FACTORY;\n\n /// @inheritdoc IFluidLendingResolver\n IFluidLiquidityResolver public immutable LIQUIDITY_RESOLVER;\n\n /// @notice thrown if an input param address is zero\n error FluidLendingResolver__AddressZero();\n\n /// @notice constructor sets the immutable `LENDING_FACTORY` address\n constructor(IFluidLendingFactory lendingFactory_, IFluidLiquidityResolver liquidityResolver_) {\n if (address(lendingFactory_) == address(0) || address(liquidityResolver_) == address(0)) {\n revert FluidLendingResolver__AddressZero();\n }\n LENDING_FACTORY = lendingFactory_;\n LIQUIDITY_RESOLVER = liquidityResolver_;\n }\n\n /// @inheritdoc IFluidLendingResolver\n function isLendingFactoryAuth(address auth_) external view returns (bool) {\n return LENDING_FACTORY.isAuth(auth_);\n }\n\n /// @inheritdoc IFluidLendingResolver\n function isLendingFactoryDeployer(address deployer_) external view returns (bool) {\n return LENDING_FACTORY.isDeployer(deployer_);\n }\n\n /// @inheritdoc IFluidLendingResolver\n function getAllFTokenTypes() public view returns (string[] memory) {\n return LENDING_FACTORY.fTokenTypes();\n }\n\n /// @inheritdoc IFluidLendingResolver\n function getAllFTokens() public view returns (address[] memory) {\n return LENDING_FACTORY.allTokens();\n }\n\n /// @inheritdoc IFluidLendingResolver\n function computeFToken(address asset_, string calldata fTokenType_) external view returns (address) {\n return LENDING_FACTORY.computeToken(asset_, fTokenType_);\n }\n\n /// @inheritdoc IFluidLendingResolver\n function getFTokenDetails(IFToken fToken_) public view returns (FTokenDetails memory fTokenDetails_) {\n address underlying_ = fToken_.asset();\n\n bool isNativeUnderlying_ = false;\n try IFTokenNativeUnderlying(address(fToken_)).NATIVE_TOKEN_ADDRESS() {\n // if NATIVE_TOKEN_ADDRESS is defined, fTokenType must be NativeUnderlying.\n isNativeUnderlying_ = true;\n } catch {}\n\n bool supportsEIP2612Deposits_ = false;\n try IERC20Permit(underlying_).DOMAIN_SEPARATOR() {\n // if DOMAIN_SEPARATOR is defined, we assume underlying supports EIP2612. Not a 100% guarantee\n supportsEIP2612Deposits_ = true;\n } catch {}\n\n (, uint256 rewardsRate_) = getFTokenRewards(fToken_);\n
},
"contracts/periphery/resolvers/lending/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLendingFactory } from \"../../../protocols/lending/interfaces/iLendingFactory.sol\";\nimport { Structs as FluidLiquidityResolverStructs } from \"../liquidity/structs.sol\";\n\nabstract contract Structs {\n struct FTokenDetails {\n address tokenAddress;\n bool eip2612Deposits;\n bool isNativeUnderlying;\n string name;\n string symbol;\n uint256 decimals;\n address asset;\n uint256 totalAssets;\n uint256 totalSupply;\n uint256 convertToShares;\n uint256 convertToAssets;\n // additional yield from rewards, if active\n uint256 rewardsRate;\n // yield at Liquidity\n uint256 supplyRate;\n // difference between fToken assets & actual deposit at Liquidity. (supplyAtLiquidity - totalAssets).\n // if negative, rewards must be funded to guarantee withdrawal is possible for all users. This happens\n // by executing rebalance().\n int256 rebalanceDifference;\n // liquidity related data such as supply amount, limits, expansion etc.\n FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyData;\n }\n\n struct UserPosition {\n uint256 fTokenShares;\n uint256 underlyingAssets;\n uint256 underlyingBalance;\n uint256 allowance;\n }\n\n struct FTokenDetailsUserPosition {\n FTokenDetails fTokenDetails;\n UserPosition userPosition;\n }\n}\n"
},
"contracts/periphery/resolvers/liquidity/iLiquidityResolver.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { Structs as LiquidityStructs } from \"../../../periphery/resolvers/liquidity/structs.sol\";\n\ninterface IFluidLiquidityResolver {\n /// @notice gets the `revenueAmount_` for a `token_`.\n function getRevenue(address token_) external view returns (uint256 revenueAmount_);\n\n /// @notice address of contract that gets sent the revenue. Configurable by governance\n function getRevenueCollector() external view returns (address);\n\n /// @notice Liquidity contract paused status: status = 1 -> normal. status = 2 -> paused.\n function getStatus() external view returns (uint256);\n\n /// @notice checks if `auth_` is an allowed auth on Liquidity.\n /// Auths can set most config values. E.g. contracts that automate certain flows like e.g. adding a new fToken.\n /// Governance can add/remove auths. Governance is auth by default.\n function isAuth(address auth_) external view returns (uint256);\n\n /// @notice checks if `guardian_` is an allowed Guardian on Liquidity.\n /// Guardians can pause lower class users.\n /// Governance can add/remove guardians. Governance is guardian by default.\n function isGuardian(address guardian_) external view returns (uint256);\n\n /// @notice gets user class for `user_`. Class defines which protocols can be paused by guardians.\n /// Currently there are 2 classes: 0 can be paused by guardians. 1 cannot be paused by guardians.\n /// New protocols are added as class 0 and will be upgraded to 1 over time.\n function getUserClass(address user_) external view returns (uint256);\n\n /// @notice gets exchangePricesAndConfig packed uint256 storage slot for `token_`.\n function getExchangePricesAndConfig(address token_) external view returns (uint256);\n\n /// @notice gets rateConfig packed uint256 storage slot for `token_`.\n function getRateConfig(address token_) external view returns (uint256);\n\n /// @notice gets totalAmounts packed uint256 storage slot for `token_`.\n function getTotalAmounts(address token_) external view returns (uint256);\n\n /// @notice gets userSupply data packed uint256 storage slot for `user_` and `token_`.\n function getUserSupply(address user_, address token_) external view returns (uint256);\n\n /// @notice gets userBorrow data packed uint256 storage slot for `user_` and `token_`.\n function getUserBorrow(address user_, address token_) external view returns (uint256);\n\n /// @notice returns all `listedTokens_` at the Liquidity contract. Once configured, a token can never be removed.\n function listedTokens() external view returns (address[] memory listedTokens_);\n\n /// @notice get the Rate config data `rateData_` for a `token_` compiled from the packed uint256 rateConfig storage slot\n function getTokenRateData(address token_) external view returns (LiquidityStructs.RateData memory rateData_);\n\n /// @notice get the Rate config datas `rateDatas_` for multiple `tokens_` compiled from the packed uint256 rateConfig storage slot\n function getTokensRateData(\n address[] calldata tokens_\n ) external view returns (LiquidityStructs.RateData[] memory rateDatas_);\n\n /// @notice returns general data for `token_` such as rates, exchange prices, utilization, fee, total amounts etc.\n function getOverallTokenData(\n address token_\n ) external view returns (LiquidityStructs.OverallTokenData memory overallTokenData_);\n\n /// @notice returns general data for multiple `tokens_` such as rates, exchange prices, utilization, fee, total amounts etc.\n function getOverallTokensData(\n address[] calldata tokens_\n ) external view returns (LiquidityStructs.OverallTokenData[] memory overallTokensData_);\n\n /// @notice returns `user_` supply data and general data (such as rates, exchange prices, utilization, fee, total amounts etc.) for `token_`\n function getUserSupplyData(\n address user_,\n address token_\n )\n external\n vie
},
"contracts/periphery/resolvers/liquidity/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport { LiquidityCalcs } from \"../../../libraries/liquidityCalcs.sol\";\nimport { BigMathMinified } from \"../../../libraries/bigMathMinified.sol\";\nimport { LiquiditySlotsLink } from \"../../../libraries/liquiditySlotsLink.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\nimport { IFluidLiquidityResolver } from \"./iLiquidityResolver.sol\";\nimport { Structs } from \"./structs.sol\";\nimport { Variables } from \"./variables.sol\";\n\ninterface TokenInterface {\n function balanceOf(address) external view returns (uint);\n}\n\n/// @notice Fluid Liquidity resolver\n/// Implements various view-only methods to give easy access to Liquidity data.\ncontract FluidLiquidityResolver is IFluidLiquidityResolver, Variables, Structs {\n /// @dev address that is mapped to the chain native token\n address internal constant _NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /// @notice thrown if an input param address is zero\n error FluidLiquidityResolver__AddressZero();\n\n constructor(IFluidLiquidity liquidity_) Variables(liquidity_) {\n if (address(liquidity_) == address(0)) {\n revert FluidLiquidityResolver__AddressZero();\n }\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function getRevenueCollector() public view returns (address) {\n return address(uint160(LIQUIDITY.readFromStorage(bytes32(0))));\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function getRevenue(address token_) public view returns (uint256 revenueAmount_) {\n uint256 liquidityTokenBalance_ = token_ == _NATIVE_TOKEN_ADDRESS\n ? address(LIQUIDITY).balance\n : IERC20(token_).balanceOf(address(LIQUIDITY));\n\n return\n LiquidityCalcs.calcRevenue(\n getTotalAmounts(token_),\n getExchangePricesAndConfig(token_),\n liquidityTokenBalance_\n );\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function getStatus() public view returns (uint256) {\n return LIQUIDITY.readFromStorage(bytes32(LiquiditySlotsLink.LIQUIDITY_STATUS_SLOT));\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function isAuth(address auth_) public view returns (uint256) {\n return\n LIQUIDITY.readFromStorage(\n LiquiditySlotsLink.calculateMappingStorageSlot(LiquiditySlotsLink.LIQUIDITY_AUTHS_MAPPING_SLOT, auth_)\n );\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function isGuardian(address guardian_) public view returns (uint256) {\n return\n LIQUIDITY.readFromStorage(\n LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_GUARDIANS_MAPPING_SLOT,\n guardian_\n )\n );\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function getUserClass(address user_) public view returns (uint256) {\n return\n LIQUIDITY.readFromStorage(\n LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_USER_CLASS_MAPPING_SLOT,\n user_\n )\n );\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function getExchangePricesAndConfig(address token_) public view returns (uint256) {\n return\n LIQUIDITY.readFromStorage(\n LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n token_\n )\n );\n }\n\n /// @inheritdoc IFluidLiquidityResolver\n function getRateConfig(address token_) public view returns (uint256) {\n return\n LIQUIDITY.readFromStorage(\n LiquiditySlotsLink.calculateMappingStorageSlot(\n
},
"contracts/periphery/resolvers/liquidity/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Structs as AdminModuleStructs } from \"../../../liquidity/adminModule/structs.sol\";\n\nabstract contract Structs {\n struct RateData {\n uint256 version;\n AdminModuleStructs.RateDataV1Params rateDataV1;\n AdminModuleStructs.RateDataV2Params rateDataV2;\n }\n\n struct OverallTokenData {\n uint256 borrowRate;\n uint256 supplyRate;\n uint256 fee; // revenue fee\n uint256 lastStoredUtilization;\n uint256 storageUpdateThreshold;\n uint256 lastUpdateTimestamp;\n uint256 supplyExchangePrice;\n uint256 borrowExchangePrice;\n uint256 supplyRawInterest;\n uint256 supplyInterestFree;\n uint256 borrowRawInterest;\n uint256 borrowInterestFree;\n uint256 totalSupply;\n uint256 totalBorrow;\n uint256 revenue;\n RateData rateData;\n }\n\n // amounts are always in normal (for withInterest already multiplied with exchange price)\n struct UserSupplyData {\n bool modeWithInterest; // true if mode = with interest, false = without interest\n uint256 supply; // user supply amount\n // the withdrawal limit (e.g. if 10% is the limit, and 100M is supplied, it would be 90M)\n uint256 withdrawalLimit;\n uint256 lastUpdateTimestamp;\n uint256 expandPercent; // withdrawal limit expand percent in 1e2\n uint256 expandDuration; // withdrawal limit expand duration in seconds\n uint256 baseWithdrawalLimit;\n // the current actual max withdrawable amount (e.g. if 10% is the limit, and 100M is supplied, it would be 10M)\n uint256 withdrawableUntilLimit;\n uint256 withdrawable; // actual currently withdrawable amount (supply - withdrawal Limit) & considering balance\n }\n\n // amounts are always in normal (for withInterest already multiplied with exchange price)\n struct UserBorrowData {\n bool modeWithInterest; // true if mode = with interest, false = without interest\n uint256 borrow; // user borrow amount\n uint256 borrowLimit;\n uint256 lastUpdateTimestamp;\n uint256 expandPercent;\n uint256 expandDuration;\n uint256 baseBorrowLimit;\n uint256 maxBorrowLimit;\n uint256 borrowableUntilLimit;\n uint256 borrowable; // actual currently borrowable amount (borrow limit - already borrowed) & considering balance\n }\n}\n"
},
"contracts/periphery/resolvers/liquidity/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\n\ncontract Variables {\n /// @dev Storage slot with the admin of the contract. Logic from \"proxy.sol\".\n /// This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n /// validated in the constructor.\n bytes32 internal constant GOVERNANCE_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n\n /// @dev Ignoring leap years\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\n // constants used for BigMath conversion from and to storage\n uint256 internal constant SMALL_COEFFICIENT_SIZE = 10;\n uint256 internal constant DEFAULT_COEFFICIENT_SIZE = 56;\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xFF;\n\n uint256 internal constant FOUR_DECIMALS = 10000;\n uint256 internal constant X8 = 0xff;\n uint256 internal constant X14 = 0x3fff;\n uint256 internal constant X16 = 0xffff;\n uint256 internal constant X18 = 0x3ffff;\n uint256 internal constant X24 = 0xffffff;\n uint256 internal constant X33 = 0x1ffffffff;\n uint256 internal constant X64 = 0xffffffffffffffff;\n\n /// @notice address of the liquidity contract\n IFluidLiquidity public immutable LIQUIDITY;\n\n constructor(IFluidLiquidity liquidity_) {\n LIQUIDITY = IFluidLiquidity(liquidity_);\n }\n}\n"
},
"contracts/periphery/resolvers/stakingRewards/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20Permit } from \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport { IFluidLendingResolver } from \"../lending/iLendingResolver.sol\";\nimport { Structs as FluidLendingResolverStructs } from \"../lending/structs.sol\";\nimport { IFluidLendingStakingRewards } from \"../../../protocols/lending/interfaces/iStakingRewards.sol\";\nimport { Structs } from \"./structs.sol\";\n\n\n/// @notice Fluid Lending protocol Staking Rewards (for fTokens) resolver\n/// Implements various view-only methods to give easy access to Lending protocol staked fToken rewards data.\ncontract FluidStakingRewardsResolver is Structs {\n IFluidLendingResolver immutable public LENDING_RESOLVER;\n\n /// @notice thrown if an input param address is zero\n error FluidStakingRewardsResolver__AddressZero();\n\n constructor(address lendingResolver_) {\n if(lendingResolver_ == address(0)){\n revert FluidStakingRewardsResolver__AddressZero();\n }\n LENDING_RESOLVER = IFluidLendingResolver(lendingResolver_);\n }\n\n function getFTokenStakingRewardsEntireData(address reward_) public view returns (FTokenStakingRewardsDetails memory r_) {\n // if address is 0 then data will be returned as 0\n if (reward_ != address(0)) {\n IFluidLendingStakingRewards rewardContract_ = IFluidLendingStakingRewards(reward_);\n \n r_.rewardPerToken = rewardContract_.rewardPerToken();\n r_.getRewardForDuration = rewardContract_.getRewardForDuration();\n r_.totalSupply = rewardContract_.totalSupply();\n r_.periodFinish = rewardContract_.periodFinish();\n r_.rewardRate = rewardContract_.rewardRate();\n r_.rewardsDuration = rewardContract_.rewardsDuration();\n r_.rewardsToken = address(rewardContract_.rewardsToken());\n r_.fToken = address(rewardContract_.stakingToken());\n }\n }\n\n function getFTokensStakingRewardsEntireData(address[] memory rewards_) public view returns (FTokenStakingRewardsDetails[] memory r_) {\n r_ = new FTokenStakingRewardsDetails[](rewards_.length);\n for (uint i = 0; i < rewards_.length; i++) {\n r_[i] = getFTokenStakingRewardsEntireData(rewards_[i]);\n }\n }\n\n function getUserRewardsData(\n address user_,\n address reward_,\n FluidLendingResolverStructs.FTokenDetails memory fTokenDetails_\n ) public view returns (UserRewardDetails memory u_) {\n if (reward_ != address(0)) {\n IFluidLendingStakingRewards rewardContract_ = IFluidLendingStakingRewards(reward_);\n \n u_.earned = rewardContract_.earned(user_);\n u_.fTokenShares = rewardContract_.balanceOf(user_);\n u_.underlyingAssets = (u_.fTokenShares * fTokenDetails_.convertToAssets) / (10**fTokenDetails_.decimals);\n u_.ftokenAllowance = IERC20(fTokenDetails_.tokenAddress).allowance(user_, reward_);\n }\n }\n\n function getUserAllRewardsData(\n address user_,\n address[] memory rewards_,\n FluidLendingResolverStructs.FTokenDetails[] memory fTokensDetails_\n ) public view returns (UserRewardDetails[] memory u_) {\n u_ = new UserRewardDetails[](rewards_.length);\n for (uint i = 0; i < rewards_.length; i++) {\n u_[i] = getUserRewardsData(user_, rewards_[i], fTokensDetails_[i]);\n }\n }\n\n struct underlyingTokenToRewardsMap {\n address underlyingToken;\n address rewardContract;\n }\n\n function getUserPositions(\n address user_,\n underlyingTokenToRewardsMap[] memory rewardsMap_\n ) public view returns (UserFTokenRewardsEntireData[] memory u_) {\n FluidLendingResolverStructs.FTokenDetailsUserPosition[] memory e_ = LENDING_RESOLVER.getUserPositions(user_);\n uint length_ = e
},
"contracts/periphery/resolvers/stakingRewards/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Structs as FluidLendingResolverStructs } from \"../lending/structs.sol\";\n\nabstract contract Structs {\n struct FTokenStakingRewardsDetails {\n uint rewardPerToken; // how much rewards have distributed per token since start\n uint getRewardForDuration; // total rewards being distributed\n uint totalSupply; // total fToken deposited\n uint periodFinish; // when rewards will get over\n uint rewardRate; // total rewards / duration\n uint rewardsDuration; // how long rewards are for since start to end\n address rewardsToken; // which token are we distributing as rewards\n address fToken; // which token are we distributing as rewards\n }\n\n struct UserRewardDetails {\n uint earned;\n uint fTokenShares; // user fToken balance deposited\n uint underlyingAssets; // user fToken balance converted into underlying token\n uint ftokenAllowance; // allowance of fToken to rewards contract\n }\n\n struct UserFTokenRewardsEntireData {\n FluidLendingResolverStructs.FTokenDetails fTokenDetails;\n FluidLendingResolverStructs.UserPosition userPosition;\n FTokenStakingRewardsDetails fTokenRewardsDetails;\n UserRewardDetails userRewardsDetails;\n }\n}\n"
},
"contracts/periphery/resolvers/steth/iStETHResolver.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IFluidStETHQueue } from \"../../../protocols/steth/interfaces/iStETHQueue.sol\";\nimport { ILidoWithdrawalQueue } from \"../../../protocols/steth/interfaces/external/iLidoWithdrawalQueue.sol\";\n\ninterface IFluidStETHResolver {\n /// @notice address of the stETHQueue contract\n function STETH_QUEUE() external view returns (IFluidStETHQueue);\n\n /// @notice address of the Lido Withdrawal Queue contract (0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1)\n function LIDO_WITHDRAWAL_QUEUE() external view returns (ILidoWithdrawalQueue);\n\n /// @notice checks if a linked claim for `claimTo_` and `claimTo_` is ready to be processed at Lido Withdrawal Queue\n /// @param claimTo_ claimTo receiver to process the claim for\n /// @param requestIdFrom_ Lido requestId from (start), as emitted at time of queuing via `LogQueue`\n function isClaimable(address claimTo_, uint256 requestIdFrom_) external view returns (bool);\n}\n"
},
"contracts/periphery/resolvers/steth/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidStETHResolver } from \"./iStETHResolver.sol\";\nimport { IFluidStETHQueue } from \"../../../protocols/steth/interfaces/iStETHQueue.sol\";\nimport { Structs as StETHQueueStructs } from \"../../../protocols/steth/structs.sol\";\nimport { ILidoWithdrawalQueue } from \"../../../protocols/steth/interfaces/external/iLidoWithdrawalQueue.sol\";\n\n/// @notice Fluid StETH protocol resolver\n/// Implements various view-only methods to give easy access to StETH protocol data.\ncontract FluidStETHResolver is IFluidStETHResolver {\n /// @inheritdoc IFluidStETHResolver\n IFluidStETHQueue public immutable STETH_QUEUE;\n\n /// @inheritdoc IFluidStETHResolver\n ILidoWithdrawalQueue public immutable LIDO_WITHDRAWAL_QUEUE;\n\n /// @notice thrown if an input param address is zero\n error FluidStETHResolver__AddressZero();\n /// @notice thrown if there is no Claim queued for the given input data\n error FluidStETHResolver__NoClaimQueued();\n\n constructor(IFluidStETHQueue stEthQueue_) {\n if (address(stEthQueue_) == address(0)) {\n revert FluidStETHResolver__AddressZero();\n }\n\n STETH_QUEUE = stEthQueue_;\n (, LIDO_WITHDRAWAL_QUEUE, ) = stEthQueue_.constantsView();\n }\n\n /// @inheritdoc IFluidStETHResolver\n function isClaimable(address claimTo_, uint256 requestIdFrom_) public view returns (bool) {\n StETHQueueStructs.Claim memory claim_ = STETH_QUEUE.claims(claimTo_, requestIdFrom_);\n\n if (claim_.checkpoint == 0) {\n revert FluidStETHResolver__NoClaimQueued();\n }\n\n uint256 requestsLength_ = claim_.requestIdTo - requestIdFrom_ + 1;\n uint256[] memory requestIds_;\n if (requestsLength_ == 1) {\n // only one request id\n requestIds_ = new uint256[](1);\n requestIds_[0] = requestIdFrom_;\n return LIDO_WITHDRAWAL_QUEUE.getWithdrawalStatus(requestIds_)[0].isFinalized;\n }\n\n // build requestIds array from `requestIdFrom` to `requestIdTo`\n uint256 curRequest_ = requestIdFrom_;\n for (uint256 i; i < requestsLength_; ) {\n requestIds_[i] = curRequest_;\n\n unchecked {\n ++i;\n ++curRequest_;\n }\n }\n\n // get requests statuses\n ILidoWithdrawalQueue.WithdrawalRequestStatus[] memory statuses_ = LIDO_WITHDRAWAL_QUEUE.getWithdrawalStatus(\n requestIds_\n );\n\n // check for each status that it is finalized\n for (uint256 i; i < requestsLength_; ) {\n if (!statuses_[i].isFinalized) {\n return false;\n }\n\n unchecked {\n ++i;\n }\n }\n\n return true;\n }\n}\n"
},
"contracts/periphery/resolvers/vault/helpers.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Variables } from \"./variables.sol\";\nimport { Structs } from \"./structs.sol\";\n\ncontract Helpers is Variables, Structs {\n function normalSlot(uint256 slot_) public pure returns (bytes32) {\n return bytes32(slot_);\n }\n\n /// @notice Calculating the slot ID for Liquidity contract for single mapping\n function calculateStorageSlotUintMapping(uint256 slot_, uint key_) public pure returns (bytes32) {\n return keccak256(abi.encode(key_, slot_));\n }\n\n /// @notice Calculating the slot ID for Liquidity contract for single mapping\n function calculateStorageSlotIntMapping(uint256 slot_, int key_) public pure returns (bytes32) {\n return keccak256(abi.encode(key_, slot_));\n }\n\n /// @notice Calculating the slot ID for Liquidity contract for double mapping\n function calculateDoubleIntUintMapping(uint256 slot_, int key1_, uint key2_) public pure returns (bytes32) {\n bytes32 intermediateSlot_ = keccak256(abi.encode(key1_, slot_));\n return keccak256(abi.encode(key2_, intermediateSlot_));\n }\n\n function tickHelper(uint tickRaw_) public pure returns (int tick) {\n require(tickRaw_ < X20, \"invalid-number\");\n if (tickRaw_ > 0) {\n tick = tickRaw_ & 1 == 1 ? int((tickRaw_ >> 1) & X19) : -int((tickRaw_ >> 1) & X19);\n } else {\n tick = type(int).min;\n }\n }\n\n constructor(\n address factory_,\n address liquidity_,\n address liquidityResolver_\n ) Variables(factory_, liquidity_, liquidityResolver_) {}\n}\n"
},
"contracts/periphery/resolvers/vault/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Helpers } from \"./helpers.sol\";\nimport { TickMath } from \"../../../libraries/tickMath.sol\";\nimport { BigMathMinified } from \"../../../libraries/bigMathMinified.sol\";\nimport { IFluidOracle } from \"../../../oracle/fluidOracle.sol\";\nimport { IFluidVaultT1 } from \"../../../protocols/vault/interfaces/iVaultT1.sol\";\nimport { Structs as LiquidityStructs } from \"../liquidity/structs.sol\";\nimport { LiquiditySlotsLink } from \"../../../libraries/liquiditySlotsLink.sol\";\nimport { LiquidityCalcs } from \"../../../libraries/liquidityCalcs.sol\";\n\ninterface TokenInterface {\n function balanceOf(address) external view returns (uint);\n}\n\n/// @notice Fluid Vault protocol resolver\n/// Implements various view-only methods to give easy access to Vault protocol data.\ncontract FluidVaultResolver is Helpers {\n function getVaultAddress(uint256 vaultId_) public view returns (address vault_) {\n // @dev based on https://ethereum.stackexchange.com/a/61413\n bytes memory data;\n if (vaultId_ == 0x00) {\n // nonce of smart contract always starts with 1. so, with nonce 0 there won't be any deployment\n return address(0);\n } else if (vaultId_ <= 0x7f) {\n data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), address(FACTORY), uint8(vaultId_));\n } else if (vaultId_ <= 0xff) {\n data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), address(FACTORY), bytes1(0x81), uint8(vaultId_));\n } else if (vaultId_ <= 0xffff) {\n data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), address(FACTORY), bytes1(0x82), uint16(vaultId_));\n } else if (vaultId_ <= 0xffffff) {\n data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), address(FACTORY), bytes1(0x83), uint24(vaultId_));\n } else {\n data = abi.encodePacked(bytes1(0xda), bytes1(0x94), address(FACTORY), bytes1(0x84), uint32(vaultId_));\n }\n\n return address(uint160(uint256(keccak256(data))));\n }\n\n function getVaultId(address vault_) public view returns (uint id_) {\n id_ = IFluidVaultT1(vault_).VAULT_ID();\n }\n\n function getTokenConfig(uint nftId_) public view returns (uint) {\n return FACTORY.readFromStorage(calculateStorageSlotUintMapping(3, nftId_));\n }\n\n function getVaultVariablesRaw(address vault_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(normalSlot(0));\n }\n\n function getVaultVariables2Raw(address vault_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(normalSlot(1));\n }\n\n function getAbsorbedLiquidityRaw(address vault_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(normalSlot(2));\n }\n\n function getPositionDataRaw(address vault_, uint positionId_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(calculateStorageSlotUintMapping(3, positionId_));\n }\n\n // if tick > 0 then key_ = tick / 256\n // if tick < 0 then key_ = (tick / 256) - 1\n function getTickHasDebtRaw(address vault_, int key_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(calculateStorageSlotIntMapping(4, key_));\n }\n\n function getTickDataRaw(address vault_, int tick_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(calculateStorageSlotIntMapping(5, tick_));\n }\n\n // TODO: Verify below\n // id_ = (realId_ / 3) + 1\n function getTickIdDataRaw(address vault_, int tick_, uint id_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(calculateDoubleIntUintMapping(6, tick_, id_));\n }\n\n function getBranchDataRaw(address vault_, uint branch_) public view returns (uint) {\n return IFluidVaultT1(vault_).readFromStorage(calculateStorageSlotUintMapping(7, branch_));\n }\n\n function getRateRaw(address vault_) public view returns
},
"contracts/periphery/resolvers/vault/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidVaultT1 } from \"../../../protocols/vault/interfaces/iVaultT1.sol\";\nimport { Structs as FluidLiquidityResolverStructs } from \"../liquidity/structs.sol\";\n\ncontract Structs {\n struct Configs {\n uint16 supplyRateMagnifier;\n uint16 borrowRateMagnifier;\n uint16 collateralFactor;\n uint16 liquidationThreshold;\n uint16 liquidationMaxLimit;\n uint16 withdrawalGap;\n uint16 liquidationPenalty;\n uint16 borrowFee;\n address oracle;\n uint oraclePrice;\n address rebalancer;\n }\n\n struct ExchangePricesAndRates {\n uint lastStoredLiquiditySupplyExchangePrice;\n uint lastStoredLiquidityBorrowExchangePrice;\n uint lastStoredVaultSupplyExchangePrice;\n uint lastStoredVaultBorrowExchangePrice;\n uint liquiditySupplyExchangePrice;\n uint liquidityBorrowExchangePrice;\n uint vaultSupplyExchangePrice;\n uint vaultBorrowExchangePrice;\n uint supplyRateVault;\n uint borrowRateVault;\n uint supplyRateLiquidity;\n uint borrowRateLiquidity;\n uint rewardsRate; // rewards rate in percent 1e2 precision (1% = 100, 100% = 10000)\n }\n\n struct TotalSupplyAndBorrow {\n uint totalSupplyVault;\n uint totalBorrowVault;\n uint totalSupplyLiquidity;\n uint totalBorrowLiquidity;\n uint absorbedSupply;\n uint absorbedBorrow;\n }\n\n struct LimitsAndAvailability {\n uint withdrawLimit;\n uint withdrawableUntilLimit;\n uint withdrawable;\n uint borrowLimit;\n uint borrowableUntilLimit;\n uint borrowable;\n uint minimumBorrowing;\n }\n\n struct CurrentBranchState {\n uint status; // if 0 then not liquidated, if 1 then liquidated, if 2 then merged, if 3 then closed\n int minimaTick;\n uint debtFactor;\n uint partials;\n uint debtLiquidity;\n uint baseBranchId;\n int baseBranchMinima;\n }\n\n struct VaultState {\n uint totalPositions;\n int topTick;\n uint currentBranch;\n uint totalBranch;\n uint totalBorrow;\n uint totalSupply;\n CurrentBranchState currentBranchState;\n }\n\n struct VaultEntireData {\n address vault;\n IFluidVaultT1.ConstantViews constantVariables;\n Configs configs;\n ExchangePricesAndRates exchangePricesAndRates;\n TotalSupplyAndBorrow totalSupplyAndBorrow;\n LimitsAndAvailability limitsAndAvailability;\n VaultState vaultState;\n // liquidity related data such as supply amount, limits, expansion etc.\n FluidLiquidityResolverStructs.UserSupplyData liquidityUserSupplyData;\n // liquidity related data such as borrow amount, limits, expansion etc.\n FluidLiquidityResolverStructs.UserBorrowData liquidityUserBorrowData;\n }\n\n struct UserPosition {\n uint nftId;\n address owner;\n bool isLiquidated;\n bool isSupplyPosition; // if true that means borrowing is 0\n int tick;\n uint tickId;\n uint beforeSupply;\n uint beforeBorrow;\n uint beforeDustBorrow;\n uint supply;\n uint borrow;\n uint dustBorrow;\n }\n\n /// @dev liquidation related data\n /// @param vault address of vault\n /// @param tokenIn_ address of token in\n /// @param tokenOut_ address of token out\n /// @param tokenInAmtOne_ (without absorb liquidity) minimum of available liquidation & tokenInAmt_\n /// @param tokenOutAmtOne_ (without absorb liquidity) expected token out, collateral to withdraw\n /// @param tokenInAmtTwo_ (absorb liquidity included) minimum of available liquidation & tokenInAmt_. In most cases it'll be same as tokenInAmtOne_ but sometimes can be bigger.\n /// @param tokenOutAmtTwo_ (absorb liquidity included) expected token out, collateral to withdraw. In most cases it'll be sa
},
"contracts/periphery/resolvers/vault/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLiquidityResolver } from \"../liquidity/iLiquidityResolver.sol\";\nimport { IFluidVaultFactory } from \"../../../protocols/vault/interfaces/iVaultFactory.sol\";\n\ninterface IFluidLiquidity {\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\n}\n\ncontract Variables {\n IFluidVaultFactory public immutable FACTORY;\n IFluidLiquidity public immutable LIQUIDITY;\n IFluidLiquidityResolver public immutable LIQUIDITY_RESOLVER;\n\n // 30 bits (used for partials mainly)\n uint internal constant X8 = 0xff;\n uint internal constant X10 = 0x3ff;\n uint internal constant X14 = 0x3fff;\n uint internal constant X15 = 0x7fff;\n uint internal constant X16 = 0xffff;\n uint internal constant X19 = 0x7ffff;\n uint internal constant X20 = 0xfffff;\n uint internal constant X24 = 0xffffff;\n uint internal constant X25 = 0x1ffffff;\n uint internal constant X30 = 0x3fffffff;\n uint internal constant X32 = 0xffffffff;\n uint internal constant X35 = 0x7ffffffff;\n uint internal constant X40 = 0xffffffffff;\n uint internal constant X50 = 0x3ffffffffffff;\n uint internal constant X64 = 0xffffffffffffffff;\n uint internal constant X96 = 0xffffffffffffffffffffffff;\n uint internal constant X128 = 0xffffffffffffffffffffffffffffffff;\n /// @dev address that is mapped to the chain native token\n address internal constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n constructor(address factory_, address liquidity_, address liquidityResolver_) {\n FACTORY = IFluidVaultFactory(factory_);\n LIQUIDITY = IFluidLiquidity(liquidity_);\n LIQUIDITY_RESOLVER = IFluidLiquidityResolver(liquidityResolver_);\n }\n}\n"
},
"contracts/protocols/flashloan/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Error {\n error FluidFlashLenderError(uint256 errorId_);\n}\n"
},
"contracts/protocols/flashloan/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | FlashLender | \n |__________________________________*/\n\n /// @notice Thrown when a function encounters or is provided with an address set to the zero address.\n uint256 internal constant FlashLender__ZeroAddress = 80001;\n\n /// @notice Thrown when the requested flash loan amount exceeds the allowed maximum.\n uint256 internal constant FlashLender__MaxFlashLoanAmountExceeded = 80002;\n\n /// @notice Thrown when a function returns an unexpected value.\n uint256 internal constant FlashLender__InvalidReturnValue = 80003;\n\n /// @notice Thrown when an unauthorized action is attempted.\n uint256 internal constant FlashLender__Unauthorized = 80004;\n\n /// @notice Thrown when an operation involves a token that isn't supported.\n uint256 internal constant FlashLender__TokenNotSupported = 80005;\n\n /// @notice Thrown when a token is already being borrowed by flashloan protocol.\n uint256 internal constant FlashLender__DuplicateBorrow = 80006;\n}\n"
},
"contracts/protocols/flashloan/helpers.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { LiquiditySlotsLink } from \"../../libraries/liquiditySlotsLink.sol\";\nimport { IFluidLiquidity } from \"../../liquidity/interfaces/iLiquidity.sol\";\n\nimport { ErrorTypes } from \"./errorTypes.sol\";\nimport { Error } from \"./error.sol\";\nimport { Variables } from \"./variables.sol\";\n\n/// @dev Flashloan protocol helper methods\nabstract contract Helpers is Variables, Error {\n constructor(IFluidLiquidity liquidity_) Variables(liquidity_) {}\n\n /// @notice Reads user borrow data of currency to be lent.\n /// @param token_ The loan currency.\n /// @return user borrow data for `token`.\n function _readUserBorrowData(address token_) internal view returns (uint256) {\n bytes32 slot_ = LiquiditySlotsLink.calculateDoubleMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT,\n address(this),\n token_\n );\n return LIQUIDITY.readFromStorage(slot_);\n }\n\n /// @notice Checks if the given address is valid (not equal to address(0)).\n /// @param value_ The address to check..\n function _checkValidAddress(address value_) internal pure {\n if (value_ == address(0)) {\n revert FluidFlashLenderError(ErrorTypes.FlashLender__ZeroAddress);\n }\n }\n\n /// @notice Ensures that the provided address is valid (not equal to address(0)).\n /// @param value_ The address to check.\n modifier validAddress(address value_) {\n _checkValidAddress(value_);\n _;\n }\n}\n"
},
"contracts/protocols/flashloan/interfaces/IERC3156FlashBorrower.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IERC3156FlashBorrower {\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n"
},
"contracts/protocols/flashloan/interfaces/IERC3156FlashLender.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\ninterface IERC3156FlashLender {\n /// @dev The amount of currency available to be lent.\n /// @param token The loan currency.\n /// @return The amount of `token` that can be borrowed.\n function maxFlashLoan(address token) external view returns (uint256);\n\n /// @dev The fee to be charged for a given loan.\n /// @param token The loan currency.\n /// @param amount The amount of tokens lent.\n /// @return The amount of `token` to be charged for the loan, on top of the returned principal.\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /// @dev Initiate a flash loan.\n /// @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n /// @param token The loan currency.\n /// @param amount The amount of tokens lent.\n /// @param data Arbitrary data structure, intended to contain user-defined parameters.\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n"
},
"contracts/protocols/flashloan/interfaces/iFlashBorrower.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport \"./IERC3156FlashBorrower.sol\";\nimport { Structs } from \"../structs.sol\";\n\ninterface IFlashBorrower is IERC3156FlashBorrower {\n function onFlashLoanMultiple(\n address initiator,\n Structs.AddressUint256[] calldata tokensWithValues,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n"
},
"contracts/protocols/flashloan/interfaces/iFlashLender.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IFlashBorrower } from \"./iFlashBorrower.sol\";\nimport { IERC3156FlashLender } from \"./IERC3156FlashLender.sol\";\nimport { IERC3156FlashBorrower } from \"./IERC3156FlashBorrower.sol\";\nimport { Structs } from \"../structs.sol\";\n\ninterface IFluidFlashLender is IERC3156FlashLender {\n /// @notice Initiate a flash loan with multiple tokens.\n /// @param receiver_ The receiver of the tokens in the loan, and the receiver of the callback.\n /// @param tokensWithAmounts_ An array of token addresses and loan amounts.\n /// @param data_ Arbitrary data structure, intended to contain user-defined parameters.\n /// @return 'true' if the flash loan are successful\n function flashLoanMultiple(\n IFlashBorrower receiver_,\n Structs.AddressUint256[] calldata tokensWithAmounts_,\n bytes calldata data_\n ) external returns (bool);\n}\n"
},
"contracts/protocols/flashloan/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport { Helpers } from \"./helpers.sol\";\nimport { Structs } from \"./structs.sol\";\nimport { ErrorTypes } from \"./errorTypes.sol\";\nimport { IFluidFlashLender } from \"./interfaces/iFlashLender.sol\";\nimport { IERC3156FlashBorrower } from \"./interfaces/IERC3156FlashBorrower.sol\";\nimport { IFlashBorrower } from \"./interfaces/iFlashBorrower.sol\";\n\nimport { IFluidLiquidity } from \"../../liquidity/interfaces/iLiquidity.sol\";\nimport { IProtocol } from \"../../liquidity/userModule/main.sol\";\n\nimport { LiquidityCalcs } from \"../../libraries/liquidityCalcs.sol\";\nimport { LiquiditySlotsLink } from \"../../libraries/liquiditySlotsLink.sol\";\n\n/// @notice contract that provides Flashloans via Fluid. ERC-3156 compatible.\n/// In addition also implements a `flashLoanMultiple()` method which can be used to flash loan multiple tokens at once.\n/// @dev Fee is a constant 0. This contract is not upgradeable.\n//\n// @dev Fee is not really implemented, just the parts that are needed to ensure compatibility with ERC-3156.\n// @dev user borrow amount for this contract at Liquidity will slowly grow but that is not an issue as the amount\n// being repaid is still the exact original amount always.\ncontract FluidFlashLender is Structs, IFluidFlashLender, IProtocol, Helpers {\n using SafeERC20 for IERC20;\n\n /// @notice emitted whenever funds for a certain `token` are rescued to Liquidity\n event LogRescueFunds(address indexed token);\n\n /// @notice emitted when a flashloan has been taken and repaid\n event LogFlashLoan(address indexed token, uint256 indexed amount, address indexed receiver);\n\n constructor(IFluidLiquidity liquidity_) Helpers(liquidity_) {}\n\n /// @notice The amount of currency available to be lent.\n /// @param token_ The loan currency.\n /// @return The amount of `token` that can be borrowed.\n function maxFlashLoan(address token_) public view returns (uint256) {\n // maximum flashloan is either:\n // a) the borrow limit of Flashloan protocol at Liquidity or\n // b) the total available amount of token at Liquidity (if lower than borrow limit)\n\n // get current exchange rates\n (uint256 supplyExchangePrice_, uint256 borrowExchangePrice_) = LiquidityCalcs.calcExchangePrices(\n LIQUIDITY.readFromStorage(\n LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n token_\n )\n )\n );\n\n // a) get the borrow limit\n uint256 userBorrowData_ = _readUserBorrowData(token_);\n uint256 userBorrow_ = (userBorrowData_ >> LiquiditySlotsLink.BITS_USER_BORROW_AMOUNT) & LiquidityCalcs.X64;\n // get borrow limit\n uint256 borrowLimit_ = LiquidityCalcs.calcBorrowLimitBeforeOperate(userBorrowData_, userBorrow_);\n // revert if Flashloan protocol has already borrowed more than 0.0001% of borrow limit for the `token_`. This\n // catches any duplicate token borrows. We can not just check for user borrow == 0 because of rounding.\n if (userBorrow_ > (borrowLimit_ / 100_000)) {\n revert FluidFlashLenderError(ErrorTypes.FlashLender__DuplicateBorrow);\n }\n // subtract any already borrowed amount\n borrowLimit_ -= userBorrow_;\n\n if (userBorrowData_ & 1 == 1) {\n // convert raw borrow limit amount to normal for withInterest mode\n borrowLimit_ = (borrowLimit_ * borrowExchangePrice_) / LiquidityCalcs.EXCHANGE_PRICES_PRECISION;\n }\n\n // b) get the total available amount at Liquidity (tota
},
"contracts/protocols/flashloan/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Structs {\n struct AddressUint256 {\n address addr;\n uint256 value;\n }\n}\n"
},
"contracts/protocols/flashloan/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLiquidity } from \"../../liquidity/interfaces/iLiquidity.sol\";\n\nabstract contract Variables {\n /// @dev address that is mapped to the chain native token\n address internal constant _NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n bytes32 internal constant _RETURN_VALUE_FOR_FLASHLOAN_SINGLE = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n bytes32 internal constant _RETURN_VALUE_FOR_FLASHLOAN_MULTIPLE = keccak256(\"FlashBorrower.onFlashLoanMultiple\");\n\n /// @dev Storage slot with the admin of the contract at Liquidity. Logic from \"proxy.sol\".\n /// This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n bytes32 internal constant _GOVERNANCE_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /// @dev fee for flashloan set globally for all tokens\n //\n // @dev can't just change this to a value != 0 as that case is not fully implemented. Ensure necessary changes are\n // made if _FLASH_FEE must be set to value != 0.\n uint256 internal constant _FLASH_FEE = 0;\n\n /// @notice address of the Fluid Liquidity contract\n IFluidLiquidity public immutable LIQUIDITY;\n\n constructor(IFluidLiquidity liquidity_) {\n LIQUIDITY = liquidity_;\n }\n}\n"
},
"contracts/protocols/lending/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Error {\n error FluidLendingError(uint256 errorId_);\n}\n"
},
"contracts/protocols/lending/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | fToken | \n |__________________________________*/\n\n /// @notice thrown when a deposit amount is too small to increase BigMath stored balance in Liquidity.\n /// precision of BigMath is 1e12, so if token holds 120_000_000_000 USDC, min amount to make a difference would be 0.1 USDC.\n /// i.e. user would send a very small deposit which mints no shares -> revert\n uint256 internal constant fToken__DepositInsignificant = 20001;\n\n /// @notice thrown when minimum output amount is not reached, e.g. for minimum shares minted (deposit) or\n /// minimum assets received (redeem)\n uint256 internal constant fToken__MinAmountOut = 20002;\n\n /// @notice thrown when maximum amount is surpassed, e.g. for maximum shares burned (withdraw) or\n /// maximum assets input (mint)\n uint256 internal constant fToken__MaxAmount = 20003;\n\n /// @notice thrown when invalid params are sent to a method, e.g. zero address\n uint256 internal constant fToken__InvalidParams = 20004;\n\n /// @notice thrown when an unauthorized caller is trying to execute an auth-protected method\n uint256 internal constant fToken__Unauthorized = 20005;\n\n /// @notice thrown when a with permit / signature method is called from msg.sender that is the owner.\n /// Should call the method without permit instead if msg.sender is the owner.\n uint256 internal constant fToken__PermitFromOwnerCall = 20006;\n\n /// @notice thrown when a reentrancy is detected.\n uint256 internal constant fToken__Reentrancy = 20007;\n\n /// @notice thrown when _tokenExchangePrice overflows type(uint64).max\n uint256 internal constant fToken__ExchangePriceOverflow = 20008;\n\n /// @notice thrown when msg.sender is not rebalancer\n uint256 internal constant fToken__NotRebalancer = 20009;\n\n /// @notice thrown when rebalance is called with msg.value > 0 for non NativeUnderlying fToken\n uint256 internal constant fToken__NotNativeUnderlying = 20010;\n\n /// @notice thrown when the received new liquidity exchange price is of unexpected value (< than the old one)\n uint256 internal constant fToken__LiquidityExchangePriceUnexpected = 20011;\n\n /***********************************|\n | fToken Native Underlying | \n |__________________________________*/\n\n /// @notice thrown when native deposit is called but sent along `msg.value` does not cover the deposit amount\n uint256 internal constant fTokenNativeUnderlying__TransferInsufficient = 21001;\n\n /// @notice thrown when a liquidity callback is called for a native token operation\n uint256 internal constant fTokenNativeUnderlying__UnexpectedLiquidityCallback = 21002;\n\n /***********************************|\n | Lending Factory | \n |__________________________________*/\n\n /// @notice thrown when a method is called with invalid params\n uint256 internal constant LendingFactory__InvalidParams = 22001;\n\n /// @notice thrown when the provided input param address is zero\n uint256 internal constant LendingFactory__ZeroAddress = 22002;\n\n /// @notice thrown when the token already exists\n uint256 internal constant LendingFactory__TokenExists = 22003;\n\n /// @notice thrown when the fToken has not yet been configured at Liquidity\n uint256 internal constant LendingFactory__LiquidityNotConfigured = 22004;\n\n /// @notice thrown when an unauthorized caller is trying to execute an auth-protected method\n uint256 internal constant LendingFactory__Unauthorized = 22005;\n\n /***********************************|\n | Lending Rewards Rate Model | \n |__________________________________*/\n\n /// @notice thrown when invalid params are given as input\n uint256 internal constant LendingRewardsRateModel__InvalidParams = 23001;\n\n /// @notice thrown when calculated rewards rate i
},
"contracts/protocols/lending/fToken/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLendingRewardsRateModel } from \"../interfaces/iLendingRewardsRateModel.sol\";\n\nabstract contract Events {\n /// @notice emitted whenever admin updates rewards rate model\n event LogUpdateRewards(IFluidLendingRewardsRateModel indexed rewardsRateModel);\n\n /// @notice emitted whenever rebalance is executed to fund difference between Liquidity deposit and totalAssets()\n /// as rewards through the rebalancer.\n event LogRebalance(uint256 assets);\n\n /// @notice emitted whenever exchange rates are updated\n event LogUpdateRates(uint256 tokenExchangePrice, uint256 liquidityExchangePrice);\n\n /// @notice emitted whenever funds for a certain `token` are rescued to Liquidity\n event LogRescueFunds(address indexed token);\n\n /// @notice emitted whenever rebalancer address is updated\n event LogUpdateRebalancer(address indexed rebalancer);\n}\n"
},
"contracts/protocols/lending/fToken/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ERC20, IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IERC4626 } from \"@openzeppelin/contracts/interfaces/IERC4626.sol\";\nimport { FixedPointMathLib } from \"solmate/src/utils/FixedPointMathLib.sol\";\nimport { IERC20Permit } from \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport { IAllowanceTransfer } from \"../interfaces/permit2/iAllowanceTransfer.sol\";\nimport { IFluidLendingRewardsRateModel } from \"../interfaces/iLendingRewardsRateModel.sol\";\nimport { IFluidLendingFactory } from \"../interfaces/iLendingFactory.sol\";\nimport { IFToken, IFTokenAdmin } from \"../interfaces/iFToken.sol\";\nimport { LiquidityCalcs } from \"../../../libraries/liquidityCalcs.sol\";\nimport { BigMathMinified } from \"../../../libraries/bigMathMinified.sol\";\nimport { LiquiditySlotsLink } from \"../../../libraries/liquiditySlotsLink.sol\";\nimport { SafeTransfer } from \"../../../libraries/safeTransfer.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\nimport { Variables } from \"./variables.sol\";\nimport { Events } from \"./events.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\n\n/// @dev ReentrancyGuard based on OpenZeppelin implementation.\n/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.8/contracts/security/ReentrancyGuard.sol\nabstract contract ReentrancyGuard is Error, Variables {\n uint8 internal constant REENTRANCY_NOT_ENTERED = 1;\n uint8 internal constant REENTRANCY_ENTERED = 2;\n\n constructor() {\n _status = REENTRANCY_NOT_ENTERED;\n }\n\n /// @dev checks that no reentrancy occurs, reverts if so. Calling the method in the modifier reduces\n /// bytecode size as modifiers are inlined into bytecode\n function _checkReentrancy() internal {\n // On the first call to nonReentrant, _status will be NOT_ENTERED\n if (_status != REENTRANCY_NOT_ENTERED) {\n revert FluidLendingError(ErrorTypes.fToken__Reentrancy);\n }\n\n // Any calls to nonReentrant after this point will fail\n _status = REENTRANCY_ENTERED;\n }\n\n /// @dev Prevents a contract from calling itself, directly or indirectly.\n /// See OpenZeppelin implementation for more info\n modifier nonReentrant() {\n _checkReentrancy();\n\n _;\n\n // storing original value triggers a refund (see https://eips.ethereum.org/EIPS/eip-2200)\n _status = REENTRANCY_NOT_ENTERED;\n }\n}\n\n/// @dev internal methods for fToken contracts\nabstract contract fTokenCore is Error, IERC4626, IFToken, Variables, Events, ReentrancyGuard {\n using FixedPointMathLib for uint256;\n\n /// @dev Gets current (updated) Liquidity supply exchange price for the underyling asset\n function _getLiquidityExchangePrice() internal view returns (uint256 supplyExchangePrice_) {\n (supplyExchangePrice_, ) = LiquidityCalcs.calcExchangePrices(\n LIQUIDITY.readFromStorage(LIQUIDITY_EXCHANGE_PRICES_SLOT)\n );\n }\n\n /// @dev Gets current Liquidity supply balance of `address(this)` for the underyling asset\n function _getLiquidityBalance() internal view returns (uint256 balance_) {\n // extract user supply amount\n uint256 userSupplyRaw_ = BigMathMinified.fromBigNumber(\n (LIQUIDITY.readFromStorage(LIQUIDITY_USER_SUPPLY_SLOT) >> LiquiditySlotsLink.BITS_USER_SUPPLY_AMOUNT) &\n LiquidityCalcs.X64,\n LiquidityCalcs.DEFAULT_EXPONENT_SIZE,\n LiquidityCalcs.DEFAULT_EXPONENT_MASK\n );\n\n unchecked {\n // can not overflow as userSupplyRaw_ can be maximally type(int128).max, liquidity exchange price type(uint64).max\n return (userSupplyRaw_ * _g
},
"contracts/protocols/lending/fToken/nativeUnderlying/fTokenNativeUnderlying.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { IERC4626 } from \"@openzeppelin/contracts/interfaces/IERC4626.sol\";\nimport { FixedPointMathLib } from \"solmate/src/utils/FixedPointMathLib.sol\";\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\n\nimport { SafeTransfer } from \"../../../../libraries/safeTransfer.sol\";\nimport { LiquiditySlotsLink } from \"../../../../libraries/liquiditySlotsLink.sol\";\nimport { ErrorTypes } from \"../../errorTypes.sol\";\nimport { fTokenCore, fTokenAdmin, fToken } from \"../main.sol\";\n\nimport { IWETH9 } from \"../../interfaces/external/iWETH9.sol\";\nimport { IFluidLendingFactory } from \"../../interfaces/iLendingFactory.sol\";\nimport { IFTokenAdmin, IFTokenNativeUnderlying, IFToken } from \"../../interfaces/iFToken.sol\";\nimport { IFluidLiquidity } from \"../../../../liquidity/interfaces/iLiquidity.sol\";\n\n/// @dev overrides certain methods from the inherited fToken used as base contract to make them compatible with\n/// the native token being used as underlying.\nabstract contract fTokenNativeUnderlyingOverrides is fToken, IFTokenNativeUnderlying {\n using FixedPointMathLib for uint256;\n\n /// @inheritdoc IFTokenNativeUnderlying\n address public constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /// @dev gets asset address for liquidity slot links, overridden to set native token address\n function _getLiquiditySlotLinksAsset() internal view virtual override returns (address) {\n return NATIVE_TOKEN_ADDRESS;\n }\n\n /// @dev Gets current Liquidity underlying token balance\n function _getLiquidityUnderlyingBalance() internal view virtual override returns (uint256) {\n return address(LIQUIDITY).balance;\n }\n\n /// @inheritdoc IFTokenAdmin\n function rescueFunds(address token_) external virtual override(IFTokenAdmin, fTokenAdmin) nonReentrant {\n _checkIsLendingFactoryAuth();\n\n if (token_ == NATIVE_TOKEN_ADDRESS) {\n Address.sendValue(payable(address(LIQUIDITY)), address(this).balance);\n } else {\n SafeTransfer.safeTransfer(address(token_), address(LIQUIDITY), IERC20(token_).balanceOf(address(this)));\n }\n\n emit LogRescueFunds(token_);\n }\n\n /*//////////////////////////////////////////////////////////////\n REWARDS\n //////////////////////////////////////////////////////////////*/\n\n /// @inheritdoc fTokenAdmin\n function rebalance()\n external\n payable\n virtual\n override(IFTokenAdmin, fTokenAdmin)\n nonReentrant\n returns (uint256 assets_)\n {\n if (msg.sender != _rebalancer) {\n revert FluidLendingError(ErrorTypes.fToken__NotRebalancer);\n }\n // calculating difference in assets. if liquidity balance is bigger it'll throw which is an expected behaviour\n assets_ = totalAssets() - _getLiquidityBalance();\n\n if (msg.value < assets_) {\n assets_ = msg.value;\n } else if (msg.value > assets_) {\n // send back overfunded msg.value amount\n Address.sendValue(payable(msg.sender), msg.value - assets_);\n }\n\n // send funds to Liquidity protocol to generate yield\n uint256 liquidityExchangePrice_ = _depositToLiquidity(assets_, new bytes(0));\n\n // update the exchange prices, always updating on storage\n _updateRates(liquidityExchangePrice_, true);\n\n // no shares are minted when funding fToken contract for rewards\n\n emit LogRebalance(assets_);\n }\n\n /*//////////////////////////////////////////////////////////////\n DEPOSIT\n //////////////////////////////////////////////////////////////*/\n\n /// @inheritdoc fTokenCore\n function _depositToLiquidity(
},
"contracts/protocols/lending/fToken/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { ERC20, IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ERC20Permit } from \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\n\nimport { IAllowanceTransfer } from \"../interfaces/permit2/iAllowanceTransfer.sol\";\nimport { LiquiditySlotsLink } from \"../../../libraries/liquiditySlotsLink.sol\";\nimport { IFToken } from \"../interfaces/iFToken.sol\";\nimport { IAllowanceTransfer } from \"../interfaces/permit2/iAllowanceTransfer.sol\";\nimport { IFluidLendingRewardsRateModel } from \"../interfaces/iLendingRewardsRateModel.sol\";\nimport { IFluidLendingFactory } from \"../interfaces/iLendingFactory.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\n\nabstract contract Constants {\n /// @dev permit2 contract, deployed to same address on EVM networks, see https://github.com/Uniswap/permit2\n IAllowanceTransfer internal constant PERMIT2 = IAllowanceTransfer(0x000000000022D473030F116dDEE9F6B43aC78BA3);\n\n /// @dev precision for exchange prices\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n\n /// @dev Ignoring leap years\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\n\n /// @dev max allowed reward rate is 50%\n uint256 internal constant MAX_REWARDS_RATE = 50 * 1e12; // 50%;\n\n /// @dev address of the Liquidity contract.\n IFluidLiquidity internal immutable LIQUIDITY;\n\n /// @dev address of the Lending factory contract.\n IFluidLendingFactory internal immutable LENDING_FACTORY;\n\n /// @dev address of the underlying asset contract.\n IERC20 internal immutable ASSET;\n\n /// @dev number of decimals for the fToken, same as ASSET\n uint8 internal immutable DECIMALS;\n\n /// @dev slot ids in Liquidity contract for underlying token.\n /// Helps in low gas fetch from liquidity contract by skipping delegate call with `readFromStorage`\n bytes32 internal immutable LIQUIDITY_EXCHANGE_PRICES_SLOT;\n bytes32 internal immutable LIQUIDITY_TOTAL_AMOUNTS_SLOT;\n bytes32 internal immutable LIQUIDITY_USER_SUPPLY_SLOT;\n\n /// @param liquidity_ liquidity contract address\n /// @param lendingFactory_ lending factory contract address\n /// @param asset_ underlying token address\n constructor(IFluidLiquidity liquidity_, IFluidLendingFactory lendingFactory_, IERC20 asset_) {\n DECIMALS = IERC20Metadata(address(asset_)).decimals();\n ASSET = asset_;\n LIQUIDITY = liquidity_;\n LENDING_FACTORY = lendingFactory_;\n\n LIQUIDITY_EXCHANGE_PRICES_SLOT = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n _getLiquiditySlotLinksAsset()\n );\n LIQUIDITY_TOTAL_AMOUNTS_SLOT = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_TOTAL_AMOUNTS_MAPPING_SLOT,\n _getLiquiditySlotLinksAsset()\n );\n LIQUIDITY_USER_SUPPLY_SLOT = LiquiditySlotsLink.calculateDoubleMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT,\n address(this),\n _getLiquiditySlotLinksAsset()\n );\n }\n\n /// @dev gets asset address for liquidity slot links, extracted to separate method so it can be overridden if needed\n function _getLiquiditySlotLinksAsset() internal view virtual returns (address) {\n return address(ASSET);\n }\n}\n\nabstract contract Variables is ERC20, ERC20Permit, Error, Constants, IFToken {\n /// @dev prefix for token name. fToken will append the underlying asset name\n string private constant TOKEN_NAME_PREFIX = \"Fluid \";\n /// @dev prefix for token symbol. fToken will append the underlying asset symbol\n string private constant
},
"contracts/protocols/lending/interfaces/external/iWETH9.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IWETH9 is IERC20 {\n function deposit() external payable;\n\n function withdraw(uint256 wad) external;\n}\n"
},
"contracts/protocols/lending/interfaces/iFToken.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IERC4626 } from \"@openzeppelin/contracts/interfaces/IERC4626.sol\";\n\nimport { IAllowanceTransfer } from \"./permit2/iAllowanceTransfer.sol\";\nimport { IFluidLendingRewardsRateModel } from \"./iLendingRewardsRateModel.sol\";\nimport { IFluidLendingFactory } from \"./iLendingFactory.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\n\ninterface IFTokenAdmin {\n /// @notice updates the rewards rate model contract.\n /// Only callable by LendingFactory auths.\n /// @param rewardsRateModel_ the new rewards rate model contract address.\n /// can be set to address(0) to set no rewards (to save gas)\n function updateRewards(IFluidLendingRewardsRateModel rewardsRateModel_) external;\n\n /// @notice Balances out the difference between fToken supply at Liquidity vs totalAssets().\n /// Deposits underlying from rebalancer address into Liquidity but doesn't mint any shares\n /// -> thus making deposit available as rewards.\n /// Only callable by rebalancer.\n /// @return assets_ amount deposited to Liquidity\n function rebalance() external payable returns (uint256 assets_);\n\n /// @notice gets the liquidity exchange price of the underlying asset, calculates the updated exchange price (with reward rates)\n /// and writes those values to storage.\n /// Callable by anyone.\n /// @return tokenExchangePrice_ exchange price of fToken share to underlying asset\n /// @return liquidityExchangePrice_ exchange price at Liquidity for the underlying asset\n function updateRates() external returns (uint256 tokenExchangePrice_, uint256 liquidityExchangePrice_);\n\n /// @notice sends any potentially stuck funds to Liquidity contract. Only callable by LendingFactory auths.\n function rescueFunds(address token_) external;\n\n /// @notice Updates the rebalancer address (ReserveContract). Only callable by LendingFactory auths.\n function updateRebalancer(address rebalancer_) external;\n}\n\ninterface IFToken is IERC4626, IFTokenAdmin {\n /// @notice returns minimum amount required for deposit (rounded up)\n function minDeposit() external view returns (uint256);\n\n /// @notice returns config, rewards and exchange prices data in a single view method.\n /// @return liquidity_ address of the Liquidity contract.\n /// @return lendingFactory_ address of the Lending factory contract.\n /// @return lendingRewardsRateModel_ address of the rewards rate model contract. changeable by LendingFactory auths.\n /// @return permit2_ address of the Permit2 contract used for deposits / mint with signature\n /// @return rebalancer_ address of the rebalancer allowed to execute `rebalance()`\n /// @return rewardsActive_ true if rewards are currently active\n /// @return liquidityBalance_ current Liquidity supply balance of `address(this)` for the underyling asset\n /// @return liquidityExchangePrice_ (updated) exchange price for the underlying assset in the liquidity protocol (without rewards)\n /// @return tokenExchangePrice_ (updated) exchange price between fToken and the underlying assset (with rewards)\n function getData()\n external\n view\n returns (\n IFluidLiquidity liquidity_,\n IFluidLendingFactory lendingFactory_,\n IFluidLendingRewardsRateModel lendingRewardsRateModel_,\n IAllowanceTransfer permit2_,\n address rebalancer_,\n bool rewardsActive_,\n uint256 liquidityBalance_,\n uint256 liquidityExchangePrice_,\n uint256 tokenExchangePrice_\n );\n\n /// @notice transfers `amount_` of `token_` to liquidity. Only callable by liquidity contract.\n /// @dev this callback is used to optimize gas consumption (reducing necessary token transfers).\n function liquidityCallback(address token_, uint256 amount_, bytes calldata data_) extern
},
"contracts/protocols/lending/interfaces/iLendingFactory.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\n\ninterface IFluidLendingFactoryAdmin {\n /// @notice reads if a certain `auth_` address is an allowed auth or not. Owner is auth by default.\n function isAuth(address auth_) external view returns (bool);\n\n /// @notice Sets an address as allowed auth or not. Only callable by owner.\n /// @param auth_ address to set auth value for\n /// @param allowed_ bool flag for whether address is allowed as auth or not\n function setAuth(address auth_, bool allowed_) external;\n\n /// @notice reads if a certain `deployer_` address is an allowed deployer or not. Owner is deployer by default.\n function isDeployer(address deployer_) external view returns (bool);\n\n /// @notice Sets an address as allowed deployer or not. Only callable by owner.\n /// @param deployer_ address to set deployer value for\n /// @param allowed_ bool flag for whether address is allowed as deployer or not\n function setDeployer(address deployer_, bool allowed_) external;\n\n /// @notice Sets the `creationCode_` bytecode for a certain `fTokenType_`. Only callable by auths.\n /// @param fTokenType_ the fToken Type used to refer the creation code\n /// @param creationCode_ contract creation code. can be set to bytes(0) to remove a previously available `fTokenType_`\n function setFTokenCreationCode(string memory fTokenType_, bytes calldata creationCode_) external;\n\n /// @notice creates token for `asset_` for a lending protocol with interest. Only callable by deployers.\n /// @param asset_ address of the asset\n /// @param fTokenType_ type of fToken:\n /// - if it's the native token, it should use `NativeUnderlying`\n /// - otherwise it should use `fToken`\n /// - could be more types available, check `fTokenTypes()`\n /// @param isNativeUnderlying_ flag to signal fToken type that uses native underlying at Liquidity\n /// @return token_ address of the created token\n function createToken(\n address asset_,\n string calldata fTokenType_,\n bool isNativeUnderlying_\n ) external returns (address token_);\n}\n\ninterface IFluidLendingFactory is IFluidLendingFactoryAdmin {\n /// @notice list of all created tokens\n function allTokens() external view returns (address[] memory);\n\n /// @notice list of all fToken types that can be deployed\n function fTokenTypes() external view returns (string[] memory);\n\n /// @notice returns the creation code for a certain `fTokenType_`\n function fTokenCreationCode(string memory fTokenType_) external view returns (bytes memory);\n\n /// @notice address of the Liquidity contract.\n function LIQUIDITY() external view returns (IFluidLiquidity);\n\n /// @notice computes deterministic token address for `asset_` for a lending protocol\n /// @param asset_ address of the asset\n /// @param fTokenType_ type of fToken:\n /// - if it's the native token, it should use `NativeUnderlying`\n /// - otherwise it should use `fToken`\n /// - could be more types available, check `fTokenTypes()`\n /// @return token_ detemrinistic address of the computed token\n function computeToken(address asset_, string calldata fTokenType_) external view returns (address token_);\n}\n"
},
"contracts/protocols/lending/interfaces/iLendingRewardsRateModel.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IFluidLendingRewardsRateModel {\n /// @notice Calculates the current rewards rate (APR)\n /// @param totalAssets_ amount of assets in the lending\n /// @return rate_ rewards rate percentage per year with 1e12 RATE_PRECISION, e.g. 1e12 = 1%, 1e14 = 100%\n /// @return ended_ flag to signal that rewards have ended (always 0 going forward)\n /// @return startTime_ start time of rewards to compare against last update timestamp\n function getRate(uint256 totalAssets_) external view returns (uint256 rate_, bool ended_, uint256 startTime_);\n\n /// @notice Returns config constants for rewards rate model\n function getConfig()\n external\n view\n returns (\n uint256 duration_,\n uint256 startTime_,\n uint256 endTime_,\n uint256 startTvl_,\n uint256 maxRate_,\n uint256 rewardAmount_,\n address initiator_\n );\n}\n"
},
"contracts/protocols/lending/interfaces/iStakingRewards.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IFluidLendingStakingRewards {\n // Views\n function lastTimeRewardApplicable() external view returns (uint256);\n\n function rewardPerToken() external view returns (uint256);\n\n function earned(address account) external view returns (uint256);\n\n function getRewardForDuration() external view returns (uint256);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address account) external view returns (uint256);\n\n function periodFinish() external view returns (uint256);\n\n function rewardRate() external view returns (uint256);\n\n function lastUpdateTime() external view returns (uint256);\n\n function rewardPerTokenStored() external view returns (uint256);\n\n function rewardsDuration() external view returns (uint256);\n\n function rewardsToken() external view returns (IERC20);\n\n function stakingToken() external view returns (IERC20);\n\n // Mutative\n\n function stake(uint256 amount) external;\n\n function withdraw(uint256 amount) external;\n\n function getReward() external;\n\n function exit() external;\n}\n"
},
"contracts/protocols/lending/interfaces/permit2/iAllowanceTransfer.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\n/// @title AllowanceTransfer\n/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts\n/// @dev Requires user's token approval on the Permit2 contract\n/// from https://github.com/Uniswap/permit2/blob/main/src/interfaces/ISignatureTransfer.sol.\n/// Copyright (c) 2022 Uniswap Labs\ninterface IAllowanceTransfer {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n /// @notice Thrown when an allowance on a token has expired.\n /// @param deadline The timestamp at which the allowed amount is no longer valid\n error AllowanceExpired(uint256 deadline);\n\n /// @notice Thrown when an allowance on a token has been depleted.\n /// @param amount The maximum amount allowed\n error InsufficientAllowance(uint256 amount);\n\n /// @notice Thrown when too many nonces are invalidated.\n error ExcessiveInvalidation();\n\n /// @notice Emits an event when the owner successfully invalidates an ordered nonce.\n event NonceInvalidation(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint48 newNonce,\n uint48 oldNonce\n );\n\n /// @notice Emits an event when the owner successfully sets permissions on a token for the spender.\n event Approval(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration\n );\n\n /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.\n event Permit(\n address indexed owner,\n address indexed token,\n address indexed spender,\n uint160 amount,\n uint48 expiration,\n uint48 nonce\n );\n\n /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.\n event Lockdown(address indexed owner, address token, address spender);\n\n /// @notice The permit data for a token\n struct PermitDetails {\n // ERC20 token address\n address token;\n // the maximum amount allowed to spend\n uint160 amount;\n // timestamp at which a spender's token allowances become invalid\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice The permit message signed for a single token allownce\n struct PermitSingle {\n // the permit data for a single token alownce\n PermitDetails details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The permit message signed for multiple token allowances\n struct PermitBatch {\n // the permit data for multiple token allowances\n PermitDetails[] details;\n // address permissioned on the allowed tokens\n address spender;\n // deadline on the permit signature\n uint256 sigDeadline;\n }\n\n /// @notice The saved permissions\n /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message\n /// @dev Setting amount to type(uint160).max sets an unlimited approval\n struct PackedAllowance {\n // amount allowed\n uint160 amount;\n // permission expiry\n uint48 expiration;\n // an incrementing value indexed per owner,token,and spender for each signature\n uint48 nonce;\n }\n\n /// @notice A token spender pair.\n struct TokenSpenderPair {\n // the token the spender is approved\n address token;\n // the spender address\n address spender;\n }\n\n /// @notice Details for a token transfer.\n struct AllowanceTransferDetails {\n // the owner of the token\n address from;\n // the recipient of
},
"contracts/protocols/lending/interfaces/permit2/IEIP712.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IEIP712 {\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
},
"contracts/protocols/lending/interfaces/permit2/IERC2612.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n// ERC20 with EIP2612 extension functions.\ninterface IERC2612 is IERC20 {\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n function nonces(address owner) external view returns (uint);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
},
"contracts/protocols/lending/interfaces/permit2/ISignatureTransfer.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IEIP712 } from \"./IEIP712.sol\";\n\n/// @title SignatureTransfer\n/// @notice Handles ERC20 token transfers through signature based actions\n/// @dev Requires user's token approval on the Permit2 contract\ninterface ISignatureTransfer is IEIP712 {\n /// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount\n /// @param maxAmount The maximum amount a spender can request to transfer\n error InvalidAmount(uint256 maxAmount);\n\n /// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred\n /// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred\n error LengthMismatch();\n\n /// @notice Emits an event when the owner successfully invalidates an unordered nonce.\n event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);\n\n /// @notice The token and amount details for a transfer signed in the permit transfer signature\n struct TokenPermissions {\n // ERC20 token address\n address token;\n // the maximum amount that can be spent\n uint256 amount;\n }\n\n /// @notice The signed permit message for a single token transfer\n struct PermitTransferFrom {\n TokenPermissions permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice Specifies the recipient address and amount for batched transfers.\n /// @dev Recipients and amounts correspond to the index of the signed token permissions array.\n /// @dev Reverts if the requested amount is greater than the permitted signed amount.\n struct SignatureTransferDetails {\n // recipient address\n address to;\n // spender requested amount\n uint256 requestedAmount;\n }\n\n /// @notice Used to reconstruct the signed permit message for multiple token transfers\n /// @dev Do not need to pass in spender address as it is required that it is msg.sender\n /// @dev Note that a user still signs over a spender address\n struct PermitBatchTransferFrom {\n // the tokens and corresponding amounts permitted for a transfer\n TokenPermissions[] permitted;\n // a unique value for every token owner's signature to prevent signature replays\n uint256 nonce;\n // deadline on the permit signature\n uint256 deadline;\n }\n\n /// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection\n /// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order\n /// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce\n /// @dev It returns a uint256 bitmap\n /// @dev The index, or wordPosition is capped at type(uint248).max\n function nonceBitmap(address, uint256) external view returns (uint256);\n\n /// @notice Transfers a token using a signed permit message\n /// @dev Reverts if the requested amount is greater than the permitted signed amount\n /// @param permit The permit data signed over by the owner\n /// @param owner The owner of the tokens to transfer\n /// @param transferDetails The spender's requested transfer details for the permitted token\n /// @param signature The signature to verify\n function permitTransferFrom(\n PermitTransferFrom memory permit,\n SignatureTransferDetails calldata transferDetails,\n address owner,\n bytes calldata signature\n ) external;\n\n /// @notice Transfers a token using a signed permit message\n /// @notice Includes extra data provided by the caller to verify signature over\n /// @dev The witness type string
},
"contracts/protocols/lending/lendingFactory/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLendingFactory } from \"../interfaces/iLendingFactory.sol\";\n\nabstract contract Events {\n /// @notice emitted when a new fToken is created\n event LogTokenCreated(address indexed token, address indexed asset, uint256 indexed count, string fTokenType);\n\n /// @notice emitted when an auth is modified by owner\n event LogSetAuth(address indexed auth, bool indexed allowed);\n\n /// @notice emitted when a deployer is modified by owner\n event LogSetDeployer(address indexed deployer, bool indexed allowed);\n\n /// @notice emitted when the creation code for an fTokenType is set\n event LogSetFTokenCreationCode(string indexed fTokenType, address indexed creationCodePointer);\n}\n"
},
"contracts/protocols/lending/lendingFactory/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { CREATE3 } from \"solmate/src/utils/CREATE3.sol\";\nimport { SSTORE2 } from \"solmate/src/utils/SSTORE2.sol\";\nimport { Owned } from \"solmate/src/auth/Owned.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\nimport { IFluidLendingFactory, IFluidLendingFactoryAdmin } from \"../interfaces/iLendingFactory.sol\";\nimport { LiquiditySlotsLink } from \"../../../libraries/liquiditySlotsLink.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\nimport { Events } from \"./events.sol\";\n\nabstract contract LendingFactoryVariables is Owned, Error, IFluidLendingFactory {\n /*//////////////////////////////////////////////////////////////\n CONSTANTS / IMMUTABLES\n //////////////////////////////////////////////////////////////*/\n\n /// @inheritdoc IFluidLendingFactory\n IFluidLiquidity public immutable LIQUIDITY;\n\n /// @dev address that is mapped to the chain native token\n address internal constant _NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /*//////////////////////////////////////////////////////////////\n STORAGE VARIABLES\n //////////////////////////////////////////////////////////////*/\n\n // ------------ storage variables from inherited contracts (Owned) come before vars here --------\n\n // ----------------------- slot 0 ---------------------------\n // address public owner;\n\n // 12 bytes empty\n\n // ----------------------- slot 1 ---------------------------\n /// @dev auths can update rewards related config at created fToken contracts.\n /// owner can add/remove auths.\n /// Owner is auth by default.\n mapping(address => uint256) internal _auths;\n\n // ----------------------- slot 2 ---------------------------\n /// @dev deployers can deploy new fTokens.\n /// owner can add/remove deployers.\n /// Owner is deployer by default.\n mapping(address => uint256) internal _deployers;\n\n // ----------------------- slot 3 ---------------------------\n /// @dev list of all created tokens.\n /// Solidity creates an automatic getter only to fetch at a certain position, so explicitly define a getter that returns all.\n address[] internal _allTokens;\n\n // ----------------------- slot 4 ---------------------------\n\n /// @dev available fTokenTypes for deployment. At least EIP2612Deposits, Permit2Deposits, NativeUnderlying.\n /// Solidity creates an automatic getter only to fetch at a certain position, so explicitly define a getter that returns all.\n string[] internal _fTokenTypes;\n\n // ----------------------- slot 5 ---------------------------\n\n /// @dev fToken creation code for each fTokenType, accessed via SSTORE2.\n /// maps keccak256(abi.encode(fTokenType)) -> SSTORE2 written creation code for the fToken contract\n mapping(bytes32 => address) internal _fTokenCreationCodePointers;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(IFluidLiquidity liquidity_, address owner_) Owned(owner_) {\n if (owner_ == address(0)) {\n // Owned does not have a zero check for owner_\n revert FluidLendingError(ErrorTypes.LendingFactory__ZeroAddress);\n }\n\n LIQUIDITY = liquidity_;\n }\n\n /// @inheritdoc IFluidLendingFactory\n function allTokens() public view returns (address[] memory) {\n return _allTokens;\n }\n\n /// @inheritdoc IFluidLendingFactory\n function fTokenTypes() public view returns (string[] memory) {\n return _fTokenTypes;\n }\n\n /// @inheritdoc IFluidLendingFactory\n function fTokenCreationCode(string memory fTokenType_) public view returns (bytes memory) {\n
},
"contracts/protocols/lending/lendingRewardsRateModel/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLendingRewardsRateModel } from \"../interfaces/iLendingRewardsRateModel.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\n\n/// @title LendingRewardsRateModel\n/// @notice Calculates rewards rate used for an fToken based on a rewardAmount over a given duration. \n/// Rewards start once the allowed initiator address triggers `start()` and only accrue above a certain startTVL.\n/// Max rate cap is at 50%.\ncontract FluidLendingRewardsRateModel is IFluidLendingRewardsRateModel, Error {\n /// @notice Emitted when rewards are started\n event LogRewardsStarted(uint256 startTime, uint256 endTime);\n\n /// @dev precision decimals for rewards rate\n uint256 internal constant RATE_PRECISION = 1e12;\n\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\n\n /// @dev maximum rewards rate is 50%. no config higher than this should be possible.\n uint256 internal constant MAX_RATE = 50 * RATE_PRECISION; // 1e12 = 1%, this is 50%.\n\n /// @dev tvl below which rewards rate is 0\n uint256 internal immutable START_TVL;\n\n /// @dev for how long rewards should run\n uint256 internal immutable DURATION;\n\n /// @dev annualized reward based on constructor input params (duration, rewardAmount)\n uint256 internal immutable YEARLY_REWARD;\n\n /// @dev total amounts to be distributed. not needed but stored for easier tracking via `getConfig`\n uint256 internal immutable REWARD_AMOUNT;\n\n /// @dev address which has access to call start() which kickstarts the rewards\n address internal immutable INITIATOR;\n\n /// @dev when rewards got started\n uint96 internal startTime;\n /// @dev when rewards will get over\n uint96 internal endTime;\n\n /// @dev Validates that an address is not the zero address\n modifier validAddress(address value_) {\n if (value_ == address(0)) {\n revert FluidLendingError(ErrorTypes.LendingRewardsRateModel__ZeroAddress);\n }\n _;\n }\n\n /// @notice sets immutable vars for rewards rate config based on input params.\n /// @param duration_ for how long rewards should run\n /// @param startTvl_ tvl below which rate is 0\n /// @param rewardAmount_ total amount of underlying asset to be distributed as rewards\n /// @param initiator_ address which has access to kickstart the rewards\n constructor(uint256 duration_, uint256 startTvl_, uint256 rewardAmount_, address initiator_) validAddress(initiator_) {\n // sanity checks\n if (duration_ == 0 || rewardAmount_ == 0 || startTvl_ == 0) {\n revert FluidLendingError(ErrorTypes.LendingRewardsRateModel__InvalidParams);\n }\n\n START_TVL = startTvl_;\n DURATION = duration_;\n REWARD_AMOUNT = rewardAmount_;\n INITIATOR = initiator_;\n\n YEARLY_REWARD = (rewardAmount_ * SECONDS_PER_YEAR) / DURATION;\n }\n\n /// @inheritdoc IFluidLendingRewardsRateModel\n function getConfig()\n external\n view\n returns (\n uint256 duration_,\n uint256 startTime_,\n uint256 endTime_,\n uint256 startTvl_,\n uint256 maxRate_,\n uint256 rewardAmount_,\n address initiator_\n )\n {\n return (DURATION, startTime, endTime, START_TVL, MAX_RATE, REWARD_AMOUNT, INITIATOR);\n }\n\n /// @inheritdoc IFluidLendingRewardsRateModel\n function getRate(uint256 totalAssets_) public view returns (uint256 rate_, bool ended_, uint256 startTime_) {\n startTime_ = startTime;\n uint endTime_ = endTime;\n if (startTime_ == 0 || endTime_ == 0) {\n return (0, false, startTime_);\n }\n if (block.timestamp > endTime_) {\n return (0, true, startTime_);\n }\n if (block.timestamp < startTime_) {\n return (0, false, startTime_);\n }\n if (totalAssets_ < START_TVL) {\n
},
"contracts/protocols/lending/stakingRewards/main.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport { IERC20Permit } from \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\nimport { Owned } from \"solmate/src/auth/Owned.sol\";\n\n// Adapted from https://github.com/Uniswap/liquidity-staker/blob/master/contracts/StakingRewards.sol\ncontract FluidLendingStakingRewards is Owned, ReentrancyGuard {\n using SafeERC20 for IERC20;\n\n IERC20 public immutable rewardsToken; // should be INST\n IERC20 public immutable stakingToken; // should be fToken\n uint256 public immutable rewardsDuration; // e.g. 60 days\n\n /* ========== STATE VARIABLES ========== */\n\n // Owned and ReentranyGuard storage variables before\n\n uint256 public periodFinish;\n uint256 public rewardRate;\n uint256 public lastUpdateTime;\n uint256 public rewardPerTokenStored;\n\n mapping(address => uint256) public userRewardPerTokenPaid;\n mapping(address => uint256) public rewards;\n\n uint256 private _totalSupply;\n mapping(address => uint256) private _balances;\n\n /* ========== CONSTRUCTOR ========== */\n\n constructor(address _owner, IERC20 _rewardsToken, IERC20 _stakingToken, uint256 _rewardsDuration) Owned(_owner) {\n require(address(_rewardsToken) != address(0), \"Invalid params\");\n require(address(_stakingToken) != address(0), \"Invalid params\");\n require(_owner != address(0), \"Invalid params\"); // Owned does not have a zero check for owner_\n require(_rewardsDuration > 0, \"Invalid params\");\n\n rewardsToken = _rewardsToken;\n stakingToken = _stakingToken;\n rewardsDuration = _rewardsDuration;\n }\n\n /* ========== VIEWS ========== */\n\n function totalSupply() external view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address account) external view returns (uint256) {\n return _balances[account];\n }\n\n function lastTimeRewardApplicable() public view returns (uint256) {\n return block.timestamp < periodFinish ? block.timestamp : periodFinish;\n }\n\n function rewardPerToken() public view returns (uint256) {\n if (_totalSupply == 0) {\n return rewardPerTokenStored;\n }\n return\n rewardPerTokenStored + (((lastTimeRewardApplicable() - lastUpdateTime) * rewardRate * 1e18) / _totalSupply);\n }\n\n function earned(address account) public view returns (uint256) {\n return (_balances[account] * (rewardPerToken() - userRewardPerTokenPaid[account])) / 1e18 + rewards[account];\n }\n\n function getRewardForDuration() external view returns (uint256) {\n return rewardRate * rewardsDuration;\n }\n\n /* ========== MUTATIVE FUNCTIONS ========== */\n\n function stakeWithPermit(\n uint256 amount,\n uint deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external nonReentrant updateReward(msg.sender) {\n require(amount > 0, \"Cannot stake 0\");\n\n // permit\n IERC20Permit(address(stakingToken)).permit(msg.sender, address(this), amount, deadline, v, r, s);\n\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\n\n _totalSupply = _totalSupply + amount;\n _balances[msg.sender] = _balances[msg.sender] + amount;\n\n emit Staked(msg.sender, amount);\n }\n\n function stake(uint256 amount) external nonReentrant updateReward(msg.sender) {\n require(amount > 0, \"Cannot stake 0\");\n\n stakingToken.safeTransferFrom(msg.sender, address(this), amount);\n\n _totalSupply = _totalSupply + amount;\n _balances[msg.sender] = _balances[msg.sender] + amount;\n\n emit Staked(msg.sender, amount);\n }\n\n function withdraw(uint256 amoun
},
"contracts/protocols/steth/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Error {\n /// @notice general Custom error used for all contract specific errors with the `errorId_` param as error code.\n /// Look up the specific error code in the source code to find a better explanation of what went wrong (errors.sol).\n error StETHQueueError(uint256 errorId_);\n}\n"
},
"contracts/protocols/steth/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | StETH | \n |__________________________________*/\n\n /// @notice thrown when maxLTV precent amount is set to 0\n uint256 internal constant StETH__MaxLTVZero = 40001;\n\n /// @notice thrown when the borrow ETH amount to StETH collateral ratio is bigger than the configured `maxLTV`\n uint256 internal constant StETH__MaxLTV = 40002;\n\n /// @notice thrown when an ERC721 other than a Lido Withdrawal NFT is transferred to this contract\n uint256 internal constant StETH__InvalidERC721Transfer = 40003;\n\n /// @notice thrown when an input amount (ethBorrowAmount or stETHAmount) is zero\n uint256 internal constant StETH__InputAmountZero = 40004;\n\n /// @notice thrown when Lido requestIds return empty.\n uint256 internal constant StETH__RequestIdsEmpty = 40005;\n\n /// @notice thrown when `liquidityCallback` is called, as this protocol only uses native token as borrow asset\n uint256 internal constant StETH__UnexpectedLiquidityCallback = 40006;\n\n /// @notice thrown when there is no claim queued for a claim owner\n uint256 internal constant StETH__NoClaimQueued = 40007;\n\n /// @notice thrown when an unauthorized `msg.sender` calls a protected method\n uint256 internal constant StETH__Unauthorized = 40008;\n\n /// @notice thrown when the borrowAmountRaw is rounded to zero because of the exchange price\n uint256 internal constant StETH__BorrowAmountRawRoundingZero = 40009;\n\n /// @notice thrown when an input address is zero\n uint256 internal constant StETH__AddressZero = 40010;\n\n /// @notice thrown when a reentrancy happens\n uint256 internal constant StETH__Reentrancy = 40011;\n\n /// @notice thrown when maxLTV precent amount is set to >= 100%\n uint256 internal constant StETH__MaxLTVAboveCap = 40012;\n\n /// @notice thrown when renounceOwnership is called\n uint256 internal constant StETH__RenounceOwnershipUnsupported = 40013;\n}\n"
},
"contracts/protocols/steth/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Events {\n /// @notice emitted whenever `maxLTV` is updated\n event LogSetMaxLTV(uint256 indexed maxLTV);\n\n /// @notice emitted when a queue() process is executed\n event LogQueue(\n address indexed claimTo,\n uint256 indexed requestIdFrom,\n uint256 indexed borrowETHAmount,\n uint256 queueStETHAmount,\n address borrowTo\n );\n\n /// @notice emitted when a claim() process is executed\n event LogClaim(\n address indexed claimTo,\n uint256 indexed requestIdFrom,\n uint256 claimedAmount,\n uint256 indexed repayAmount\n );\n\n /// @notice emitted when an auth is modified by owner\n event LogSetAuth(address indexed auth, bool indexed allowed);\n}\n"
},
"contracts/protocols/steth/interfaces/external/iLidoWithdrawalQueue.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface ILidoWithdrawalQueue {\n function balanceOf(address) external view returns (uint);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n // code below based on Lido WithdrawalQueueBase.sol\n // see https://github.com/lidofinance/lido-dao/blob/v2.0.0/contracts/0.8.9/WithdrawalQueueBase.sol\n\n /// @notice output format struct for `_getWithdrawalStatus()` method\n struct WithdrawalRequestStatus {\n /// @notice stETH token amount that was locked on withdrawal queue for this request\n uint256 amountOfStETH;\n /// @notice amount of stETH shares locked on withdrawal queue for this request\n uint256 amountOfShares;\n /// @notice address that can claim or transfer this request\n address owner;\n /// @notice timestamp of when the request was created, in seconds\n uint256 timestamp;\n /// @notice true, if request is finalized\n bool isFinalized;\n /// @notice true, if request is claimed. Request is claimable if (isFinalized && !isClaimed)\n bool isClaimed;\n }\n\n /// @notice length of the checkpoint array. Last possible value for the hint.\n /// NB! checkpoints are indexed from 1, so it returns 0 if there is no checkpoints\n function getLastCheckpointIndex() external view returns (uint256);\n\n // code below based on Lido WithdrawalQueue.sol\n // see https://github.com/lidofinance/lido-dao/blob/v2.0.0/contracts/0.8.9/WithdrawalQueue.sol\n\n /// @notice Request the batch of stETH for withdrawal. Approvals for the passed amounts should be done before.\n /// @param _amounts an array of stETH amount values.\n /// The standalone withdrawal request will be created for each item in the passed list.\n /// @param _owner address that will be able to manage the created requests.\n /// If `address(0)` is passed, `msg.sender` will be used as owner.\n /// @return requestIds an array of the created withdrawal request ids\n function requestWithdrawals(\n uint256[] calldata _amounts,\n address _owner\n ) external returns (uint256[] memory requestIds);\n\n /// @notice Claim one`_requestId` request once finalized sending locked ether to the owner\n /// @param _requestId request id to claim\n /// @dev use unbounded loop to find a hint, which can lead to OOG\n /// @dev\n /// Reverts if requestId or hint are not valid\n /// Reverts if request is not finalized or already claimed\n /// Reverts if msg sender is not an owner of request\n function claimWithdrawal(uint256 _requestId) external;\n\n /// @notice Claim a batch of withdrawal requests if they are finalized sending locked ether to the owner\n /// @param _requestIds array of request ids to claim\n /// @param _hints checkpoint hint for each id. Can be obtained with `findCheckpointHints()`\n /// @dev\n /// Reverts if requestIds and hints arrays length differs\n /// Reverts if any requestId or hint in arguments are not valid\n /// Reverts if any request is not finalized or already claimed\n /// Reverts if msg sender is not an owner of the requests\n function claimWithdrawals(uint256[] calldata _requestIds, uint256[] calldata _hints) external;\n\n //// @notice Returns all withdrawal requests that belongs to the `_owner` address\n ///\n /// WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n /// to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n /// this function has an unbounded cost, and using it as part of a state-changing function may render the function\n /// uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n function getWithdrawalRequ
},
"contracts/protocols/steth/interfaces/iStETHQueue.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport { Structs } from \"../structs.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\nimport { ILidoWithdrawalQueue } from \"../interfaces/external/iLidoWithdrawalQueue.sol\";\n\ninterface IFluidStETHQueue {\n /// @notice returns the constant values for LIQUIDITY, LIDO_WITHDRAWAL_QUEUE, STETH\n function constantsView() external view returns (IFluidLiquidity, ILidoWithdrawalQueue, IERC20);\n\n /// @notice gets an open Claim for `claimTo_` and `requestIdFrom_`\n function claims(address claimTo_, uint256 requestIdFrom_) external view returns (Structs.Claim memory);\n}\n"
},
"contracts/protocols/steth/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\n\nimport { ILidoWithdrawalQueue } from \"./interfaces/external/iLidoWithdrawalQueue.sol\";\nimport { IFluidLiquidity } from \"../../liquidity/interfaces/iLiquidity.sol\";\nimport { ErrorTypes } from \"./errorTypes.sol\";\nimport { Error } from \"./error.sol\";\nimport { Events } from \"./events.sol\";\nimport { Variables } from \"./variables.sol\";\nimport { LiquidityCalcs } from \"../../libraries/liquidityCalcs.sol\";\n\nabstract contract StETHQueueCore is Variables, Events, Error {\n /// @dev validates that an address is not the zero address\n modifier validAddress(address value_) {\n if (value_ == address(0)) {\n revert StETHQueueError(ErrorTypes.StETH__AddressZero);\n }\n _;\n }\n\n /// @dev reads the current, updated borrow exchange price for Native ETH at Liquidity\n function _getLiquidityExchangePrice() internal view returns (uint256 borrowExchangePrice_) {\n (, borrowExchangePrice_) = LiquidityCalcs.calcExchangePrices(\n LIQUIDITY.readFromStorage(LIQUIDITY_EXCHANGE_PRICES_SLOT)\n );\n }\n}\n\n/// @dev ReentrancyGuard based on OpenZeppelin implementation.\n/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.8/contracts/security/ReentrancyGuard.sol\nabstract contract ReentrancyGuard is StETHQueueCore {\n uint8 internal constant REENTRANCY_NOT_ENTERED = 1;\n uint8 internal constant REENTRANCY_ENTERED = 2;\n\n constructor() {\n _status = REENTRANCY_NOT_ENTERED;\n }\n\n /// @dev Prevents a contract from calling itself, directly or indirectly.\n /// See OpenZeppelin implementation for more info\n modifier nonReentrant() {\n // On the first call to nonReentrant, _status will be NOT_ENTERED\n if (_status != REENTRANCY_NOT_ENTERED) {\n revert StETHQueueError(ErrorTypes.StETH__Reentrancy);\n }\n\n // Any calls to nonReentrant after this point will fail\n _status = REENTRANCY_ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = REENTRANCY_NOT_ENTERED;\n }\n}\n\n/// @dev FluidStETHQueue admin related methods to set allowed auths / config for maxLTV.\nabstract contract StETHQueueAdmin is Variables, StETHQueueCore {\n /// @dev only auths guard\n modifier onlyAuths() {\n if (!isAuth(msg.sender)) {\n revert StETHQueueError(ErrorTypes.StETH__Unauthorized);\n }\n _;\n }\n\n /// @notice reads if a certain `auth_` address is an allowed auth or not\n function isAuth(address auth_) public view returns (bool) {\n return auth_ == owner() || _auths[auth_] == 1;\n }\n\n /// @notice Sets an address as allowed auth or not. Only callable by owner.\n /// @param auth_ address to set auth value for\n /// @param allowed_ bool flag for whether address is allowed as auth or not\n function setAuth(address auth_, bool allowed_) external onlyOwner validAddress(auth_) {\n _auths[auth_] = allowed_ ? 1 : 0;\n\n emit LogSetAuth(auth_, allowed_);\n }\n\n /// @notice Sets `maxLTV` to `maxLTV_` (in 1e2: 1% = 100, 100% = 10000). Must be > 0 and < 100%.\n function setMaxLTV(uint16 maxLTV_) external onlyAuths {\n if (maxLTV_ == 0) {\n revert StETHQueueError(ErrorTypes.StETH__MaxLTVZero);\n }\n if (maxLTV_ >= HUNDRED_PERCENT) {\n revert StETHQueueError(ErrorTypes.StETH__MaxLTVAboveCap);\n }\n\n maxLTV = maxLTV_;\n emit LogSetMaxLTV(maxLTV_);\n }\n
},
"contracts/protocols/steth/proxy.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { ERC1967Proxy } from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/// @title FluidStETHQueueProxy\n/// @notice Default ERC1967Proxy for StETHQueue\ncontract FluidStETHQueueProxy is ERC1967Proxy {\n constructor(address logic_, bytes memory data_) payable ERC1967Proxy(logic_, data_) {}\n}\n"
},
"contracts/protocols/steth/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Structs {\n /// @notice Claim data struct for storage link to owner address\n struct Claim {\n /// @param borrowAmountRaw raw borrow amount at Liquidity. Multiply with borrowExchangePrice to get normal borrow amount\n uint128 borrowAmountRaw;\n /// @param checkpoint checkpoint at time of queue. optimizes finding checkpoint hints range at claim time.\n uint48 checkpoint;\n /// @param requestIdTo last request Id linked to the claim\n uint40 requestIdTo;\n // 5 bytes empty\n }\n}\n"
},
"contracts/protocols/steth/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nimport { LiquiditySlotsLink } from \"../../libraries/liquiditySlotsLink.sol\";\nimport { IFluidLiquidity } from \"../../liquidity/interfaces/iLiquidity.sol\";\nimport { ILidoWithdrawalQueue } from \"./interfaces/external/iLidoWithdrawalQueue.sol\";\nimport { Structs } from \"./structs.sol\";\n\nabstract contract Constants {\n /// @dev hundred percent at 1e2 precision\n uint256 internal constant HUNDRED_PERCENT = 1e4;\n\n /// @dev precision for exchange prices in Liquidity\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n\n /// @dev address that is mapped to the chain native token at Liquidity\n address internal constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /// @notice address of the Liquidity contract.\n IFluidLiquidity internal immutable LIQUIDITY;\n\n /// @notice address of the Lido Withdrawal Queue contract (0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1)\n ILidoWithdrawalQueue internal immutable LIDO_WITHDRAWAL_QUEUE;\n\n /// @notice address of the StETH contract.\n IERC20 internal immutable STETH;\n\n /// @dev maximum amount of stETH that is possible to withdraw by a single request at Lido (should be 1_000 stETH).\n /// see https://github.com/lidofinance/lido-dao/blob/v2.0.0/contracts/0.8.9/WithdrawalQueue.sol#L57.\n /// stored here to optimize gas usage\n uint256 internal immutable MAX_STETH_WITHDRAWAL_AMOUNT;\n\n /// @dev minimum amount of stETH that is possible to withdraw by a single request at Lido (should be 100 wei).\n /// see https://github.com/lidofinance/lido-dao/blob/v2.0.0/contracts/0.8.9/WithdrawalQueue.sol#L52.\n /// stored here to optimize gas usage\n uint256 internal immutable MIN_STETH_WITHDRAWAL_AMOUNT;\n\n /// @dev slot ids in Liquidity contract for exchange prices and total amounts storage slots\n /// for token NATIVE_TOKEN_ADDRESS. Both are required to calculated updated borrow exchange price.\n /// Helps in low gas fetch from liquidity contract by skipping delegate call with `readFromStorage`\n bytes32 internal immutable LIQUIDITY_EXCHANGE_PRICES_SLOT;\n bytes32 internal immutable LIQUIDITY_TOTAL_AMOUNTS_SLOT;\n\n constructor(IFluidLiquidity liquidity_, ILidoWithdrawalQueue lidoWithdrawalQueue_, IERC20 stETH_) {\n LIQUIDITY = liquidity_;\n\n LIDO_WITHDRAWAL_QUEUE = lidoWithdrawalQueue_;\n MAX_STETH_WITHDRAWAL_AMOUNT = lidoWithdrawalQueue_.MAX_STETH_WITHDRAWAL_AMOUNT();\n MIN_STETH_WITHDRAWAL_AMOUNT = lidoWithdrawalQueue_.MIN_STETH_WITHDRAWAL_AMOUNT();\n\n STETH = stETH_;\n\n LIQUIDITY_EXCHANGE_PRICES_SLOT = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n NATIVE_TOKEN_ADDRESS\n );\n LIQUIDITY_TOTAL_AMOUNTS_SLOT = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_TOTAL_AMOUNTS_MAPPING_SLOT,\n NATIVE_TOKEN_ADDRESS\n );\n }\n\n /// @notice returns the constant values for LIQUIDITY, LIDO_WITHDRAWAL_QUEUE, STETH\n function constantsView() external view returns (IFluidLiquidity, ILidoWithdrawalQueue, IERC20) {\n return (LIQUIDITY, LIDO_WITHDRAWAL_QUEUE, STETH);\n }\n}\n\nabstract contract Variables is Initializable, OwnableUpgradeable, Constants, Structs {\n // ------------ storage variables from inherited contracts (Initializable, OwnableUpgradeable) come before vars here --------\n // @dev variables here start at storage slot 101, before is:\n // - Initializable with storage slot 0:\n // uint8 private _initialized;\n // bool private _initializing;\n // - OwnableUpgradeable with slots
},
"contracts/protocols/vault/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Error {\n error FluidVaultError(uint256 errorId_);\n\n /// @notice used to simulate liquidation to find the maximum liquidatable amounts\n error FluidLiquidateResult(uint256 colLiquidated, uint256 debtLiquidated);\n}\n"
},
"contracts/protocols/vault/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | Vault Factory | \n |__________________________________*/\n\n uint256 internal constant VaultFactory__InvalidOperation = 30001;\n uint256 internal constant VaultFactory__Unauthorized = 30002;\n uint256 internal constant VaultFactory__SameTokenNotAllowed = 30003;\n uint256 internal constant VaultFactory__InvalidParams = 30004;\n uint256 internal constant VaultFactory__InvalidVault = 30005;\n uint256 internal constant VaultFactory__InvalidVaultAddress = 30006;\n uint256 internal constant VaultFactory__OnlyDelegateCallAllowed = 30007;\n\n /***********************************|\n | VaultT1 | \n |__________________________________*/\n\n /// @notice thrown at reentrancy\n uint256 internal constant VaultT1__AlreadyEntered = 31001;\n\n /// @notice thrown when user sends deposit & borrow amount as 0\n uint256 internal constant VaultT1__InvalidOperateAmount = 31002;\n\n /// @notice thrown when msg.value is not in sync with native token deposit or payback\n uint256 internal constant VaultT1__InvalidMsgValueOperate = 31003;\n\n /// @notice thrown when msg.sender is not the owner of the vault\n uint256 internal constant VaultT1__NotAnOwner = 31004;\n\n /// @notice thrown when user's position does not exist. Sending the wrong index from the frontend\n uint256 internal constant VaultT1__TickIsEmpty = 31005;\n\n /// @notice thrown when the user's position is above CF and the user tries to make it more risky by trying to withdraw or borrow\n uint256 internal constant VaultT1__PositionAboveCF = 31006;\n\n /// @notice thrown when the top tick is not initialized. Happens if the vault is totally new or all the user's left\n uint256 internal constant VaultT1__TopTickDoesNotExist = 31007;\n\n /// @notice thrown when msg.value in liquidate is not in sync payback\n uint256 internal constant VaultT1__InvalidMsgValueLiquidate = 31008;\n\n /// @notice thrown when slippage is more on liquidation than what the liquidator sent\n uint256 internal constant VaultT1__ExcessSlippageLiquidation = 31009;\n\n /// @notice thrown when msg.sender is not the rebalancer/reserve contract\n uint256 internal constant VaultT1__NotRebalancer = 31010;\n\n /// @notice thrown when NFT of one vault interacts with the NFT of other vault\n uint256 internal constant VaultT1__NftNotOfThisVault = 31011;\n\n /// @notice thrown when the token is not initialized on the liquidity contract\n uint256 internal constant VaultT1__TokenNotInitialized = 31012;\n\n /// @notice thrown when admin updates fallback if a non-auth calls vault\n uint256 internal constant VaultT1__NotAnAuth = 31013;\n\n /// @notice thrown in operate when user tries to witdhraw more collateral than deposited\n uint256 internal constant VaultT1__ExcessCollateralWithdrawal = 31014;\n\n /// @notice thrown in operate when user tries to payback more debt than borrowed\n uint256 internal constant VaultT1__ExcessDebtPayback = 31015;\n\n /// @notice thrown when user try to withdrawal more than operate's withdrawal limit\n uint256 internal constant VaultT1__WithdrawMoreThanOperateLimit = 31016;\n\n /// @notice thrown when caller of liquidityCallback is not Liquidity\n uint256 internal constant VaultT1__InvalidLiquidityCallbackAddress = 31017;\n\n /// @notice thrown when reentrancy is not already on\n uint256 internal constant VaultT1__NotEntered = 31018;\n\n /// @notice thrown when someone directly calls secondary implementation contract\n uint256 internal constant VaultT1__OnlyDelegateCallAllowed = 31019;\n\n /// @notice thrown when the safeTransferFrom for a token amount failed\n uint256 internal constant VaultT1__TransferFromFailed = 31020;\n\n /// @notice thrown when exchange price overflows while updating on storage\n uint256 internal constant VaultT1__ExchangePriceOv
},
"contracts/protocols/vault/factory/deploymentLogics/vaultT1Logic.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { SSTORE2 } from \"solmate/src/utils/SSTORE2.sol\";\n\nimport { ErrorTypes } from \"../../errorTypes.sol\";\nimport { Error } from \"../../error.sol\";\nimport { IFluidVaultFactory } from \"../../interfaces/iVaultFactory.sol\";\n\nimport { LiquiditySlotsLink } from \"../../../../libraries/liquiditySlotsLink.sol\";\n\nimport { IFluidVaultT1 } from \"../../interfaces/iVaultT1.sol\";\nimport { FluidVaultT1 } from \"../../vaultT1/coreModule/main.sol\";\n\ninterface IERC20 {\n function decimals() external view returns (uint8);\n}\n\ncontract FluidVaultT1DeploymentLogic is Error {\n address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n /// @notice SSTORE2 pointer for the VaultT1 creation code. Stored externally to reduce factory bytecode\n address public immutable VAULT_T1_CREATIONCODE_ADDRESS;\n\n /// @notice address of liquidity contract\n address public immutable LIQUIDITY;\n\n /// @notice address of Admin implementation\n address public immutable ADMIN_IMPLEMENTATION;\n\n /// @notice address of Secondary implementation\n address public immutable SECONDARY_IMPLEMENTATION;\n\n /// @notice address of this contract\n address public immutable ADDRESS_THIS;\n\n /// @notice Emitted when a new vaultT1 is deployed.\n /// @param vault The address of the newly deployed vault.\n /// @param vaultId The id of the newly deployed vault.\n /// @param supplyToken The address of the supply token.\n /// @param borrowToken The address of the borrow token.\n event VaultT1Deployed(\n address indexed vault,\n uint256 vaultId,\n address indexed supplyToken,\n address indexed borrowToken\n );\n\n constructor(address liquidity_, address vaultAdminImplementation_, address vaultSecondaryImplementation_) {\n LIQUIDITY = liquidity_;\n ADMIN_IMPLEMENTATION = vaultAdminImplementation_;\n SECONDARY_IMPLEMENTATION = vaultSecondaryImplementation_;\n VAULT_T1_CREATIONCODE_ADDRESS = SSTORE2.write(type(FluidVaultT1).creationCode);\n ADDRESS_THIS = address(this);\n }\n\n /// @dev Calculates the liquidity vault slots for the given supply token, borrow token, and vault (`vault_`).\n /// @param constants_ Constants struct as used in Vault T1\n /// @param vault_ The address of the vault.\n /// @return liquidityVaultSlots_ Returns the calculated liquidity vault slots set in the `IFluidVaultT1.ConstantViews` struct.\n function _calculateLiquidityVaultSlots(\n IFluidVaultT1.ConstantViews memory constants_,\n address vault_\n ) private pure returns (IFluidVaultT1.ConstantViews memory) {\n constants_.liquiditySupplyExchangePriceSlot = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n constants_.supplyToken\n );\n constants_.liquidityBorrowExchangePriceSlot = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n constants_.borrowToken\n );\n constants_.liquidityUserSupplySlot = LiquiditySlotsLink.calculateDoubleMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_USER_SUPPLY_DOUBLE_MAPPING_SLOT,\n vault_,\n constants_.supplyToken\n );\n constants_.liquidityUserBorrowSlot = LiquiditySlotsLink.calculateDoubleMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_USER_BORROW_DOUBLE_MAPPING_SLOT,\n vault_,\n constants_.borrowToken\n );\n return constants_;\n }\n\n /// @notice Computes vaultT1 bytecode for the given supply token (`supplyToken_`) and borrow token (`borrowToken_`).\n /// This will be called by the VaultFactory via .delegateCall\n /// @param supplyToken_ The address
},
"contracts/protocols/vault/factory/ERC721/ERC721.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { ErrorTypes } from \"../../errorTypes.sol\";\nimport { Error } from \"../../error.sol\";\n\n/// @notice Fluid Vault Factory ERC721 base contract. Implements the ERC721 standard, based on Solmate.\n/// In addition, implements ERC721 Enumerable.\n/// Modern, minimalist, and gas efficient ERC-721 with Enumerable implementation.\n///\n/// @author Instadapp\n/// @author Modified Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 is Error {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n // token id => token config\n // uint160 0 - 159: address:: owner\n // uint32 160 - 191: uint32:: index\n // uint32 192 - 223: uint32:: vaultId\n // uint32 224 - 255: uint32:: null\n mapping(uint256 => uint256) internal _tokenConfig;\n\n // owner => slot => index\n /*\n // slot 0: \n // uint32 0 - 31: uint32:: balanceOf\n // uint224 32 - 255: 7 tokenIds each of uint32 packed\n // slot N (N >= 1)\n // uint32 * 8 each tokenId\n */\n mapping(address => mapping(uint256 => uint256)) internal _ownerConfig;\n\n /// @notice returns `owner_` of NFT with `id_`\n function ownerOf(uint256 id_) public view virtual returns (address owner_) {\n if ((owner_ = address(uint160(_tokenConfig[id_]))) == address(0))\n revert FluidVaultError(ErrorTypes.ERC721__InvalidParams);\n }\n\n /// @notice returns total count of NFTs owned by `owner_`\n function balanceOf(address owner_) public view virtual returns (uint256) {\n if (owner_ == address(0)) revert FluidVaultError(ErrorTypes.ERC721__InvalidParams);\n\n return _ownerConfig[owner_][0] & type(uint32).max;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721Enumerable STORAGE\n //////////////////////////////////////////////////////////////*/\n\n /// @notice total amount of tokens stored by the contract.\n uint256 public totalSupply;\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n /// @notice trackes if a NFT id is approved for a certain address.\n mapping(uint256 => address) public getApproved;\n\n /// @notice trackes if all the NFTs of an owner are approved for a certain other address.\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n /// @notice approves an NFT with `id_` to be spent (transferred) by `spender_`\n function approve(a
},
"contracts/protocols/vault/factory/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Owned } from \"solmate/src/auth/Owned.sol\";\nimport { ERC721 } from \"./ERC721/ERC721.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\n\nimport { StorageRead } from \"../../../libraries/storageRead.sol\";\n\nabstract contract VaultFactoryVariables is Owned, ERC721, StorageRead {\n /// @dev ERC721 tokens name\n string internal constant ERC721_NAME = \"Fluid Vault\";\n /// @dev ERC721 tokens symbol\n string internal constant ERC721_SYMBOL = \"fVLT\";\n\n /*//////////////////////////////////////////////////////////////\n STORAGE VARIABLES\n //////////////////////////////////////////////////////////////*/\n\n // ------------ storage variables from inherited contracts (Owned and ERC721) come before vars here --------\n\n // ----------------------- slot 0 ---------------------------\n // address public owner; // from Owned\n\n // 12 bytes empty\n\n // ----------------------- slot 1 ---------------------------\n // string public name;\n\n // ----------------------- slot 2 ---------------------------\n // string public symbol;\n\n // ----------------------- slot 3 ---------------------------\n // mapping(uint256 => uint256) internal _tokenConfig;\n\n // ----------------------- slot 4 ---------------------------\n // mapping(address => mapping(uint256 => uint256)) internal _ownerConfig;\n\n // ----------------------- slot 5 ---------------------------\n // uint256 public totalSupply;\n\n // ----------------------- slot 6 ---------------------------\n // mapping(uint256 => address) public getApproved;\n\n // ----------------------- slot 7 ---------------------------\n // mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n // ----------------------- slot 8 ---------------------------\n /// @dev deployer can deploy new Vault contract\n /// owner can add/remove deployer.\n /// Owner is deployer by default.\n mapping(address => bool) internal _deployers;\n\n // ----------------------- slot 9 ---------------------------\n /// @dev global auths can update any vault config.\n /// owner can add/remove global auths.\n /// Owner is global auth by default.\n mapping(address => bool) internal _globalAuths;\n\n // ----------------------- slot 10 ---------------------------\n /// @dev vault auths can update specific vault config.\n /// owner can add/remove vault auths.\n /// Owner is vault auth by default.\n /// vault => auth => add/remove\n mapping(address => mapping(address => bool)) internal _vaultAuths;\n\n // ----------------------- slot 11 ---------------------------\n /// @dev total no of vaults deployed by the factory\n /// only addresses that have deployer role or owner can deploy new vault.\n uint256 internal _totalVaults;\n\n // ----------------------- slot 12 ---------------------------\n /// @dev vault deployment logics for deploying vault\n /// These logic contracts hold the deployment logics of specific vaults and are called via .delegatecall inside deployVault().\n /// only addresses that have owner can add/remove new vault deployment logic.\n mapping(address => bool) internal _vaultDeploymentLogics;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n constructor(address owner_) Owned(owner_) ERC721(ERC721_NAME, ERC721_SYMBOL) {}\n}\n\nabstract contract VaultFactoryEvents {\n /// @dev Emitted when a new vault is deployed.\n /// @param vault The address of the newly deployed vault.\n /// @param vaultId The id of the newly deployed vault.\n event VaultDeployed(address indexed vault, uint256 indexed vaultId);\n\n /// @dev Emitted when a new token/position is minted by a vault.\n /// @param vault The address of the vault that minted the token.\n /// @param user The address of the user
},
"contracts/protocols/vault/interfaces/iVaultFactory.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { IERC721Enumerable } from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\";\n\ninterface IFluidVaultFactory is IERC721Enumerable {\n /// @notice Minting an NFT Vault for the user\n function mint(uint256 vaultId_, address user_) external returns (uint256 tokenId_);\n\n /// @notice returns owner of Vault which is also an NFT\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /// @notice Global auth is auth for all vaults\n function isGlobalAuth(address auth_) external view returns (bool);\n\n /// @notice Vault auth is auth for a specific vault\n function isVaultAuth(address auth_, address vault_) external view returns (bool);\n\n /// @notice Total vaults deployed.\n function totalVaults() external view returns (uint256);\n\n /// @notice Compute vaultAddress\n function getVaultAddress(uint256 vaultId) external view returns (address);\n\n /// @notice read uint256 `result_` for a storage `slot_` key\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\n}\n"
},
"contracts/protocols/vault/interfaces/iVaultT1.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\ninterface IFluidVaultT1 {\n /// @notice returns the vault id\n function VAULT_ID() external view returns (uint256);\n\n /// @notice reads uint256 data `result_` from storage at a bytes32 storage `slot_` key.\n function readFromStorage(bytes32 slot_) external view returns (uint256 result_);\n\n struct ConstantViews {\n address liquidity;\n address factory;\n address adminImplementation;\n address secondaryImplementation;\n address supplyToken;\n address borrowToken;\n uint8 supplyDecimals;\n uint8 borrowDecimals;\n uint vaultId;\n bytes32 liquiditySupplyExchangePriceSlot;\n bytes32 liquidityBorrowExchangePriceSlot;\n bytes32 liquidityUserSupplySlot;\n bytes32 liquidityUserBorrowSlot;\n }\n\n /// @notice returns all Vault constants\n function constantsView() external view returns (ConstantViews memory constantsView_);\n\n /// @notice fetches the latest user position after a liquidation\n function fetchLatestPosition(\n int256 positionTick_,\n uint256 positionTickId_,\n uint256 positionRawDebt_,\n uint256 tickData_\n )\n external\n view\n returns (\n int256, // tick\n uint256, // raw debt\n uint256, // raw collateral\n uint256, // branchID_\n uint256 // branchData_\n );\n\n /// @notice calculates the updated vault exchange prices\n function updateExchangePrices(\n uint256 vaultVariables2_\n )\n external\n view\n returns (\n uint256 liqSupplyExPrice_,\n uint256 liqBorrowExPrice_,\n uint256 vaultSupplyExPrice_,\n uint256 vaultBorrowExPrice_\n );\n\n /// @notice calculates the updated vault exchange prices and writes them to storage\n function updateExchangePricesOnStorage()\n external\n returns (\n uint256 liqSupplyExPrice_,\n uint256 liqBorrowExPrice_,\n uint256 vaultSupplyExPrice_,\n uint256 vaultBorrowExPrice_\n );\n\n /// @notice returns the liquidity contract address\n function LIQUIDITY() external view returns (address);\n\n function operate(\n uint256 nftId_, // if 0 then new position\n int256 newCol_, // if negative then withdraw\n int256 newDebt_, // if negative then payback\n address to_ // address at which the borrow & withdraw amount should go to. If address(0) then it'll go to msg.sender\n )\n external\n payable\n returns (\n uint256, // nftId_\n int256, // final supply amount. if - then withdraw\n int256 // final borrow amount. if - then payback\n );\n \n function liquidate(\n uint256 debtAmt_,\n uint256 colPerUnitDebt_, // min collateral needed per unit of debt in 1e18\n address to_,\n bool absorb_\n ) external payable returns (uint actualDebtAmt_, uint actualColAmt_);\n\n function absorb() external;\n\n function rebalance() external payable returns (int supplyAmt_, int borrowAmt_);\n\n error FluidLiquidateResult(uint256 colLiquidated, uint256 debtLiquidated);\n}\n"
},
"contracts/protocols/vault/rewards/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Events {\n /// @notice Emitted when magnifier is updated\n event LogUpdateMagnifier(address indexed vault, uint256 newMagnifier);\n\n /// @notice Emitted when rewards are started\n event LogRewardsStarted(uint256 startTime, uint256 endTime);\n}\n"
},
"contracts/protocols/vault/rewards/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { FluidVaultT1Admin } from \"../vaultT1/adminModule/main.sol\";\nimport { IFluidVaultT1 } from \"../interfaces/iVaultT1.sol\";\nimport { IFluidReserveContract } from \"../../../reserve/interfaces/iReserveContract.sol\";\nimport { LiquiditySlotsLink } from \"../../../libraries/liquiditySlotsLink.sol\";\nimport { Events } from \"./events.sol\";\nimport { Variables } from \"./variables.sol\";\nimport { ErrorTypes } from \"../errorTypes.sol\";\nimport { Error } from \"../error.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\n\n/// @title VaultRewards\n/// @notice This contract is designed to adjust the supply rate magnifier for a vault based on the current collateral supply & supply rate.\n/// The adjustment aims to dynamically scale the rewards given to lenders as the TVL in the vault changes.\n///\n/// The magnifier is adjusted based on a regular most used reward type where rewardRate = totalRewardsAnnually / totalSupply.\n/// Reward rate is applied by adjusting the supply magnifier on vault.\n/// Adjustments are made via the rebalance function, which is restricted to be called by designated rebalancers only.\ncontract FluidVaultRewards is Variables, Events, Error {\n /// @dev Validates that an address is not the zero address\n modifier validAddress(address value_) {\n if (value_ == address(0)) {\n revert FluidVaultError(ErrorTypes.VaultRewards__AddressZero);\n }\n _;\n }\n\n /// @dev Validates that an address is a rebalancer (taken from reserve contract)\n modifier onlyRebalancer() {\n if (!RESERVE_CONTRACT.isRebalancer(msg.sender)) {\n revert FluidVaultError(ErrorTypes.VaultRewards__Unauthorized);\n }\n _;\n }\n\n /// @notice Constructs the FluidVaultRewards contract.\n /// @param reserveContract_ The address of the reserve contract where rebalancers are defined.\n /// @param vault_ The vault to which this contract will apply new magnifier parameter.\n /// @param liquidity_ Fluid liquidity address\n /// @param rewardsAmt_ Amounts of rewards to distribute\n /// @param duration_ rewards duration\n /// @param initiator_ address that can start rewards with `start()`\n /// @param collateralToken_ vault collateral token address\n constructor(\n IFluidReserveContract reserveContract_,\n IFluidVaultT1 vault_,\n IFluidLiquidity liquidity_,\n uint256 rewardsAmt_,\n uint256 duration_,\n address initiator_,\n address collateralToken_\n ) validAddress(address(reserveContract_)) validAddress(address(liquidity_)) validAddress(address(vault_)) validAddress(initiator_) validAddress(address(collateralToken_)){\n if (rewardsAmt_ == 0 || duration_ == 0) {\n revert FluidVaultError(ErrorTypes.VaultRewards__InvalidParams);\n }\n RESERVE_CONTRACT = reserveContract_;\n VAULT = vault_;\n REWARDS_AMOUNT = rewardsAmt_;\n REWARDS_AMOUNT_PER_YEAR = rewardsAmt_ * SECONDS_PER_YEAR / duration_;\n DURATION = duration_;\n INITIATOR = initiator_;\n LIQUIDITY = liquidity_;\n VAULT_COLLATERAL_TOKEN = collateralToken_;\n\n LIQUIDITY_TOTAL_AMOUNTS_COLLATERAL_TOKEN_SLOT = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_TOTAL_AMOUNTS_MAPPING_SLOT,\n collateralToken_\n );\n LIQUIDITY_EXCHANGE_PRICE_COLLATERAL_TOKEN_SLOT = LiquiditySlotsLink.calculateMappingStorageSlot(\n LiquiditySlotsLink.LIQUIDITY_EXCHANGE_PRICES_MAPPING_SLOT,\n collateralToken_\n );\n }\n\n /// @notice Rebalances the supply rate magnifier based on the current collateral supply.\n /// Can only be called by an authorized rebalancer.\n function rebalance() external onlyRebalancer {\n (uint256 newMagnifier_, bool ended_) = calculateMagnifier();\n if (ended_) {\n ended = true;\n }\n
},
"contracts/protocols/vault/rewards/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidReserveContract } from \"../../../reserve/interfaces/iReserveContract.sol\";\nimport { IFluidVaultT1 } from \"../interfaces/iVaultT1.sol\";\nimport { IFluidLiquidity } from \"../../../liquidity/interfaces/iLiquidity.sol\";\n\nabstract contract Constants {\n IFluidLiquidity public immutable LIQUIDITY;\n IFluidReserveContract public immutable RESERVE_CONTRACT;\n IFluidVaultT1 public immutable VAULT;\n uint256 public immutable REWARDS_AMOUNT;\n uint256 public immutable REWARDS_AMOUNT_PER_YEAR;\n uint256 public immutable DURATION;\n address public immutable INITIATOR;\n address public immutable VAULT_COLLATERAL_TOKEN;\n\n bytes32 internal immutable LIQUIDITY_TOTAL_AMOUNTS_COLLATERAL_TOKEN_SLOT;\n bytes32 internal immutable LIQUIDITY_EXCHANGE_PRICE_COLLATERAL_TOKEN_SLOT;\n uint256 internal constant FOUR_DECIMALS = 10000;\n uint256 internal constant SECONDS_PER_YEAR = 365 days;\n uint256 internal constant DEFAULT_EXPONENT_SIZE = 8;\n uint256 internal constant DEFAULT_EXPONENT_MASK = 0xff;\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n uint256 internal constant X14 = 0x3fff;\n uint256 internal constant X16 = 0xffff;\n uint256 internal constant X64 = 0xffffffffffffffff;\n}\n\nabstract contract Variables is Constants {\n bool public ended; // when rewards are ended\n uint96 public startTime;\n uint96 public endTime;\n}\n"
},
"contracts/protocols/vault/vaultT1/adminModule/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Events {\n /// @notice emitted when the supply rate magnifier config is updated\n event LogUpdateSupplyRateMagnifier(uint supplyRateMagnifier_);\n\n /// @notice emitted when the borrow rate magnifier config is updated\n event LogUpdateBorrowRateMagnifier(uint borrowRateMagnifier_);\n\n /// @notice emitted when the collateral factor config is updated\n event LogUpdateCollateralFactor(uint collateralFactor_);\n\n /// @notice emitted when the liquidation threshold config is updated\n event LogUpdateLiquidationThreshold(uint liquidationThreshold_);\n\n /// @notice emitted when the liquidation max limit config is updated\n event LogUpdateLiquidationMaxLimit(uint liquidationMaxLimit_);\n\n /// @notice emitted when the withdrawal gap config is updated\n event LogUpdateWithdrawGap(uint withdrawGap_);\n\n /// @notice emitted when the liquidation penalty config is updated\n event LogUpdateLiquidationPenalty(uint liquidationPenalty_);\n\n /// @notice emitted when the borrow fee config is updated\n event LogUpdateBorrowFee(uint borrowFee_);\n\n /// @notice emitted when the core setting configs are updated\n event LogUpdateCoreSettings(\n uint supplyRateMagnifier_,\n uint borrowRateMagnifier_,\n uint collateralFactor_,\n uint liquidationThreshold_,\n uint liquidationMaxLimit_,\n uint withdrawGap_,\n uint liquidationPenalty_,\n uint borrowFee_\n );\n\n /// @notice emitted when the oracle is updated\n event LogUpdateOracle(address indexed newOracle_);\n\n /// @notice emitted when the allowed rebalancer is updated\n event LogUpdateRebalancer(address indexed newRebalancer_);\n\n /// @notice emitted when funds are rescued\n event LogRescueFunds(address indexed token_);\n\n /// @notice emitted when dust debt is absorbed for `nftIds_`\n event LogAbsorbDustDebt(uint256[] nftIds_, uint256 absorbedDustDebt_);\n}\n"
},
"contracts/protocols/vault/vaultT1/adminModule/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport { Variables } from \"../common/variables.sol\";\nimport { Events } from \"./events.sol\";\nimport { ErrorTypes } from \"../../errorTypes.sol\";\nimport { Error } from \"../../error.sol\";\nimport { IFluidVaultT1 } from \"../../interfaces/iVaultT1.sol\";\nimport { BigMathMinified } from \"../../../../libraries/bigMathMinified.sol\";\nimport { TickMath } from \"../../../../libraries/tickMath.sol\";\n\n/// @notice Fluid Vault protocol Admin Module contract.\n/// Implements admin related methods to set configs such as liquidation params, rates\n/// oracle address etc.\n/// Methods are limited to be called via delegateCall only. Vault CoreModule (\"VaultT1\" contract)\n/// is expected to call the methods implemented here after checking the msg.sender is authorized.\n/// All methods update the exchange prices in storage before changing configs.\ncontract FluidVaultT1Admin is Variables, Events, Error {\n uint private constant X8 = 0xff;\n uint private constant X10 = 0x3ff;\n uint private constant X16 = 0xffff;\n uint private constant X19 = 0x7ffff;\n uint private constant X24 = 0xffffff;\n uint internal constant X64 = 0xffffffffffffffff;\n uint private constant X96 = 0xffffffffffffffffffffffff;\n address private constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n address private immutable addressThis;\n\n constructor() {\n addressThis = address(this);\n }\n\n modifier _verifyCaller() {\n if (address(this) == addressThis) {\n revert FluidVaultError(ErrorTypes.VaultT1Admin__OnlyDelegateCallAllowed);\n }\n _;\n }\n\n /// @dev updates exchange price on storage, called on all admin methods in combination with _verifyCaller modifier so\n /// only called by authorized delegatecall\n modifier _updateExchangePrice() {\n IFluidVaultT1(address(this)).updateExchangePricesOnStorage();\n _;\n }\n\n function _checkLiquidationMaxLimitAndPenalty(uint liquidationMaxLimit_, uint liquidationPenalty_) private pure {\n // liquidation max limit with penalty should not go above 99.7%\n // As liquidation with penalty can happen from liquidation Threshold to max limit\n // If it goes above 100% than that means liquidator is getting more collateral than user's available\n if ((liquidationMaxLimit_ + liquidationPenalty_) > 9970) {\n revert FluidVaultError(ErrorTypes.VaultT1Admin__ValueAboveLimit);\n }\n }\n\n /// @notice updates the supply rate magnifier to `supplyRateMagnifier_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateSupplyRateMagnifier(uint supplyRateMagnifier_) public _updateExchangePrice _verifyCaller {\n emit LogUpdateSupplyRateMagnifier(supplyRateMagnifier_);\n\n if (supplyRateMagnifier_ > X16) revert FluidVaultError(ErrorTypes.VaultT1Admin__ValueAboveLimit);\n\n vaultVariables2 =\n (vaultVariables2 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000) |\n supplyRateMagnifier_;\n }\n\n /// @notice updates the borrow rate magnifier to `borrowRateMagnifier_`. Input in 1e2 (1% = 100, 100% = 10_000).\n function updateBorrowRateMagnifier(uint borrowRateMagnifier_) public _updateExchangePrice _verifyCaller {\n emit LogUpdateBorrowRateMagnifier(borrowRateMagnifier_);\n\n if (borrowRateMagnifier_ > X16) revert FluidVaultError(ErrorTypes.VaultT1Admin__ValueAboveLimit);\n\n vaultVariables2 =\n (vaultVariables2 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff) |\n (borrowRateMagnifier_ << 16);\n }\n\n /// @notice updates the collateral factor to `collateralFactor_`.
},
"contracts/protocols/vault/vaultT1/common/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Variables {\n /***********************************|\n | Storage Variables |\n |__________________________________*/\n\n /// note: in all variables. For tick >= 0 are represented with bit as 1, tick < 0 are represented with bit as 0\n /// note: read all the variables through storageRead.sol\n\n /// note: vaultVariables contains vault variables which need regular updates through transactions\n /// First 1 bit => 0 => re-entrancy. If 0 then allow transaction to go, else throw.\n /// Next 1 bit => 1 => Is the current active branch liquidated? If true then check the branch's minima tick before creating a new position\n /// If the new tick is greater than minima tick then initialize a new branch, make that as current branch & do proper linking\n /// Next 1 bit => 2 => sign of topmost tick (0 -> negative; 1 -> positive)\n /// Next 19 bits => 3-21 => absolute value of topmost tick\n /// Next 30 bits => 22-51 => current branch ID\n /// Next 30 bits => 52-81 => total branch ID\n /// Next 64 bits => 82-145 => Total supply\n /// Next 64 bits => 146-209 => Total borrow\n /// Next 32 bits => 210-241 => Total positions\n uint256 internal vaultVariables;\n\n /// note: vaultVariables2 contains variables which do not update on every transaction. So mainly admin/auth set amount\n /// First 16 bits => 0-15 => supply rate magnifier; 10000 = 1x (Here 16 bits should be more than enough)\n /// Next 16 bits => 16-31 => borrow rate magnifier; 10000 = 1x (Here 16 bits should be more than enough)\n /// Next 10 bits => 32-41 => collateral factor. 800 = 0.8 = 80% (max precision of 0.1%)\n /// Next 10 bits => 42-51 => liquidation Threshold. 900 = 0.9 = 90% (max precision of 0.1%)\n /// Next 10 bits => 52-61 => liquidation Max Limit. 950 = 0.95 = 95% (max precision of 0.1%) (above this 100% liquidation can happen)\n /// Next 10 bits => 62-71 => withdraw gap. 100 = 0.1 = 10%. (max precision of 0.1%) (max 7 bits can also suffice for the requirement here of 0.1% to 10%). Needed to save some limits on withdrawals so liquidate can work seamlessly.\n /// Next 10 bits => 72-81 => liquidation penalty. 100 = 0.01 = 1%. (max precision of 0.01%) (max liquidation penantly can be 10.23%). Applies when tick is in between liquidation Threshold & liquidation Max Limit.\n /// Next 10 bits => 82-91 => borrow fee. 100 = 0.01 = 1%. (max precision of 0.01%) (max borrow fee can be 10.23%). Fees on borrow.\n /// Next 4 bits => 92-95 => empty\n /// Next 160 bits => 96-255 => Oracle address\n uint256 internal vaultVariables2;\n\n /// note: stores absorbed liquidity\n /// First 128 bits raw debt amount\n /// last 128 bits raw col amount\n uint256 internal absorbedLiquidity;\n\n /// position index => position data uint\n /// if the entire variable is 0 (meaning not initialized) at the start that means no position at all\n /// First 1 bit => 0 => position type (0 => borrow position; 1 => supply position)\n /// Next 1 bit => 1 => sign of user's tick (0 => negative; 1 => positive)\n /// Next 19 bits => 2-20 => absolute value of user's tick\n /// Next 24 bits => 21-44 => user's tick's id\n /// Below we are storing user's collateral & not debt, because the position can also be only collateral with no tick but it can never be only debt\n /// Next 64 bits => 45-108 => user's supply amount. Debt will be calculated through supply & ratio.\n /// Next 64 bits => 109-172 => user's dust debt amount. User's net debt = total debt - dust amount. Total debt is calculated through supply & ratio\n /// User won't pay any extra interest on dust debt & hence we will not show it as a debt on UI. For user's there's no dust.\n mapping(uint256 => uint256) internal positionData;\n\n /// Tick has debt only keeps data of non liquidated positions. liquidated tick's data stays in branch itself\n /// tick parent => uint (represents bool for 256 children)\n /// par
},
"contracts/protocols/vault/vaultT1/coreModule/constantVariables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidVaultFactory } from \"../../interfaces/iVaultFactory.sol\";\nimport { IFluidLiquidity } from \"../../../../liquidity/interfaces/iLiquidity.sol\";\nimport { StorageRead } from \"../../../../libraries/storageRead.sol\";\n\nimport { Structs } from \"./structs.sol\";\n\ninterface TokenInterface {\n function decimals() external view returns (uint8);\n}\n\ncontract ConstantVariables is StorageRead, Structs {\n /***********************************|\n | Constant Variables |\n |__________________________________*/\n\n address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n /// @dev collateral token address\n address internal immutable SUPPLY_TOKEN;\n /// @dev borrow token address\n address internal immutable BORROW_TOKEN;\n\n /// @dev Token decimals. For example wETH is 18 decimals\n uint8 internal immutable SUPPLY_DECIMALS;\n /// @dev Token decimals. For example USDC is 6 decimals\n uint8 internal immutable BORROW_DECIMALS;\n\n /// @dev VaultT1 AdminModule implemenation address\n address internal immutable ADMIN_IMPLEMENTATION;\n\n /// @dev VaultT1 Secondary implemenation (main2.sol) address\n address internal immutable SECONDARY_IMPLEMENTATION;\n\n /// @dev liquidity proxy contract address\n IFluidLiquidity public immutable LIQUIDITY;\n\n /// @dev vault factory contract address\n IFluidVaultFactory public immutable VAULT_FACTORY;\n\n uint public immutable VAULT_ID;\n\n uint internal constant X8 = 0xff;\n uint internal constant X10 = 0x3ff;\n uint internal constant X16 = 0xffff;\n uint internal constant X19 = 0x7ffff;\n uint internal constant X20 = 0xfffff;\n uint internal constant X24 = 0xffffff;\n uint internal constant X25 = 0x1ffffff;\n uint internal constant X30 = 0x3fffffff;\n uint internal constant X35 = 0x7ffffffff;\n uint internal constant X50 = 0x3ffffffffffff;\n uint internal constant X64 = 0xffffffffffffffff;\n uint internal constant X96 = 0xffffffffffffffffffffffff;\n uint internal constant X128 = 0xffffffffffffffffffffffffffffffff;\n\n uint256 internal constant EXCHANGE_PRICES_PRECISION = 1e12;\n\n /// @dev slot ids in Liquidity contract. Helps in low gas fetch from liquidity contract by skipping delegate call\n bytes32 internal immutable LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT;\n bytes32 internal immutable LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT;\n bytes32 internal immutable LIQUIDITY_USER_SUPPLY_SLOT;\n bytes32 internal immutable LIQUIDITY_USER_BORROW_SLOT;\n\n /// @notice returns all Vault constants\n function constantsView() external view returns (ConstantViews memory constantsView_) {\n constantsView_.liquidity = address(LIQUIDITY);\n constantsView_.factory = address(VAULT_FACTORY);\n constantsView_.adminImplementation = ADMIN_IMPLEMENTATION;\n constantsView_.secondaryImplementation = SECONDARY_IMPLEMENTATION;\n constantsView_.supplyToken = SUPPLY_TOKEN;\n constantsView_.borrowToken = BORROW_TOKEN;\n constantsView_.supplyDecimals = SUPPLY_DECIMALS;\n constantsView_.borrowDecimals = BORROW_DECIMALS;\n constantsView_.vaultId = VAULT_ID;\n constantsView_.liquiditySupplyExchangePriceSlot = LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT;\n constantsView_.liquidityBorrowExchangePriceSlot = LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT;\n constantsView_.liquidityUserSupplySlot = LIQUIDITY_USER_SUPPLY_SLOT;\n constantsView_.liquidityUserBorrowSlot = LIQUIDITY_USER_BORROW_SLOT;\n }\n\n constructor(ConstantViews memory constants_) {\n LIQUIDITY = IFluidLiquidity(constants_.liquidity);\n VAULT_FACTORY = IFluidVaultFactory(constants_.factory);\n VAULT_ID = constants_.vaultId;\n\n SUPPLY_TOKEN = constants_.supplyToken;\n BORROW_TOKEN = constants_.borrowToken;\n SUPPLY_DECIMALS = constants_.supplyDecimals;\n BORROW_DECIMALS = constants_
},
"contracts/protocols/vault/vaultT1/coreModule/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Events {\n /// @notice emitted when an operate() method is executed that changes collateral (`colAmt_`) / debt (debtAmt_`)\n /// amount for a `user_` position with `nftId_`. Receiver of any funds is the address `to_`.\n event LogOperate(address user_, uint256 nftId_, int256 colAmt_, int256 debtAmt_, address to_);\n\n /// @notice emitted when the exchange prices are updated in storage.\n event LogUpdateExchangePrice(uint256 supplyExPrice_, uint256 borrowExPrice_);\n\n /// @notice emitted when a liquidation has been executed.\n event LogLiquidate(address liquidator_, uint256 colAmt_, uint256 debtAmt_, address to_);\n\n /// @notice emitted when `absorb()` was executed to absorb bad debt.\n event LogAbsorb(uint colAbsorbedRaw_, uint debtAbsorbedRaw_);\n\n /// @notice emitted when a `rebalance()` has been executed, balancing out total supply / borrow between Vault\n /// and Fluid Liquidity pools.\n /// if `colAmt_` is positive then profit, meaning withdrawn from vault and sent to rebalancer address.\n /// if `colAmt_` is negative then loss, meaning transfer from rebalancer address to vault and deposit.\n /// if `debtAmt_` is positive then profit, meaning borrow from vault and sent to rebalancer address.\n /// if `debtAmt_` is negative then loss, meaning transfer from rebalancer address to vault and payback.\n event LogRebalance(int colAmt_, int debtAmt_);\n}\n"
},
"contracts/protocols/vault/vaultT1/coreModule/helpers.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Variables } from \"../common/variables.sol\";\nimport { ConstantVariables } from \"./constantVariables.sol\";\nimport { Events } from \"./events.sol\";\nimport { TickMath } from \"../../../../libraries/tickMath.sol\";\nimport { BigMathMinified } from \"../../../../libraries/bigMathMinified.sol\";\nimport { BigMathVault } from \"../../../../libraries/bigMathVault.sol\";\nimport { LiquidityCalcs } from \"../../../../libraries/liquidityCalcs.sol\";\n\nimport { ErrorTypes } from \"../../errorTypes.sol\";\nimport { Error } from \"../../error.sol\";\n\n/// @dev Fluid vault protocol helper methods. Mostly used for `operate()` and `liquidate()` methods of CoreModule.\nabstract contract Helpers is Variables, ConstantVariables, Events, Error {\n using BigMathMinified for uint256;\n using BigMathVault for uint256;\n\n /// @notice Calculates new vault exchange prices. Does not update values in storage.\n /// @param vaultVariables2_ exactly same as vaultVariables2 from storage\n /// @return liqSupplyExPrice_ latest liquidity's supply token supply exchange price\n /// @return liqBorrowExPrice_ latest liquidity's borrow token borrow exchange price\n /// @return vaultSupplyExPrice_ latest vault's supply token exchange price\n /// @return vaultBorrowExPrice_ latest vault's borrow token exchange price\n function updateExchangePrices(\n uint256 vaultVariables2_\n )\n public\n view\n returns (\n uint256 liqSupplyExPrice_,\n uint256 liqBorrowExPrice_,\n uint256 vaultSupplyExPrice_,\n uint256 vaultBorrowExPrice_\n )\n {\n // Fetching last stored rates\n uint rates_ = rates;\n\n (liqSupplyExPrice_, ) = LiquidityCalcs.calcExchangePrices(\n LIQUIDITY.readFromStorage(LIQUIDITY_SUPPLY_EXCHANGE_PRICE_SLOT)\n );\n (, liqBorrowExPrice_) = LiquidityCalcs.calcExchangePrices(\n LIQUIDITY.readFromStorage(LIQUIDITY_BORROW_EXCHANGE_PRICE_SLOT)\n );\n\n uint256 oldLiqSupplyExPrice_ = (rates_ & X64);\n uint256 oldLiqBorrowExPrice_ = ((rates_ >> 64) & X64);\n if (liqSupplyExPrice_ < oldLiqSupplyExPrice_ || liqBorrowExPrice_ < oldLiqBorrowExPrice_) {\n // new liquidity exchange price is < than the old one. liquidity exchange price should only ever increase.\n // If not, something went wrong and avoid proceeding with unknown outcome.\n revert FluidVaultError(ErrorTypes.VaultT1__LiquidityExchangePriceUnexpected);\n }\n\n // liquidity Exchange Prices always increases in next block. Hence substraction with old will never be negative\n // uint64 * 1e18 is the max the number that could be\n unchecked {\n // Calculating increase in supply exchange price w.r.t last stored liquidity's exchange price\n // vaultSupplyExPrice_ => supplyIncreaseInPercent_\n vaultSupplyExPrice_ = ((((liqSupplyExPrice_ * 1e18) / oldLiqSupplyExPrice_) - 1e18) *\n (vaultVariables2_ & X16)) / 10000; // supply rate magnifier\n\n // Calculating increase in borrow exchange price w.r.t last stored liquidity's exchange price\n // vaultBorrowExPrice_ => borrowIncreaseInPercent_\n vaultBorrowExPrice_ = ((((liqBorrowExPrice_ * 1e18) / oldLiqBorrowExPrice_) - 1e18) *\n ((vaultVariables2_ >> 16) & X16)) / 10000; // borrow rate magnifier\n\n // It's extremely hard the exchange prices to overflow even in 100 years but if it does it's not an\n // issue here as we are not updating on storage\n // (rates_ >> 128) & X64) -> last stored vault's supply token exchange price\n vaultSupplyExPrice_ = (((rates_ >> 128) & X64) * (1e18 + vaultSupplyExPrice_)) / 1e18;\n // (rates_ >> 192) -> last stored vault's borrow token exchange price (no need to mask with & X64 as it is anyway max 64 bits)\n vaultBorrowExPrice_
},
"contracts/protocols/vault/vaultT1/coreModule/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidOracle } from \"../../../../oracle/fluidOracle.sol\";\n\nimport { TickMath } from \"../../../../libraries/tickMath.sol\";\nimport { BigMathMinified } from \"../../../../libraries/bigMathMinified.sol\";\nimport { BigMathVault } from \"../../../../libraries/bigMathVault.sol\";\nimport { LiquidityCalcs } from \"../../../../libraries/liquidityCalcs.sol\";\nimport { SafeTransfer } from \"../../../../libraries/safeTransfer.sol\";\n\nimport { Helpers } from \"./helpers.sol\";\nimport { LiquiditySlotsLink } from \"../../../../libraries/liquiditySlotsLink.sol\";\n\nimport { ErrorTypes } from \"../../errorTypes.sol\";\n\n/// @notice Fluid \"VaultT1\" (Vault Type 1). Fluid vault protocol main contract.\n/// Fluid Vault protocol is a borrow / lending protocol, allowing users to create collateral / borrow positions.\n/// All funds are deposited into / borrowed from Fluid Liquidity layer.\n/// Positions are represented through NFTs minted by the VaultFactory.\n/// Deployed by \"VaultFactory\" and linked together with VaultT1 AdminModule `ADMIN_IMPLEMENTATION` and\n/// FluidVaultT1Secondary (main2.sol) `SECONDARY_IMPLEMENTATION`.\n/// AdminModule & FluidVaultT1Secondary methods are delegateCalled, if the msg.sender has the required authorization.\n/// This contract links to an Oracle, which is used to assess collateral / debt value. Oracles implement the\n/// \"FluidOracle\" base contract and return the price in 1e27 precision.\n/// @dev For view methods / accessing data, use the \"VaultResolver\" periphery contract.\ncontract FluidVaultT1 is Helpers {\n using BigMathMinified for uint256;\n using BigMathVault for uint256;\n\n /// @dev Single function which handles supply, withdraw, borrow & payback\n /// @param nftId_ NFT ID for interaction. If 0 then create new NFT/position.\n /// @param newCol_ new collateral. If positive then deposit, if negative then withdraw, if 0 then do nohing\n /// @param newDebt_ new debt. If positive then borrow, if negative then payback, if 0 then do nohing\n /// @param to_ address where withdraw or borrow should go. If address(0) then msg.sender\n /// @return nftId_ if 0 then this returns the newly created NFT Id else returns the same NFT ID\n /// @return newCol_ final supply amount. Mainly if max withdraw using type(int).min then this is useful to get perfect amount else remain same as newCol_\n /// @return newDebt_ final borrow amount. Mainly if max payback using type(int).min then this is useful to get perfect amount else remain same as newDebt_\n function operate(\n uint256 nftId_, // if 0 then new position\n int256 newCol_, // if negative then withdraw\n int256 newDebt_, // if negative then payback\n address to_ // address at which the borrow & withdraw amount should go to. If address(0) then it'll go to msg.sender\n )\n public\n payable\n returns (\n uint256, // nftId_\n int256, // final supply amount. if - then withdraw\n int256 // final borrow amount. if - then payback\n )\n {\n uint256 vaultVariables_ = vaultVariables;\n // re-entrancy check\n if (vaultVariables_ & 1 == 0) {\n // Updating on storage\n vaultVariables = vaultVariables_ | 1;\n } else {\n revert FluidVaultError(ErrorTypes.VaultT1__AlreadyEntered);\n }\n\n if (\n (newCol_ == 0 && newDebt_ == 0) ||\n // withdrawal or deposit cannot be too small\n ((newCol_ != 0) && (newCol_ > -10000 && newCol_ < 10000)) ||\n // borrow or payback cannot be too small\n ((newDebt_ != 0) && (newDebt_ > -10000 && newDebt_ < 10000))\n ) {\n revert FluidVaultError(ErrorTypes.VaultT1__InvalidOperateAmount);\n }\n\n // Check msg.value aligns with input amounts if supply or borrow token is native token.\n // N
},
"contracts/protocols/vault/vaultT1/coreModule/main2.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Variables } from \"../common/variables.sol\";\nimport { IFluidOracle } from \"../../../../oracle/fluidOracle.sol\";\nimport { TickMath } from \"../../../../libraries/tickMath.sol\";\nimport { BigMathMinified } from \"../../../../libraries/bigMathMinified.sol\";\nimport { Error } from \"../../error.sol\";\nimport { ErrorTypes } from \"../../errorTypes.sol\";\nimport { IFluidVaultT1 } from \"../../interfaces/iVaultT1.sol\";\nimport { Structs } from \"./structs.sol\";\nimport { Events } from \"./events.sol\";\nimport { LiquiditySlotsLink } from \"../../../../libraries/liquiditySlotsLink.sol\";\nimport { LiquidityCalcs } from \"../../../../libraries/liquidityCalcs.sol\";\nimport { IFluidLiquidity } from \"../../../../liquidity/interfaces/iLiquidity.sol\";\nimport { SafeTransfer } from \"../../../../libraries/safeTransfer.sol\";\n\n/// @notice Fluid Vault protocol secondary methods contract.\n/// Implements `absorb()` and `rebalance()` methods, extracted from main contract due to contract size limits.\n/// Methods are limited to be called via delegateCall only (as done by Vault CoreModule \"VaultT1\" contract).\ncontract FluidVaultT1Secondary is Variables, Error, Structs, Events {\n using BigMathMinified for uint;\n\n address internal constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n // 30 bits (used for partials mainly)\n uint internal constant X8 = 0xff;\n uint internal constant X10 = 0x3ff;\n uint internal constant X16 = 0xffff;\n uint internal constant X19 = 0x7ffff;\n uint internal constant X20 = 0xfffff;\n uint internal constant X24 = 0xffffff;\n uint internal constant X25 = 0x1ffffff;\n uint internal constant X30 = 0x3fffffff;\n uint internal constant X35 = 0x7ffffffff;\n uint internal constant X50 = 0x3ffffffffffff;\n uint internal constant X64 = 0xffffffffffffffff;\n uint internal constant X96 = 0xffffffffffffffffffffffff;\n uint internal constant X128 = 0xffffffffffffffffffffffffffffffff;\n\n address private immutable addressThis;\n\n constructor() {\n addressThis = address(this);\n }\n\n modifier _verifyCaller() {\n if (address(this) == addressThis) {\n revert FluidVaultError(ErrorTypes.VaultT1__OnlyDelegateCallAllowed);\n }\n _;\n }\n\n /// @dev absorb function absorbs the bad debt if the bad debt is above max limit. The main use of it is\n /// if the bad debt didn't got liquidated in time maybe due to sudden price drop or bad debt was extremely small to liquidate\n /// and the bad debt goes above 100% ratio then there's no incentive for anyone to liquidate now\n /// hence absorb functions absorbs that bad debt to allow newer bad debt to liquidate seamlessly.\n /// if absorbing were to happen after this it's on governance on how to deal with it\n /// although it can still be removed through liquidate via liquidator if the price goes back up and liquidation becomes beneficial\n /// upon absorbed user position gets 100% liquidated.\n function absorb() public _verifyCaller {\n uint256 vaultVariables_ = vaultVariables;\n\n // ############# turning re-entrancy bit on #############\n if (vaultVariables_ & 1 == 0) {\n // Updating on storage\n vaultVariables = vaultVariables_ | 1;\n } else {\n revert FluidVaultError(ErrorTypes.VaultT1__AlreadyEntered);\n }\n\n AbsorbMemoryVariables memory a_;\n\n // Temporary holder variables, used many times for different small few liner things\n uint temp_;\n uint temp2_;\n\n int maxTick_;\n\n {\n a_.vaultVariables2 = vaultVariables2;\n\n // temp_ -> top tick\n temp_ = ((vaultVariables_ >> 2) & X20);\n if (temp_ == 0) {\n revert FluidVaultError(ErrorTypes.VaultT1__TopTickDoesNotExist);\n }\n\n // Below are exchange prices of vaults\n (,
},
"contracts/protocols/vault/vaultT1/coreModule/structs.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\ncontract Structs {\n // structs are used to mitigate Stack too deep errors\n\n struct OperateMemoryVars {\n // ## User's position before update ##\n uint oldColRaw;\n uint oldNetDebtRaw; // total debt - dust debt\n int oldTick;\n // ## User's position after update ##\n uint colRaw;\n uint debtRaw; // total debt - dust debt\n uint dustDebtRaw;\n int tick;\n uint tickId;\n // others\n uint256 vaultVariables2;\n uint256 branchId;\n int256 topTick;\n uint liquidityExPrice;\n uint supplyExPrice;\n uint borrowExPrice;\n uint branchData;\n // user's supply slot data in liquidity\n uint userSupplyLiquidityData;\n }\n\n struct BranchData {\n uint id;\n uint data;\n uint ratio;\n uint debtFactor;\n int minimaTick;\n uint baseBranchData;\n }\n\n struct TickData {\n int tick;\n uint data;\n uint ratio;\n uint ratioOneLess;\n uint length;\n uint currentRatio; // current tick is ratio with partials.\n uint partials;\n }\n\n // note: All the below token amounts are in raw form.\n struct CurrentLiquidity {\n uint256 debtRemaining; // Debt remaining to liquidate\n uint256 debt; // Current liquidatable debt before reaching next check point\n uint256 col; // Calculate using debt & ratioCurrent\n uint256 colPerDebt; // How much collateral to liquidate per unit of Debt\n uint256 totalDebtLiq; // Total debt liquidated till now\n uint256 totalColLiq; // Total collateral liquidated till now\n int tick; // Current tick to liquidate\n uint ratio; // Current ratio to liquidate\n uint tickStatus; // if 1 then it's a perfect tick, if 2 that means it's a liquidated tick\n int refTick; // ref tick to liquidate\n uint refRatio; // ratio at ref tick\n uint refTickStatus; // if 1 then it's a perfect tick, if 2 that means it's a liquidated tick, if 3 that means it's a liquidation threshold\n }\n\n struct TickHasDebt {\n int tick; // current tick\n int nextTick; // next tick with liquidity\n int mapId; // mapping ID of tickHasDebt\n uint bitsToRemove; // liquidity to remove till tick_ so we can search for next tick\n uint tickHasDebt; // getting tickHasDebt_ from tickHasDebt[mapId_]\n uint mostSigBit; // most significant bit in tickHasDebt_ to get the next tick\n }\n\n struct LiquidateMemoryVars {\n uint256 vaultVariables2;\n int liquidationTick;\n int maxTick;\n uint256 supplyExPrice;\n uint256 borrowExPrice;\n }\n\n struct AbsorbMemoryVariables {\n uint256 supplyExPrice;\n uint256 borrowExPrice;\n uint256 debtAbsorbed;\n uint256 colAbsorbed;\n uint256 vaultVariables2;\n int256 startingTick;\n uint256 mostSigBit;\n }\n\n struct ConstantViews {\n address liquidity;\n address factory;\n address adminImplementation;\n address secondaryImplementation;\n address supplyToken;\n address borrowToken;\n uint8 supplyDecimals;\n uint8 borrowDecimals;\n uint vaultId;\n bytes32 liquiditySupplyExchangePriceSlot;\n bytes32 liquidityBorrowExchangePriceSlot;\n bytes32 liquidityUserSupplySlot;\n bytes32 liquidityUserBorrowSlot;\n }\n\n struct RebalanceMemoryVariables {\n uint256 liqSupplyExPrice;\n uint256 liqBorrowExPrice;\n uint256 vaultSupplyExPrice;\n uint256 vaultBorrowExPrice;\n }\n}\n"
},
"contracts/reserve/error.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Error {\n error FluidReserveContractError(uint256 errorId_);\n}\n"
},
"contracts/reserve/errorTypes.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nlibrary ErrorTypes {\n /***********************************|\n | Reserve | \n |__________________________________*/\n\n /// @notice thrown when an unauthorized caller is trying to execute an auth-protected method\n uint256 internal constant ReserveContract__Unauthorized = 90001;\n\n /// @notice thrown when an input address is zero\n uint256 internal constant ReserveContract__AddressZero = 90002;\n\n /// @notice thrown when input arrays has different lenghts\n uint256 internal constant ReserveContract__InvalidInputLenghts = 90003;\n\n /// @notice thrown when renounceOwnership is called\n uint256 internal constant ReserveContract__RenounceOwnershipUnsupported = 90004;\n}\n"
},
"contracts/reserve/events.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nabstract contract Events {\n /// @notice Emitted when an address is added or removed from the auths\n event LogUpdateAuth(address indexed auth, bool isAuth);\n\n /// @notice Emitted when an address is added or removed from the rebalancers\n event LogUpdateRebalancer(address indexed rebalancer, bool isRebalancer);\n\n /// @notice Emitted when a token is approved for use by a protocol\n event LogAllow(address indexed protocol, address indexed token, uint256 newAllowance, uint existingAllowance);\n\n /// @notice Emitted when a token is revoked for use by a protocol\n event LogRevoke(address indexed protocol, address indexed token);\n\n /// @notice Emitted when fToken is rebalanced\n event LogRebalanceFToken(address indexed protocol, uint amount);\n\n /// @notice Emitted when vault is rebalanced\n event LogRebalanceVault(address indexed protocol, int colAmount, int debtAmount);\n\n /// @notice Emitted whenever funds for a certain `token` are transfered to Liquidity\n event LogTransferFunds(address indexed token);\n}\n"
},
"contracts/reserve/interfaces/iReserveContract.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { IFluidLiquidity } from \"../../liquidity/interfaces/iLiquidity.sol\";\n\ninterface IFluidReserveContract {\n function isRebalancer(address user) external returns (bool);\n\n function initialize(\n address[] memory _auths,\n address[] memory _rebalancers,\n IFluidLiquidity liquidity_,\n address owner_\n ) external;\n\n function rebalanceFToken(address protocol_) external;\n\n function rebalanceVault(address protocol_) external;\n\n function transferFunds(address token_) external;\n\n function getProtocolTokens(address protocol_) external;\n\n function updateAuth(address auth_, bool isAuth_) external;\n\n function updateRebalancer(address rebalancer_, bool isRebalancer_) external;\n\n function approve(address[] memory protocols_, address[] memory tokens_, uint256[] memory amounts_) external;\n\n function revoke(address[] memory protocols_, address[] memory tokens_) external;\n}\n"
},
"contracts/reserve/main.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { EnumerableSet } from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport { IFluidLiquidity } from \"../liquidity/interfaces/iLiquidity.sol\";\nimport { IFluidLendingFactory } from \"../protocols/lending/interfaces/iLendingFactory.sol\";\nimport { IFTokenAdmin } from \"../protocols/lending/interfaces/iFToken.sol\";\nimport { IFluidVaultT1 } from \"../protocols/vault/interfaces/iVaultT1.sol\";\nimport { SafeTransfer } from \"../libraries/safeTransfer.sol\";\n\nimport { Variables } from \"./variables.sol\";\nimport { Events } from \"./events.sol\";\nimport { ErrorTypes } from \"./errorTypes.sol\";\nimport { Error } from \"./error.sol\";\n\nabstract contract ReserveContractAuth is Variables, Error, Events {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /// @dev validates that an address is not the zero address\n modifier validAddress(address value_) {\n if (value_ == address(0)) {\n revert FluidReserveContractError(ErrorTypes.ReserveContract__AddressZero);\n }\n _;\n }\n\n /// @notice Checks that the sender is an auth\n modifier onlyAuth() {\n if (!isAuth[msg.sender] && owner() != msg.sender)\n revert FluidReserveContractError(ErrorTypes.ReserveContract__Unauthorized);\n _;\n }\n\n /// @notice Updates an auth's status as an auth\n /// @param auth_ The address to update\n /// @param isAuth_ Whether or not the address should be an auth\n function updateAuth(address auth_, bool isAuth_) external onlyOwner validAddress(auth_) {\n isAuth[auth_] = isAuth_;\n emit LogUpdateAuth(auth_, isAuth_);\n }\n\n /// @notice Updates a rebalancer's status as a rebalancer\n /// @param rebalancer_ The address to update\n /// @param isRebalancer_ Whether or not the address should be a rebalancer\n function updateRebalancer(address rebalancer_, bool isRebalancer_) external onlyAuth validAddress(rebalancer_) {\n isRebalancer[rebalancer_] = isRebalancer_;\n emit LogUpdateRebalancer(rebalancer_, isRebalancer_);\n }\n\n /// @notice Approves protocols to spend the reserves tokens\n /// @dev The parameters are parallel arrays\n /// @param protocols_ The protocols that will be spending reserve tokens\n /// @param tokens_ The tokens to approve\n /// @param amounts_ The amounts to approve\n function approve(\n address[] memory protocols_,\n address[] memory tokens_,\n uint256[] memory amounts_\n ) external onlyAuth {\n if (protocols_.length != tokens_.length || tokens_.length != amounts_.length) {\n revert FluidReserveContractError(ErrorTypes.ReserveContract__InvalidInputLenghts);\n }\n\n for (uint256 i = 0; i < protocols_.length; i++) {\n address protocol_ = protocols_[i];\n address token_ = tokens_[i];\n uint256 amount_ = amounts_[i];\n uint256 existingAllowance_ = IERC20(token_).allowance(address(this), protocol_);\n\n // making approval 0 first and then re-approving with a new amount.\n SafeERC20.safeApprove(IERC20(address(token_)), protocol_, 0);\n SafeERC20.safeApprove(IERC20(address(token_)), protocol_, amount_);\n _protocolTokens[protocol_].add(token_);\n emit LogAllow(protocol_, token_, amount_, existingAllowance_);\n }\n }\n\n /// @notice Revokes protocols' ability to spend the reserves tokens\n /// @dev The parameters are parallel arrays\n /// @param protocols_ The protocols that will no longer be spending reserve tokens\n /
},
"contracts/reserve/proxy.sol": {
"content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.21;\n\nimport { ERC1967Proxy } from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/// @title FluidReserveContractProxy\n/// @notice Default ERC1967Proxy for ReserveContract\ncontract FluidReserveContractProxy is ERC1967Proxy {\n constructor(address logic_, bytes memory data_) payable ERC1967Proxy(logic_, data_) {}\n}\n"
},
"contracts/reserve/variables.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.21;\n\nimport { Initializable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { EnumerableSet } from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport { IFluidLiquidity } from \"../liquidity/interfaces/iLiquidity.sol\";\nimport { IFluidLendingFactory } from \"../protocols/lending/interfaces/iLendingFactory.sol\";\n\nabstract contract Constants {\n /// @notice address of the liquidity contract\n IFluidLiquidity public immutable LIQUIDITY;\n\n constructor(IFluidLiquidity liquidity_) {\n LIQUIDITY = liquidity_;\n }\n}\n\nabstract contract Variables is Constants, Initializable, OwnableUpgradeable {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n // ------------ storage variables from inherited contracts (Initializable, OwnableUpgradeable) come before vars here --------\n // @dev variables here start at storage slot 101, before is:\n // - Initializable with storage slot 0:\n // uint8 private _initialized;\n // bool private _initializing;\n // - OwnableUpgradeable with slots 1 to 100:\n // uint256[50] private __gap; (from ContextUpgradeable, slot 1 until slot 50)\n // address private _owner; (at slot 51)\n // uint256[49] private __gap; (slot 52 until slot 100)\n\n // ----------------------- slot 101 ---------------------------\n /// @notice Maps address to there status as an Auth\n mapping(address => bool) public isAuth;\n\n /// @notice Maps address to there status as a Rebalancer\n mapping(address => bool) public isRebalancer;\n\n /// @notice Mapping of protocol addresses to the tokens that are allowed to be used by that protocol\n mapping(address => EnumerableSet.AddressSet) internal _protocolTokens;\n\n constructor(IFluidLiquidity liquidity_) Constants(liquidity_) {}\n}\n"
},
"solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnershipTransferred(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function transferOwnership(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnershipTransferred(msg.sender, newOwner);\n }\n}\n"
},
"solmate/src/utils/Bytes32AddressLib.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Library for converting between addresses and bytes32 values.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Bytes32AddressLib.sol)\nlibrary Bytes32AddressLib {\n function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {\n return address(uint160(uint256(bytesValue)));\n }\n\n function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {\n return bytes32(bytes20(addressValue));\n }\n}\n"
},
"solmate/src/utils/CREATE3.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {Bytes32AddressLib} from \"./Bytes32AddressLib.sol\";\n\n/// @notice Deploy to deterministic addresses without an initcode factor.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol)\n/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol)\nlibrary CREATE3 {\n using Bytes32AddressLib for bytes32;\n\n //--------------------------------------------------------------------------------//\n // Opcode | Opcode + Arguments | Description | Stack View //\n //--------------------------------------------------------------------------------//\n // 0x36 | 0x36 | CALLDATASIZE | size //\n // 0x3d | 0x3d | RETURNDATASIZE | 0 size //\n // 0x3d | 0x3d | RETURNDATASIZE | 0 0 size //\n // 0x37 | 0x37 | CALLDATACOPY | //\n // 0x36 | 0x36 | CALLDATASIZE | size //\n // 0x3d | 0x3d | RETURNDATASIZE | 0 size //\n // 0x34 | 0x34 | CALLVALUE | value 0 size //\n // 0xf0 | 0xf0 | CREATE | newContract //\n //--------------------------------------------------------------------------------//\n // Opcode | Opcode + Arguments | Description | Stack View //\n //--------------------------------------------------------------------------------//\n // 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode //\n // 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode //\n // 0x52 | 0x52 | MSTORE | //\n // 0x60 | 0x6008 | PUSH1 08 | 8 //\n // 0x60 | 0x6018 | PUSH1 18 | 24 8 //\n // 0xf3 | 0xf3 | RETURN | //\n //--------------------------------------------------------------------------------//\n bytes internal constant PROXY_BYTECODE = hex\"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3\";\n\n bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE);\n\n function deploy(\n bytes32 salt,\n bytes memory creationCode,\n uint256 value\n ) internal returns (address deployed) {\n bytes memory proxyChildBytecode = PROXY_BYTECODE;\n\n address proxy;\n /// @solidity memory-safe-assembly\n assembly {\n // Deploy a new contract with our pre-made bytecode via CREATE2.\n // We start 32 bytes into the code to avoid copying the byte length.\n proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt)\n }\n require(proxy != address(0), \"DEPLOYMENT_FAILED\");\n\n deployed = getDeployed(salt);\n (bool success, ) = proxy.call{value: value}(creationCode);\n require(success && deployed.code.length != 0, \"INITIALIZATION_FAILED\");\n }\n\n function getDeployed(bytes32 salt) internal view returns (address) {\n address proxy = keccak256(\n abi.encodePacked(\n // Prefix:\n bytes1(0xFF),\n // Creator:\n address(this),\n // Salt:\n salt,\n // Bytecode hash:\n PROXY_BYTECODE_HASH\n )\n ).fromLast20Bytes();\n\n return\n keccak256(\n abi.encodePacked(\n // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01)\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in h
},
"solmate/src/utils/FixedPointMathLib.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\n/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)\nlibrary FixedPointMathLib {\n /*//////////////////////////////////////////////////////////////\n SIMPLIFIED FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal constant MAX_UINT256 = 2**256 - 1;\n\n uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n }\n\n function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n }\n\n function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n }\n\n function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n }\n\n /*//////////////////////////////////////////////////////////////\n LOW LEVEL FIXED POINT OPERATIONS\n //////////////////////////////////////////////////////////////*/\n\n function mulDivDown(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n /// @solidity memory-safe-assembly\n assembly {\n // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n revert(0, 0)\n }\n\n // Divide x * y by the denominator.\n z := div(mul(x, y), denominator)\n }\n }\n\n function mulDivUp(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 z) {\n /// @solidity memory-safe-assembly\n assembly {\n // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n revert(0, 0)\n }\n\n // If x * y modulo the denominator is strictly greater than 0,\n // 1 is added to round up the division of x * y by the denominator.\n z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))\n }\n }\n\n function rpow(\n uint256 x,\n uint256 n,\n uint256 scalar\n ) internal pure returns (uint256 z) {\n /// @solidity memory-safe-assembly\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n // 0 ** 0 = 1\n z := scalar\n }\n default {\n // 0 ** n = 0\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n // If n is even, store scalar in z for now.\n z := scalar\n }\n default {\n // If n is odd, store x in z for now.\n z := x\n }\n\n // Shifting right by 1 is like dividing by 2.\n let half := shr(1, scalar)\n\n for {\n // Shift n right by 1 before looping to halve it.\n n := shr(1, n)\n } n {\n // Shift n right by 1 each iteration to halve it.\n n := shr(1, n)\n } {\n
},
"solmate/src/utils/SSTORE2.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Read and write to persistent storage at a fraction of the cost.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)\n/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)\nlibrary SSTORE2 {\n uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.\n\n /*//////////////////////////////////////////////////////////////\n WRITE LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function write(bytes memory data) internal returns (address pointer) {\n // Prefix the bytecode with a STOP opcode to ensure it cannot be called.\n bytes memory runtimeCode = abi.encodePacked(hex\"00\", data);\n\n bytes memory creationCode = abi.encodePacked(\n //---------------------------------------------------------------------------------------------------------------//\n // Opcode | Opcode + Arguments | Description | Stack View //\n //---------------------------------------------------------------------------------------------------------------//\n // 0x60 | 0x600B | PUSH1 11 | codeOffset //\n // 0x59 | 0x59 | MSIZE | 0 codeOffset //\n // 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //\n // 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //\n // 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //\n // 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //\n // 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //\n // 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //\n // 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //\n // 0xf3 | 0xf3 | RETURN | //\n //---------------------------------------------------------------------------------------------------------------//\n hex\"60_0B_59_81_38_03_80_92_59_39_F3\", // Returns all code in the contract except for the first 11 (0B in hex) bytes.\n runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.\n );\n\n /// @solidity memory-safe-assembly\n assembly {\n // Deploy a new contract with the generated creation code.\n // We start 32 bytes into the code to avoid copying the byte length.\n pointer := create(0, add(creationCode, 32), mload(creationCode))\n }\n\n require(pointer != address(0), \"DEPLOYMENT_FAILED\");\n }\n\n /*//////////////////////////////////////////////////////////////\n READ LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function read(address pointer) internal view returns (bytes memory) {\n return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);\n }\n\n function read(address pointer, uint256 start) internal view returns (bytes memory) {\n start += DATA_OFFSET;\n\n return readBytecode(pointer, start, pointer.code.length - start);\n }\n\n function read(\n address pointer,\n ui
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000000
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}