-
Notifications
You must be signed in to change notification settings - Fork 23
/
ProtocolRewards.json
1 lines (1 loc) · 85.4 KB
/
ProtocolRewards.json
1
{"language":"Solidity","sources":{"contracts/ProtocolRewards.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\nimport {OwnableRoles} from \"solady/auth/OwnableRoles.sol\";\r\nimport {Initializable} from \"openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol\";\r\nimport {SafeTransferLib} from \"solady/utils/SafeTransferLib.sol\";\r\nimport {IProtocolRewards} from \"./interfaces/IProtocolRewards.sol\";\r\n\r\n/// @title ProtocolRewards\r\n/// @notice Manager of deposits & withdrawals for protocol rewards\r\n/// @custom:oz-upgrades-from ProtocolRewardsV0\r\ncontract ProtocolRewards is Initializable, OwnableRoles, IProtocolRewards {\r\n /// @notice An account's balance\r\n mapping(address => uint256) public balanceOf;\r\n\r\n /// @notice Total Balance across all accounts\r\n uint256 public totalBalance;\r\n\r\n using SafeTransferLib for address;\r\n\r\n /// @custom:oz-upgrades-unsafe-allow constructor\r\n // solhint-disable-next-line func-visibility\r\n constructor() payable {\r\n _disableInitializers();\r\n }\r\n\r\n function initialize(address ownerAddress_) external initializer {\r\n _initializeOwner(ownerAddress_);\r\n }\r\n\r\n /// @notice The total amount of ETH held in the contract\r\n function totalSupply() external view returns (uint256) {\r\n return address(this).balance;\r\n }\r\n\r\n /// @notice The total excess amount of ETH held in the contract\r\n function excessSupply() external view returns (uint256) {\r\n return address(this).balance - totalBalance;\r\n }\r\n\r\n /// @notice transfer excessSupply onlyOwner\r\n /// @param to The address to transfer to\r\n function transferExcessSupply(address to, uint256 amount) external onlyOwnerOrRoles(_ROLE_0) {\r\n if (amount > this.excessSupply()) {\r\n revert INVALID_AMOUNT();\r\n }\r\n _transferExcessSupply(to, amount);\r\n }\r\n\r\n /// @notice internal function to transfer excessSupply\r\n /// @param to The address to transfer to\r\n function _transferExcessSupply(address to, uint256 amount) internal {\r\n if (to == address(0)) {\r\n revert ADDRESS_ZERO();\r\n }\r\n\r\n to.safeTransferETH(amount);\r\n\r\n emit TransferExcessSupply(msg.sender, to, amount);\r\n }\r\n\r\n /// @notice Generic function to deposit ETH for a recipient, with an optional comment\r\n /// @param to Address to deposit to\r\n /// @param to Reason system reason for deposit (used for indexing)\r\n /// @param comment Optional comment as reason for deposit\r\n function deposit(address to, bytes4 reason, string calldata comment) external payable {\r\n if (to == address(0)) {\r\n revert ADDRESS_ZERO();\r\n }\r\n\r\n _increaseBalance(to, msg.value);\r\n\r\n emit Deposit(msg.sender, to, reason, msg.value, comment);\r\n }\r\n\r\n /// @notice Allow admin to increase balance of an address only up the amount of excess ETH in the contract\r\n /// @param to The address to increase the balance of\r\n /// @param amount The amount to increase the balance by\r\n function increaseBalance(address to, uint256 amount) external onlyOwnerOrRoles(_ROLE_0) {\r\n if (amount > this.excessSupply()) {\r\n revert INVALID_AMOUNT();\r\n }\r\n _increaseBalance(to, amount);\r\n\r\n emit IncreaseBalance(to, amount);\r\n }\r\n\r\n /// @notice Increase the balance of addresses in amounts in a batch function\r\n /// @param to The addresses to increase the balance of\r\n /// @param amounts The amounts to increase the balance by\r\n function increaseBalanceBatch(address[] calldata to, uint256[] calldata amounts) external onlyOwnerOrRoles(_ROLE_0) {\r\n uint256 numRecipients = to.length;\r\n\r\n if (numRecipients != amounts.length) {\r\n revert ARRAY_LENGTH_MISMATCH();\r\n }\r\n\r\n address currentRecipient;\r\n uint256 currentAmount;\r\n\r\n for (uint256 i; i < numRecipients;) {\r\n currentRecipient = to[i];\r\n currentAmount = amounts[i];\r\n\r\n if (currentRecipient == address(0)) {\r\n revert ADDRESS_ZERO();\r\n }\r\n _increaseBalance(currentRecipient, currentAmount);\r\n\r\n emit IncreaseBalance(currentRecipient, currentAmount);\r\n\r\n unchecked {\r\n ++i;\r\n }\r\n }\r\n\r\n if (totalBalance > address(this).balance) {\r\n revert INVALID_AMOUNT();\r\n }\r\n }\r\n\r\n /// @notice internal function to increase balance\r\n /// @param to The address to increase the balance of\r\n /// @param amount The amount to increase the balance by\r\n function _increaseBalance(address to, uint256 amount) internal {\r\n balanceOf[to] += amount;\r\n totalBalance += amount;\r\n }\r\n\r\n /// @notice internal function to decrease balance\r\n /// @param to The address to decrease the balance of\r\n /// @param amount The amount to decrease the balance by\r\n function _decreaseBalance(address to, uint256 amount) internal {\r\n balanceOf[to] -= amount;\r\n totalBalance -= amount;\r\n }\r\n\r\n /// @notice Generic function to deposit ETH for multiple recipients, with an optional comment\r\n /// @param recipients recipients to send the amount to, array aligns with amounts\r\n /// @param amounts amounts to send to each recipient, array aligns with recipients\r\n /// @param reasons optional bytes4 hash for indexing\r\n /// @param comment Optional comment to include with mint\r\n function depositBatch(\r\n address[] calldata recipients,\r\n uint256[] calldata amounts,\r\n bytes4[] calldata reasons,\r\n string calldata comment\r\n ) external payable {\r\n uint256 numRecipients = recipients.length;\r\n\r\n if (numRecipients != amounts.length || numRecipients != reasons.length) {\r\n revert ARRAY_LENGTH_MISMATCH();\r\n }\r\n\r\n uint256 expectedTotalValue;\r\n\r\n for (uint256 i; i < numRecipients;) {\r\n expectedTotalValue += amounts[i];\r\n\r\n unchecked {\r\n ++i;\r\n }\r\n }\r\n\r\n if (msg.value != expectedTotalValue) {\r\n revert INVALID_DEPOSIT();\r\n }\r\n\r\n address currentRecipient;\r\n uint256 currentAmount;\r\n\r\n for (uint256 i; i < numRecipients;) {\r\n currentRecipient = recipients[i];\r\n currentAmount = amounts[i];\r\n\r\n if (currentRecipient == address(0)) {\r\n revert ADDRESS_ZERO();\r\n }\r\n\r\n _increaseBalance(currentRecipient, currentAmount);\r\n\r\n emit Deposit(msg.sender, currentRecipient, reasons[i], currentAmount, comment);\r\n\r\n unchecked {\r\n ++i;\r\n }\r\n }\r\n }\r\n\r\n /// @notice Withdraw protocol rewards\r\n /// @param to Withdraws from msg.sender to this address\r\n /// @param amount Amount to withdraw (0 for total balance)\r\n function withdraw(address to, uint256 amount) external {\r\n if (to == address(0)) {\r\n revert ADDRESS_ZERO();\r\n }\r\n\r\n address owner = msg.sender;\r\n\r\n if (amount > balanceOf[owner]) {\r\n revert INVALID_WITHDRAW();\r\n }\r\n\r\n if (amount == 0) {\r\n amount = balanceOf[owner];\r\n }\r\n\r\n _decreaseBalance(owner, amount);\r\n\r\n emit Withdraw(owner, to, amount);\r\n\r\n to.safeTransferETH(amount);\r\n }\r\n\r\n /// @notice Withdraw rewards on behalf of an address\r\n /// @param to The address to withdraw for\r\n /// @param amount The amount to withdraw (0 for total balance)\r\n function withdrawFor(address to, uint256 amount) external {\r\n if (to == address(0)) {\r\n revert ADDRESS_ZERO();\r\n }\r\n\r\n if (amount > balanceOf[to]) {\r\n revert INVALID_WITHDRAW();\r\n }\r\n\r\n if (amount == 0) {\r\n amount = balanceOf[to];\r\n }\r\n\r\n _decreaseBalance(to, amount);\r\n\r\n emit Withdraw(to, to, amount);\r\n\r\n to.safeTransferETH(amount);\r\n }\r\n\r\n // Receive function to receive ETH\r\n receive() external payable {}\r\n\r\n // Fallback function to receive ETH when other functions are not available\r\n fallback() external payable {}\r\n}\r\n"},"lib/solady/src/auth/OwnableRoles.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/// @notice Simple single owner and multiroles authorization mixin.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)\n/// @dev While the ownable portion follows [EIP-173](https://eips.ethereum.org/EIPS/eip-173)\n/// for compatibility, the nomenclature for the 2-step ownership handover and roles\n/// may be unique to this codebase.\nabstract contract OwnableRoles is Ownable {\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* EVENTS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The `user`'s roles is updated to `roles`.\n /// Each bit of `roles` represents whether the role is set.\n event RolesUpdated(address indexed user, uint256 indexed roles);\n\n /// @dev `keccak256(bytes(\"RolesUpdated(address,uint256)\"))`.\n uint256 private constant _ROLES_UPDATED_EVENT_SIGNATURE =\n 0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26;\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* STORAGE */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The role slot of `user` is given by:\n /// ```\n /// mstore(0x00, or(shl(96, user), _ROLE_SLOT_SEED))\n /// let roleSlot := keccak256(0x00, 0x20)\n /// ```\n /// This automatically ignores the upper bits of the `user` in case\n /// they are not clean, as well as keep the `keccak256` under 32-bytes.\n ///\n /// Note: This is equivalent to `uint32(bytes4(keccak256(\"_OWNER_SLOT_NOT\")))`.\n uint256 private constant _ROLE_SLOT_SEED = 0x8b78c6d8;\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* INTERNAL FUNCTIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Overwrite the roles directly without authorization guard.\n function _setRoles(address user, uint256 roles) internal virtual {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x0c, _ROLE_SLOT_SEED)\n mstore(0x00, user)\n // Store the new value.\n sstore(keccak256(0x0c, 0x20), roles)\n // Emit the {RolesUpdated} event.\n log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), roles)\n }\n }\n\n /// @dev Updates the roles directly without authorization guard.\n /// If `on` is true, each set bit of `roles` will be turned on,\n /// otherwise, each set bit of `roles` will be turned off.\n function _updateRoles(address user, uint256 roles, bool on) internal virtual {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x0c, _ROLE_SLOT_SEED)\n mstore(0x00, user)\n let roleSlot := keccak256(0x0c, 0x20)\n // Load the current value.\n let current := sload(roleSlot)\n // Compute the updated roles if `on` is true.\n let updated := or(current, roles)\n // Compute the updated roles if `on` is false.\n // Use `and` to compute the intersection of `current` and `roles`,\n // `xor` it with `current` to flip the bits in the intersection.\n if iszero(on) { updated := xor(current, and(current, roles)) }\n // Then, store the new value.\n sstore(roleSlot, updated)\n // Emit the {RolesUpdated} event.\n log3(0, 0, _ROLES_UPDATED_EVENT_SIGNATURE, shr(96, mload(0x0c)), updated)\n }\n }\n\n /// @dev Grants the roles directly without authorization guard.\n /// Each bit of `roles` represents the role to turn on.\n function _grantRoles(address user, uint256 roles) internal virtual {\n _updateRoles(user, roles, true);\n }\n\n /// @dev Removes the roles directly without authorization guard.\n /// Each bit of `roles` represents the role to turn off.\n function _removeRoles(address user, uint256 roles) internal virtual {\n _updateRoles(user, roles, false);\n }\n\n /// @dev Throws if the sender does not have any of the `roles`.\n function _checkRoles(uint256 roles) internal view virtual {\n /// @solidity memory-safe-assembly\n assembly {\n // Compute the role slot.\n mstore(0x0c, _ROLE_SLOT_SEED)\n mstore(0x00, caller())\n // Load the stored value, and if the `and` intersection\n // of the value and `roles` is zero, revert.\n if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {\n mstore(0x00, 0x82b42900) // `Unauthorized()`.\n revert(0x1c, 0x04)\n }\n }\n }\n\n /// @dev Throws if the sender is not the owner,\n /// and does not have any of the `roles`.\n /// Checks for ownership first, then lazily checks for roles.\n function _checkOwnerOrRoles(uint256 roles) internal view virtual {\n /// @solidity memory-safe-assembly\n assembly {\n // If the caller is not the stored owner.\n // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.\n if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {\n // Compute the role slot.\n mstore(0x0c, _ROLE_SLOT_SEED)\n mstore(0x00, caller())\n // Load the stored value, and if the `and` intersection\n // of the value and `roles` is zero, revert.\n if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {\n mstore(0x00, 0x82b42900) // `Unauthorized()`.\n revert(0x1c, 0x04)\n }\n }\n }\n }\n\n /// @dev Throws if the sender does not have any of the `roles`,\n /// and is not the owner.\n /// Checks for roles first, then lazily checks for ownership.\n function _checkRolesOrOwner(uint256 roles) internal view virtual {\n /// @solidity memory-safe-assembly\n assembly {\n // Compute the role slot.\n mstore(0x0c, _ROLE_SLOT_SEED)\n mstore(0x00, caller())\n // Load the stored value, and if the `and` intersection\n // of the value and `roles` is zero, revert.\n if iszero(and(sload(keccak256(0x0c, 0x20)), roles)) {\n // If the caller is not the stored owner.\n // Note: `_ROLE_SLOT_SEED` is equal to `_OWNER_SLOT_NOT`.\n if iszero(eq(caller(), sload(not(_ROLE_SLOT_SEED)))) {\n mstore(0x00, 0x82b42900) // `Unauthorized()`.\n revert(0x1c, 0x04)\n }\n }\n }\n }\n\n /// @dev Convenience function to return a `roles` bitmap from an array of `ordinals`.\n /// This is meant for frontends like Etherscan, and is therefore not fully optimized.\n /// Not recommended to be called on-chain.\n /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n function _rolesFromOrdinals(uint8[] memory ordinals) internal pure returns (uint256 roles) {\n /// @solidity memory-safe-assembly\n assembly {\n for { let i := shl(5, mload(ordinals)) } i { i := sub(i, 0x20) } {\n // We don't need to mask the values of `ordinals`, as Solidity\n // cleans dirty upper bits when storing variables into memory.\n roles := or(shl(mload(add(ordinals, i)), 1), roles)\n }\n }\n }\n\n /// @dev Convenience function to return an array of `ordinals` from the `roles` bitmap.\n /// This is meant for frontends like Etherscan, and is therefore not fully optimized.\n /// Not recommended to be called on-chain.\n /// Made internal to conserve bytecode. Wrap it in a public function if needed.\n function _ordinalsFromRoles(uint256 roles) internal pure returns (uint8[] memory ordinals) {\n /// @solidity memory-safe-assembly\n assembly {\n // Grab the pointer to the free memory.\n ordinals := mload(0x40)\n let ptr := add(ordinals, 0x20)\n let o := 0\n // The absence of lookup tables, De Bruijn, etc., here is intentional for\n // smaller bytecode, as this function is not meant to be called on-chain.\n for { let t := roles } 1 {} {\n mstore(ptr, o)\n // `shr` 5 is equivalent to multiplying by 0x20.\n // Push back into the ordinals array if the bit is set.\n ptr := add(ptr, shl(5, and(t, 1)))\n o := add(o, 1)\n t := shr(o, roles)\n if iszero(t) { break }\n }\n // Store the length of `ordinals`.\n mstore(ordinals, shr(5, sub(ptr, add(ordinals, 0x20))))\n // Allocate the memory.\n mstore(0x40, ptr)\n }\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* PUBLIC UPDATE FUNCTIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Allows the owner to grant `user` `roles`.\n /// If the `user` already has a role, then it will be an no-op for the role.\n function grantRoles(address user, uint256 roles) public payable virtual onlyOwner {\n _grantRoles(user, roles);\n }\n\n /// @dev Allows the owner to remove `user` `roles`.\n /// If the `user` does not have a role, then it will be an no-op for the role.\n function revokeRoles(address user, uint256 roles) public payable virtual onlyOwner {\n _removeRoles(user, roles);\n }\n\n /// @dev Allow the caller to remove their own roles.\n /// If the caller does not have a role, then it will be an no-op for the role.\n function renounceRoles(uint256 roles) public payable virtual {\n _removeRoles(msg.sender, roles);\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* PUBLIC READ FUNCTIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Returns the roles of `user`.\n function rolesOf(address user) public view virtual returns (uint256 roles) {\n /// @solidity memory-safe-assembly\n assembly {\n // Compute the role slot.\n mstore(0x0c, _ROLE_SLOT_SEED)\n mstore(0x00, user)\n // Load the stored value.\n roles := sload(keccak256(0x0c, 0x20))\n }\n }\n\n /// @dev Returns whether `user` has any of `roles`.\n function hasAnyRole(address user, uint256 roles) public view virtual returns (bool) {\n return rolesOf(user) & roles != 0;\n }\n\n /// @dev Returns whether `user` has all of `roles`.\n function hasAllRoles(address user, uint256 roles) public view virtual returns (bool) {\n return rolesOf(user) & roles == roles;\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* MODIFIERS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Marks a function as only callable by an account with `roles`.\n modifier onlyRoles(uint256 roles) virtual {\n _checkRoles(roles);\n _;\n }\n\n /// @dev Marks a function as only callable by the owner or by an account\n /// with `roles`. Checks for ownership first, then lazily checks for roles.\n modifier onlyOwnerOrRoles(uint256 roles) virtual {\n _checkOwnerOrRoles(roles);\n _;\n }\n\n /// @dev Marks a function as only callable by an account with `roles`\n /// or the owner. Checks for roles first, then lazily checks for ownership.\n modifier onlyRolesOrOwner(uint256 roles) virtual {\n _checkRolesOrOwner(roles);\n _;\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* ROLE CONSTANTS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n // IYKYK\n\n uint256 internal constant _ROLE_0 = 1 << 0;\n uint256 internal constant _ROLE_1 = 1 << 1;\n uint256 internal constant _ROLE_2 = 1 << 2;\n uint256 internal constant _ROLE_3 = 1 << 3;\n uint256 internal constant _ROLE_4 = 1 << 4;\n uint256 internal constant _ROLE_5 = 1 << 5;\n uint256 internal constant _ROLE_6 = 1 << 6;\n uint256 internal constant _ROLE_7 = 1 << 7;\n uint256 internal constant _ROLE_8 = 1 << 8;\n uint256 internal constant _ROLE_9 = 1 << 9;\n uint256 internal constant _ROLE_10 = 1 << 10;\n uint256 internal constant _ROLE_11 = 1 << 11;\n uint256 internal constant _ROLE_12 = 1 << 12;\n uint256 internal constant _ROLE_13 = 1 << 13;\n uint256 internal constant _ROLE_14 = 1 << 14;\n uint256 internal constant _ROLE_15 = 1 << 15;\n uint256 internal constant _ROLE_16 = 1 << 16;\n uint256 internal constant _ROLE_17 = 1 << 17;\n uint256 internal constant _ROLE_18 = 1 << 18;\n uint256 internal constant _ROLE_19 = 1 << 19;\n uint256 internal constant _ROLE_20 = 1 << 20;\n uint256 internal constant _ROLE_21 = 1 << 21;\n uint256 internal constant _ROLE_22 = 1 << 22;\n uint256 internal constant _ROLE_23 = 1 << 23;\n uint256 internal constant _ROLE_24 = 1 << 24;\n uint256 internal constant _ROLE_25 = 1 << 25;\n uint256 internal constant _ROLE_26 = 1 << 26;\n uint256 internal constant _ROLE_27 = 1 << 27;\n uint256 internal constant _ROLE_28 = 1 << 28;\n uint256 internal constant _ROLE_29 = 1 << 29;\n uint256 internal constant _ROLE_30 = 1 << 30;\n uint256 internal constant _ROLE_31 = 1 << 31;\n uint256 internal constant _ROLE_32 = 1 << 32;\n uint256 internal constant _ROLE_33 = 1 << 33;\n uint256 internal constant _ROLE_34 = 1 << 34;\n uint256 internal constant _ROLE_35 = 1 << 35;\n uint256 internal constant _ROLE_36 = 1 << 36;\n uint256 internal constant _ROLE_37 = 1 << 37;\n uint256 internal constant _ROLE_38 = 1 << 38;\n uint256 internal constant _ROLE_39 = 1 << 39;\n uint256 internal constant _ROLE_40 = 1 << 40;\n uint256 internal constant _ROLE_41 = 1 << 41;\n uint256 internal constant _ROLE_42 = 1 << 42;\n uint256 internal constant _ROLE_43 = 1 << 43;\n uint256 internal constant _ROLE_44 = 1 << 44;\n uint256 internal constant _ROLE_45 = 1 << 45;\n uint256 internal constant _ROLE_46 = 1 << 46;\n uint256 internal constant _ROLE_47 = 1 << 47;\n uint256 internal constant _ROLE_48 = 1 << 48;\n uint256 internal constant _ROLE_49 = 1 << 49;\n uint256 internal constant _ROLE_50 = 1 << 50;\n uint256 internal constant _ROLE_51 = 1 << 51;\n uint256 internal constant _ROLE_52 = 1 << 52;\n uint256 internal constant _ROLE_53 = 1 << 53;\n uint256 internal constant _ROLE_54 = 1 << 54;\n uint256 internal constant _ROLE_55 = 1 << 55;\n uint256 internal constant _ROLE_56 = 1 << 56;\n uint256 internal constant _ROLE_57 = 1 << 57;\n uint256 internal constant _ROLE_58 = 1 << 58;\n uint256 internal constant _ROLE_59 = 1 << 59;\n uint256 internal constant _ROLE_60 = 1 << 60;\n uint256 internal constant _ROLE_61 = 1 << 61;\n uint256 internal constant _ROLE_62 = 1 << 62;\n uint256 internal constant _ROLE_63 = 1 << 63;\n uint256 internal constant _ROLE_64 = 1 << 64;\n uint256 internal constant _ROLE_65 = 1 << 65;\n uint256 internal constant _ROLE_66 = 1 << 66;\n uint256 internal constant _ROLE_67 = 1 << 67;\n uint256 internal constant _ROLE_68 = 1 << 68;\n uint256 internal constant _ROLE_69 = 1 << 69;\n uint256 internal constant _ROLE_70 = 1 << 70;\n uint256 internal constant _ROLE_71 = 1 << 71;\n uint256 internal constant _ROLE_72 = 1 << 72;\n uint256 internal constant _ROLE_73 = 1 << 73;\n uint256 internal constant _ROLE_74 = 1 << 74;\n uint256 internal constant _ROLE_75 = 1 << 75;\n uint256 internal constant _ROLE_76 = 1 << 76;\n uint256 internal constant _ROLE_77 = 1 << 77;\n uint256 internal constant _ROLE_78 = 1 << 78;\n uint256 internal constant _ROLE_79 = 1 << 79;\n uint256 internal constant _ROLE_80 = 1 << 80;\n uint256 internal constant _ROLE_81 = 1 << 81;\n uint256 internal constant _ROLE_82 = 1 << 82;\n uint256 internal constant _ROLE_83 = 1 << 83;\n uint256 internal constant _ROLE_84 = 1 << 84;\n uint256 internal constant _ROLE_85 = 1 << 85;\n uint256 internal constant _ROLE_86 = 1 << 86;\n uint256 internal constant _ROLE_87 = 1 << 87;\n uint256 internal constant _ROLE_88 = 1 << 88;\n uint256 internal constant _ROLE_89 = 1 << 89;\n uint256 internal constant _ROLE_90 = 1 << 90;\n uint256 internal constant _ROLE_91 = 1 << 91;\n uint256 internal constant _ROLE_92 = 1 << 92;\n uint256 internal constant _ROLE_93 = 1 << 93;\n uint256 internal constant _ROLE_94 = 1 << 94;\n uint256 internal constant _ROLE_95 = 1 << 95;\n uint256 internal constant _ROLE_96 = 1 << 96;\n uint256 internal constant _ROLE_97 = 1 << 97;\n uint256 internal constant _ROLE_98 = 1 << 98;\n uint256 internal constant _ROLE_99 = 1 << 99;\n uint256 internal constant _ROLE_100 = 1 << 100;\n uint256 internal constant _ROLE_101 = 1 << 101;\n uint256 internal constant _ROLE_102 = 1 << 102;\n uint256 internal constant _ROLE_103 = 1 << 103;\n uint256 internal constant _ROLE_104 = 1 << 104;\n uint256 internal constant _ROLE_105 = 1 << 105;\n uint256 internal constant _ROLE_106 = 1 << 106;\n uint256 internal constant _ROLE_107 = 1 << 107;\n uint256 internal constant _ROLE_108 = 1 << 108;\n uint256 internal constant _ROLE_109 = 1 << 109;\n uint256 internal constant _ROLE_110 = 1 << 110;\n uint256 internal constant _ROLE_111 = 1 << 111;\n uint256 internal constant _ROLE_112 = 1 << 112;\n uint256 internal constant _ROLE_113 = 1 << 113;\n uint256 internal constant _ROLE_114 = 1 << 114;\n uint256 internal constant _ROLE_115 = 1 << 115;\n uint256 internal constant _ROLE_116 = 1 << 116;\n uint256 internal constant _ROLE_117 = 1 << 117;\n uint256 internal constant _ROLE_118 = 1 << 118;\n uint256 internal constant _ROLE_119 = 1 << 119;\n uint256 internal constant _ROLE_120 = 1 << 120;\n uint256 internal constant _ROLE_121 = 1 << 121;\n uint256 internal constant _ROLE_122 = 1 << 122;\n uint256 internal constant _ROLE_123 = 1 << 123;\n uint256 internal constant _ROLE_124 = 1 << 124;\n uint256 internal constant _ROLE_125 = 1 << 125;\n uint256 internal constant _ROLE_126 = 1 << 126;\n uint256 internal constant _ROLE_127 = 1 << 127;\n uint256 internal constant _ROLE_128 = 1 << 128;\n uint256 internal constant _ROLE_129 = 1 << 129;\n uint256 internal constant _ROLE_130 = 1 << 130;\n uint256 internal constant _ROLE_131 = 1 << 131;\n uint256 internal constant _ROLE_132 = 1 << 132;\n uint256 internal constant _ROLE_133 = 1 << 133;\n uint256 internal constant _ROLE_134 = 1 << 134;\n uint256 internal constant _ROLE_135 = 1 << 135;\n uint256 internal constant _ROLE_136 = 1 << 136;\n uint256 internal constant _ROLE_137 = 1 << 137;\n uint256 internal constant _ROLE_138 = 1 << 138;\n uint256 internal constant _ROLE_139 = 1 << 139;\n uint256 internal constant _ROLE_140 = 1 << 140;\n uint256 internal constant _ROLE_141 = 1 << 141;\n uint256 internal constant _ROLE_142 = 1 << 142;\n uint256 internal constant _ROLE_143 = 1 << 143;\n uint256 internal constant _ROLE_144 = 1 << 144;\n uint256 internal constant _ROLE_145 = 1 << 145;\n uint256 internal constant _ROLE_146 = 1 << 146;\n uint256 internal constant _ROLE_147 = 1 << 147;\n uint256 internal constant _ROLE_148 = 1 << 148;\n uint256 internal constant _ROLE_149 = 1 << 149;\n uint256 internal constant _ROLE_150 = 1 << 150;\n uint256 internal constant _ROLE_151 = 1 << 151;\n uint256 internal constant _ROLE_152 = 1 << 152;\n uint256 internal constant _ROLE_153 = 1 << 153;\n uint256 internal constant _ROLE_154 = 1 << 154;\n uint256 internal constant _ROLE_155 = 1 << 155;\n uint256 internal constant _ROLE_156 = 1 << 156;\n uint256 internal constant _ROLE_157 = 1 << 157;\n uint256 internal constant _ROLE_158 = 1 << 158;\n uint256 internal constant _ROLE_159 = 1 << 159;\n uint256 internal constant _ROLE_160 = 1 << 160;\n uint256 internal constant _ROLE_161 = 1 << 161;\n uint256 internal constant _ROLE_162 = 1 << 162;\n uint256 internal constant _ROLE_163 = 1 << 163;\n uint256 internal constant _ROLE_164 = 1 << 164;\n uint256 internal constant _ROLE_165 = 1 << 165;\n uint256 internal constant _ROLE_166 = 1 << 166;\n uint256 internal constant _ROLE_167 = 1 << 167;\n uint256 internal constant _ROLE_168 = 1 << 168;\n uint256 internal constant _ROLE_169 = 1 << 169;\n uint256 internal constant _ROLE_170 = 1 << 170;\n uint256 internal constant _ROLE_171 = 1 << 171;\n uint256 internal constant _ROLE_172 = 1 << 172;\n uint256 internal constant _ROLE_173 = 1 << 173;\n uint256 internal constant _ROLE_174 = 1 << 174;\n uint256 internal constant _ROLE_175 = 1 << 175;\n uint256 internal constant _ROLE_176 = 1 << 176;\n uint256 internal constant _ROLE_177 = 1 << 177;\n uint256 internal constant _ROLE_178 = 1 << 178;\n uint256 internal constant _ROLE_179 = 1 << 179;\n uint256 internal constant _ROLE_180 = 1 << 180;\n uint256 internal constant _ROLE_181 = 1 << 181;\n uint256 internal constant _ROLE_182 = 1 << 182;\n uint256 internal constant _ROLE_183 = 1 << 183;\n uint256 internal constant _ROLE_184 = 1 << 184;\n uint256 internal constant _ROLE_185 = 1 << 185;\n uint256 internal constant _ROLE_186 = 1 << 186;\n uint256 internal constant _ROLE_187 = 1 << 187;\n uint256 internal constant _ROLE_188 = 1 << 188;\n uint256 internal constant _ROLE_189 = 1 << 189;\n uint256 internal constant _ROLE_190 = 1 << 190;\n uint256 internal constant _ROLE_191 = 1 << 191;\n uint256 internal constant _ROLE_192 = 1 << 192;\n uint256 internal constant _ROLE_193 = 1 << 193;\n uint256 internal constant _ROLE_194 = 1 << 194;\n uint256 internal constant _ROLE_195 = 1 << 195;\n uint256 internal constant _ROLE_196 = 1 << 196;\n uint256 internal constant _ROLE_197 = 1 << 197;\n uint256 internal constant _ROLE_198 = 1 << 198;\n uint256 internal constant _ROLE_199 = 1 << 199;\n uint256 internal constant _ROLE_200 = 1 << 200;\n uint256 internal constant _ROLE_201 = 1 << 201;\n uint256 internal constant _ROLE_202 = 1 << 202;\n uint256 internal constant _ROLE_203 = 1 << 203;\n uint256 internal constant _ROLE_204 = 1 << 204;\n uint256 internal constant _ROLE_205 = 1 << 205;\n uint256 internal constant _ROLE_206 = 1 << 206;\n uint256 internal constant _ROLE_207 = 1 << 207;\n uint256 internal constant _ROLE_208 = 1 << 208;\n uint256 internal constant _ROLE_209 = 1 << 209;\n uint256 internal constant _ROLE_210 = 1 << 210;\n uint256 internal constant _ROLE_211 = 1 << 211;\n uint256 internal constant _ROLE_212 = 1 << 212;\n uint256 internal constant _ROLE_213 = 1 << 213;\n uint256 internal constant _ROLE_214 = 1 << 214;\n uint256 internal constant _ROLE_215 = 1 << 215;\n uint256 internal constant _ROLE_216 = 1 << 216;\n uint256 internal constant _ROLE_217 = 1 << 217;\n uint256 internal constant _ROLE_218 = 1 << 218;\n uint256 internal constant _ROLE_219 = 1 << 219;\n uint256 internal constant _ROLE_220 = 1 << 220;\n uint256 internal constant _ROLE_221 = 1 << 221;\n uint256 internal constant _ROLE_222 = 1 << 222;\n uint256 internal constant _ROLE_223 = 1 << 223;\n uint256 internal constant _ROLE_224 = 1 << 224;\n uint256 internal constant _ROLE_225 = 1 << 225;\n uint256 internal constant _ROLE_226 = 1 << 226;\n uint256 internal constant _ROLE_227 = 1 << 227;\n uint256 internal constant _ROLE_228 = 1 << 228;\n uint256 internal constant _ROLE_229 = 1 << 229;\n uint256 internal constant _ROLE_230 = 1 << 230;\n uint256 internal constant _ROLE_231 = 1 << 231;\n uint256 internal constant _ROLE_232 = 1 << 232;\n uint256 internal constant _ROLE_233 = 1 << 233;\n uint256 internal constant _ROLE_234 = 1 << 234;\n uint256 internal constant _ROLE_235 = 1 << 235;\n uint256 internal constant _ROLE_236 = 1 << 236;\n uint256 internal constant _ROLE_237 = 1 << 237;\n uint256 internal constant _ROLE_238 = 1 << 238;\n uint256 internal constant _ROLE_239 = 1 << 239;\n uint256 internal constant _ROLE_240 = 1 << 240;\n uint256 internal constant _ROLE_241 = 1 << 241;\n uint256 internal constant _ROLE_242 = 1 << 242;\n uint256 internal constant _ROLE_243 = 1 << 243;\n uint256 internal constant _ROLE_244 = 1 << 244;\n uint256 internal constant _ROLE_245 = 1 << 245;\n uint256 internal constant _ROLE_246 = 1 << 246;\n uint256 internal constant _ROLE_247 = 1 << 247;\n uint256 internal constant _ROLE_248 = 1 << 248;\n uint256 internal constant _ROLE_249 = 1 << 249;\n uint256 internal constant _ROLE_250 = 1 << 250;\n uint256 internal constant _ROLE_251 = 1 << 251;\n uint256 internal constant _ROLE_252 = 1 << 252;\n uint256 internal constant _ROLE_253 = 1 << 253;\n uint256 internal constant _ROLE_254 = 1 << 254;\n uint256 internal constant _ROLE_255 = 1 << 255;\n}\n"},"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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 * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\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, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"},"lib/solady/src/utils/SafeTransferLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n///\n/// @dev Note:\n/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.\n/// - For ERC20s, this implementation won't check that a token has code,\n/// responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* CUSTOM ERRORS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev The ETH transfer has failed.\n error ETHTransferFailed();\n\n /// @dev The ERC20 `transferFrom` has failed.\n error TransferFromFailed();\n\n /// @dev The ERC20 `transfer` has failed.\n error TransferFailed();\n\n /// @dev The ERC20 `approve` has failed.\n error ApproveFailed();\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* CONSTANTS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.\n uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;\n\n /// @dev Suggested gas stipend for contract receiving ETH to perform a few\n /// storage reads and writes, but low enough to prevent griefing.\n uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* ETH OPERATIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.\n //\n // The regular variants:\n // - Forwards all remaining gas to the target.\n // - Reverts if the target reverts.\n // - Reverts if the current contract has insufficient balance.\n //\n // The force variants:\n // - Forwards with an optional gas stipend\n // (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).\n // - If the target reverts, or if the gas stipend is exhausted,\n // creates a temporary contract to force send the ETH via `SELFDESTRUCT`.\n // Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.\n // - Reverts if the current contract has insufficient balance.\n //\n // The try variants:\n // - Forwards with a mandatory gas stipend.\n // - Instead of reverting, returns whether the transfer succeeded.\n\n /// @dev Sends `amount` (in wei) ETH to `to`.\n function safeTransferETH(address to, uint256 amount) internal {\n /// @solidity memory-safe-assembly\n assembly {\n if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {\n mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n revert(0x1c, 0x04)\n }\n }\n }\n\n /// @dev Sends all the ETH in the current contract to `to`.\n function safeTransferAllETH(address to) internal {\n /// @solidity memory-safe-assembly\n assembly {\n // Transfer all the ETH and check if it succeeded or not.\n if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n revert(0x1c, 0x04)\n }\n }\n }\n\n /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {\n /// @solidity memory-safe-assembly\n assembly {\n if lt(selfbalance(), amount) {\n mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n revert(0x1c, 0x04)\n }\n if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {\n mstore(0x00, to) // Store the address in scratch space.\n mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n }\n }\n }\n\n /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.\n function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {\n /// @solidity memory-safe-assembly\n assembly {\n if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n mstore(0x00, to) // Store the address in scratch space.\n mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n }\n }\n }\n\n /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.\n function forceSafeTransferETH(address to, uint256 amount) internal {\n /// @solidity memory-safe-assembly\n assembly {\n if lt(selfbalance(), amount) {\n mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n revert(0x1c, 0x04)\n }\n if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {\n mstore(0x00, to) // Store the address in scratch space.\n mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n }\n }\n }\n\n /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.\n function forceSafeTransferAllETH(address to) internal {\n /// @solidity memory-safe-assembly\n assembly {\n // forgefmt: disable-next-item\n if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {\n mstore(0x00, to) // Store the address in scratch space.\n mstore8(0x0b, 0x73) // Opcode `PUSH20`.\n mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.\n if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.\n }\n }\n }\n\n /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.\n function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)\n internal\n returns (bool success)\n {\n /// @solidity memory-safe-assembly\n assembly {\n success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)\n }\n }\n\n /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.\n function trySafeTransferAllETH(address to, uint256 gasStipend)\n internal\n returns (bool success)\n {\n /// @solidity memory-safe-assembly\n assembly {\n success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)\n }\n }\n\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n /* ERC20 OPERATIONS */\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.\n /// Reverts upon failure.\n ///\n /// The `from` account must have at least `amount` approved for\n /// the current contract to manage.\n function safeTransferFrom(address token, address from, address to, uint256 amount) internal {\n /// @solidity memory-safe-assembly\n assembly {\n let m := mload(0x40) // Cache the free memory pointer.\n mstore(0x60, amount) // Store the `amount` argument.\n mstore(0x40, to) // Store the `to` argument.\n mstore(0x2c, shl(96, from)) // Store the `from` argument.\n mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.\n // Perform the transfer, reverting upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n )\n ) {\n mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n revert(0x1c, 0x04)\n }\n mstore(0x60, 0) // Restore the zero slot to zero.\n mstore(0x40, m) // Restore the free memory pointer.\n }\n }\n\n /// @dev Sends all of ERC20 `token` from `from` to `to`.\n /// Reverts upon failure.\n ///\n /// The `from` account must have their entire balance approved for\n /// the current contract to manage.\n function safeTransferAllFrom(address token, address from, address to)\n internal\n returns (uint256 amount)\n {\n /// @solidity memory-safe-assembly\n assembly {\n let m := mload(0x40) // Cache the free memory pointer.\n mstore(0x40, to) // Store the `to` argument.\n mstore(0x2c, shl(96, from)) // Store the `from` argument.\n mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.\n // Read the balance, reverting upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)\n )\n ) {\n mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n revert(0x1c, 0x04)\n }\n mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.\n amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.\n // Perform the transfer, reverting upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)\n )\n ) {\n mstore(0x00, 0x7939f424) // `TransferFromFailed()`.\n revert(0x1c, 0x04)\n }\n mstore(0x60, 0) // Restore the zero slot to zero.\n mstore(0x40, m) // Restore the free memory pointer.\n }\n }\n\n /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.\n /// Reverts upon failure.\n function safeTransfer(address token, address to, uint256 amount) internal {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x14, to) // Store the `to` argument.\n mstore(0x34, amount) // Store the `amount` argument.\n mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.\n // Perform the transfer, reverting upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n )\n ) {\n mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n revert(0x1c, 0x04)\n }\n mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n }\n }\n\n /// @dev Sends all of ERC20 `token` from the current contract to `to`.\n /// Reverts upon failure.\n function safeTransferAll(address token, address to) internal returns (uint256 amount) {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.\n mstore(0x20, address()) // Store the address of the current contract.\n // Read the balance, reverting upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)\n )\n ) {\n mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n revert(0x1c, 0x04)\n }\n mstore(0x14, to) // Store the `to` argument.\n amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.\n mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.\n // Perform the transfer, reverting upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n )\n ) {\n mstore(0x00, 0x90b8ec18) // `TransferFailed()`.\n revert(0x1c, 0x04)\n }\n mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n }\n }\n\n /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.\n /// Reverts upon failure.\n function safeApprove(address token, address to, uint256 amount) internal {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x14, to) // Store the `to` argument.\n mstore(0x34, amount) // Store the `amount` argument.\n mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n // Perform the approval, reverting upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n )\n ) {\n mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.\n revert(0x1c, 0x04)\n }\n mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n }\n }\n\n /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.\n /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,\n /// then retries the approval again (some tokens, e.g. USDT, requires this).\n /// Reverts upon failure.\n function safeApproveWithRetry(address token, address to, uint256 amount) internal {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x14, to) // Store the `to` argument.\n mstore(0x34, amount) // Store the `amount` argument.\n mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n // Perform the approval, retrying upon failure.\n if iszero(\n and( // The arguments of `and` are evaluated from right to left.\n or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n )\n ) {\n mstore(0x34, 0) // Store 0 for the `amount`.\n mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.\n pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.\n mstore(0x34, amount) // Store back the original `amount`.\n // Retry the approval, reverting upon failure.\n if iszero(\n and(\n or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.\n call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)\n )\n ) {\n mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.\n revert(0x1c, 0x04)\n }\n }\n mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.\n }\n }\n\n /// @dev Returns the amount of ERC20 `token` owned by `account`.\n /// Returns zero if the `token` does not exist.\n function balanceOf(address token, address account) internal view returns (uint256 amount) {\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x14, account) // Store the `account` argument.\n mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.\n amount :=\n mul(\n mload(0x20),\n and( // The arguments of `and` are evaluated from right to left.\n gt(returndatasize(), 0x1f), // At least 32 bytes returned.\n staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)\n )\n )\n }\n }\n}\n"},"contracts/interfaces/IProtocolRewards.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\n/// @title IProtocolRewards\r\n/// @notice The interface for deposits & withdrawals for Protocol Rewards\r\ninterface IProtocolRewards {\r\n /// @notice Deposit Event\r\n /// @param from From user\r\n /// @param to To user (within contract)\r\n /// @param reason Optional bytes4 reason for indexing\r\n /// @param amount Amount of deposit\r\n /// @param comment Optional user comment\r\n event Deposit(address indexed from, address indexed to, bytes4 indexed reason, uint256 amount, string comment);\r\n\r\n /// @notice IncreaseBalance Event\r\n /// @param to To user (within contract)\r\n /// @param amount Amount of deposit\r\n event IncreaseBalance(address indexed to, uint256 amount);\r\n\r\n /// @notice Withdraw Event\r\n /// @param from From user\r\n /// @param to To user (within contract)\r\n /// @param amount Amount of deposit\r\n event Withdraw(address indexed from, address indexed to, uint256 amount);\r\n\r\n /// @notice TransferExcessSupply Event\r\n /// @param from From user\r\n /// @param to To user (within contract)\r\n /// @param amount Amount of deposit\r\n event TransferExcessSupply(address indexed from, address indexed to, uint256 amount);\r\n\r\n /// @notice Cannot send to address zero\r\n error ADDRESS_ZERO();\r\n\r\n /// @notice Function argument array length mismatch\r\n error ARRAY_LENGTH_MISMATCH();\r\n\r\n /// @notice Invalid deposit\r\n error INVALID_DEPOSIT();\r\n\r\n /// @notice Invalid withdraw\r\n error INVALID_WITHDRAW();\r\n\r\n error INVALID_AMOUNT();\r\n\r\n /// @notice Generic function to deposit ETH for a recipient, with an optional comment\r\n /// @param to Address to deposit to\r\n /// @param to Reason system reason for deposit (used for indexing)\r\n /// @param comment Optional comment as reason for deposit\r\n function deposit(address to, bytes4 why, string calldata comment) external payable;\r\n\r\n /// @notice Generic function to deposit ETH for multiple recipients, with an optional comment\r\n /// @param recipients recipients to send the amount to, array aligns with amounts\r\n /// @param amounts amounts to send to each recipient, array aligns with recipients\r\n /// @param reasons optional bytes4 hash for indexing\r\n /// @param comment Optional comment to include with mint\r\n function depositBatch(\r\n address[] calldata recipients,\r\n uint256[] calldata amounts,\r\n bytes4[] calldata reasons,\r\n string calldata comment\r\n ) external payable;\r\n\r\n /// @notice Withdraw protocol rewards\r\n /// @param to Withdraws from msg.sender to this address\r\n /// @param amount amount to withdraw\r\n function withdraw(address to, uint256 amount) external;\r\n\r\n function excessSupply() external view returns (uint256);\r\n\r\n /// @param to Increase the balance of an address\r\n /// @param amount Amount to increase by\r\n function increaseBalance(address to, uint256 amount) external;\r\n\r\n /// @param to array of addresses to increase the balance of\r\n /// @param amounts Amounts to increase by\r\n function increaseBalanceBatch(address[] calldata to, uint256[] calldata amounts) external;\r\n}\r\n"},"lib/solady/src/auth/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.4;\r\n\r\n/// @notice Simple single owner authorization mixin.\r\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)\r\n///\r\n/// @dev Note:\r\n/// This implementation does NOT auto-initialize the owner to `msg.sender`.\r\n/// You MUST call the `_initializeOwner` in the constructor / initializer.\r\n///\r\n/// While the ownable portion follows\r\n/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,\r\n/// the nomenclature for the 2-step ownership handover may be unique to this codebase.\r\nabstract contract Ownable {\r\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\r\n /* CUSTOM ERRORS */\r\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\r\n\r\n /// @dev The caller is not authorized to call the function.\r\n error Unauthorized();\r\n\r\n /// @dev The `newOwner` cannot be the zero address.\r\n error NewOwnerIsZeroAddress();\r\n\r\n /// @dev The `pendingOwner` does not have a valid handover request.\r\n error NoHandoverRequest();\r\n\r\n /// @dev Cannot double-initialize.\r\n error AlreadyInitialized();\r\n\r\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\r\n /* EVENTS */\r\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\r\n\r\n /// @dev The ownership is transferred from `oldOwner` to `newOwner`.\r\n /// This event is intentionally kept the same as OpenZeppelin's Ownable to be\r\n /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),\r\n /// despite it not being as lightweight as a single argument event.\r\n event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);\r\n\r\n /// @dev An ownership handover to `pendingOwner` has been requested.\r\n event OwnershipHandoverRequested(address indexed pendingOwner);\r\n\r\n /// @dev The ownership handover to `pendingOwner` has been canceled.\r\n event OwnershipHandoverCanceled(address indexed pendingOwner);\r\n\r\n /// @dev `keccak256(bytes(\"OwnershipTransferred(address,address)\"))`.\r\n uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =\r\n 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;\r\n\r\n /// @dev `keccak256(bytes(\"OwnershipHandoverRequested(address)\"))`.\r\n uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =\r\n 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;\r\n\r\n /// @dev `keccak256(bytes(\"OwnershipHandoverCanceled(address)\"))`.\r\n uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =\r\n 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;\r\n\r\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\r\n /* STORAGE */\r\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\r\n\r\n /// @dev The owner slot is given by:\r\n /// `bytes32(~uint256(uint32(bytes4(keccak256(\"_OWNER_SLOT_NOT\")))))`.\r\n /// It is intentionally chosen to be a high value\r\n /// to avoid collision with lower slots.\r\n /// The choice of manual storage layout is to enable compatibility\r\n /// with both regular and upgradeable contracts.\r\n bytes32 internal constant _OWNER_SLOT =\r\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;\r\n\r\n /// The ownership handover slot of `newOwner` is given by:\r\n /// ```\r\n /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))\r\n /// let handoverSlot := keccak256(0x00, 0x20)\r\n /// ```\r\n /// It stores the expiry timestamp of the two-step ownership handover.\r\n uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;\r\n\r\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\r\n /* INTERNAL FUNCTIONS */\r\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\r\n\r\n /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.\r\n function _guardInitializeOwner() internal pure virtual returns (bool guard) {}\r\n\r\n /// @dev Initializes the owner directly without authorization guard.\r\n /// This function must be called upon initialization,\r\n /// regardless of whether the contract is upgradeable or not.\r\n /// This is to enable generalization to both regular and upgradeable contracts,\r\n /// and to save gas in case the initial owner is not the caller.\r\n /// For performance reasons, this function will not check if there\r\n /// is an existing owner.\r\n function _initializeOwner(address newOwner) internal virtual {\r\n if (_guardInitializeOwner()) {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n let ownerSlot := _OWNER_SLOT\r\n if sload(ownerSlot) {\r\n mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.\r\n revert(0x1c, 0x04)\r\n }\r\n // Clean the upper 96 bits.\r\n newOwner := shr(96, shl(96, newOwner))\r\n // Store the new value.\r\n sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\r\n // Emit the {OwnershipTransferred} event.\r\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\r\n }\r\n } else {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n // Clean the upper 96 bits.\r\n newOwner := shr(96, shl(96, newOwner))\r\n // Store the new value.\r\n sstore(_OWNER_SLOT, newOwner)\r\n // Emit the {OwnershipTransferred} event.\r\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)\r\n }\r\n }\r\n }\r\n\r\n /// @dev Sets the owner directly without authorization guard.\r\n function _setOwner(address newOwner) internal virtual {\r\n if (_guardInitializeOwner()) {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n let ownerSlot := _OWNER_SLOT\r\n // Clean the upper 96 bits.\r\n newOwner := shr(96, shl(96, newOwner))\r\n // Emit the {OwnershipTransferred} event.\r\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\r\n // Store the new value.\r\n sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))\r\n }\r\n } else {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n let ownerSlot := _OWNER_SLOT\r\n // Clean the upper 96 bits.\r\n newOwner := shr(96, shl(96, newOwner))\r\n // Emit the {OwnershipTransferred} event.\r\n log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)\r\n // Store the new value.\r\n sstore(ownerSlot, newOwner)\r\n }\r\n }\r\n }\r\n\r\n /// @dev Throws if the sender is not the owner.\r\n function _checkOwner() internal view virtual {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n // If the caller is not the stored owner, revert.\r\n if iszero(eq(caller(), sload(_OWNER_SLOT))) {\r\n mstore(0x00, 0x82b42900) // `Unauthorized()`.\r\n revert(0x1c, 0x04)\r\n }\r\n }\r\n }\r\n\r\n /// @dev Returns how long a two-step ownership handover is valid for in seconds.\r\n /// Override to return a different value if needed.\r\n /// Made internal to conserve bytecode. Wrap it in a public function if needed.\r\n function _ownershipHandoverValidFor() internal view virtual returns (uint64) {\r\n return 48 * 3600;\r\n }\r\n\r\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\r\n /* PUBLIC UPDATE FUNCTIONS */\r\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\r\n\r\n /// @dev Allows the owner to transfer the ownership to `newOwner`.\r\n function transferOwnership(address newOwner) public payable virtual onlyOwner {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n if iszero(shl(96, newOwner)) {\r\n mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.\r\n revert(0x1c, 0x04)\r\n }\r\n }\r\n _setOwner(newOwner);\r\n }\r\n\r\n /// @dev Allows the owner to renounce their ownership.\r\n function renounceOwnership() public payable virtual onlyOwner {\r\n _setOwner(address(0));\r\n }\r\n\r\n /// @dev Request a two-step ownership handover to the caller.\r\n /// The request will automatically expire in 48 hours (172800 seconds) by default.\r\n function requestOwnershipHandover() public payable virtual {\r\n unchecked {\r\n uint256 expires = block.timestamp + _ownershipHandoverValidFor();\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n // Compute and set the handover slot to `expires`.\r\n mstore(0x0c, _HANDOVER_SLOT_SEED)\r\n mstore(0x00, caller())\r\n sstore(keccak256(0x0c, 0x20), expires)\r\n // Emit the {OwnershipHandoverRequested} event.\r\n log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())\r\n }\r\n }\r\n }\r\n\r\n /// @dev Cancels the two-step ownership handover to the caller, if any.\r\n function cancelOwnershipHandover() public payable virtual {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n // Compute and set the handover slot to 0.\r\n mstore(0x0c, _HANDOVER_SLOT_SEED)\r\n mstore(0x00, caller())\r\n sstore(keccak256(0x0c, 0x20), 0)\r\n // Emit the {OwnershipHandoverCanceled} event.\r\n log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())\r\n }\r\n }\r\n\r\n /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.\r\n /// Reverts if there is no existing ownership handover requested by `pendingOwner`.\r\n function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n // Compute and set the handover slot to 0.\r\n mstore(0x0c, _HANDOVER_SLOT_SEED)\r\n mstore(0x00, pendingOwner)\r\n let handoverSlot := keccak256(0x0c, 0x20)\r\n // If the handover does not exist, or has expired.\r\n if gt(timestamp(), sload(handoverSlot)) {\r\n mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.\r\n revert(0x1c, 0x04)\r\n }\r\n // Set the handover slot to 0.\r\n sstore(handoverSlot, 0)\r\n }\r\n _setOwner(pendingOwner);\r\n }\r\n\r\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\r\n /* PUBLIC READ FUNCTIONS */\r\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\r\n\r\n /// @dev Returns the owner of the contract.\r\n function owner() public view virtual returns (address result) {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n result := sload(_OWNER_SLOT)\r\n }\r\n }\r\n\r\n /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.\r\n function ownershipHandoverExpiresAt(address pendingOwner)\r\n public\r\n view\r\n virtual\r\n returns (uint256 result)\r\n {\r\n /// @solidity memory-safe-assembly\r\n assembly {\r\n // Compute the handover slot.\r\n mstore(0x0c, _HANDOVER_SLOT_SEED)\r\n mstore(0x00, pendingOwner)\r\n // Load the handover slot.\r\n result := sload(keccak256(0x0c, 0x20))\r\n }\r\n }\r\n\r\n /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\r\n /* MODIFIERS */\r\n /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\r\n\r\n /// @dev Marks a function as only callable by the owner.\r\n modifier onlyOwner() virtual {\r\n _checkOwner();\r\n _;\r\n }\r\n}\r\n"},"lib/openzeppelin-contracts-upgradeable/contracts/utils/AddressUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\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://consensys.net/diligence/blog/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.8.0/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 errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"}},"settings":{"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/","openzeppelin/=lib/openzeppelin-contracts/contracts/","solady/=lib/solady/src/"],"optimizer":{"enabled":true,"runs":1000},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"outputSelection":{"*":{"":["ast"],"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","storageLayout"]}},"evmVersion":"paris","viaIR":true,"libraries":{}}}