-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathPullTokenWrapperAllowImmutable.verify.json
More file actions
1 lines (1 loc) · 160 KB
/
Copy pathPullTokenWrapperAllowImmutable.verify.json
File metadata and controls
1 lines (1 loc) · 160 KB
1
{"language":"Solidity","sources":{"contracts/partners/tokenWrappers/PullTokenWrapperAllowImmutable.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.17;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { IERC20, IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport { PullTokenWrapperImmutableBase } from \"./PullTokenWrapperImmutableBase.sol\";\n\n/// @title PullTokenWrapperAllowImmutable\n/// @notice Non-upgradeable wrapper for a reward token on Merkl so campaigns do not have to be prefunded\n/// @dev In this version of the PullTokenWrapper, tokens are pulled from a holder address during claims\n/// @dev Managers of such wrapper contracts must ensure that the holder address has enough allowance to the wrapper\n/// contract for the token pulled during claims\n/// @dev This is the non-upgradeable version of `PullTokenWrapperAllow`\ncontract PullTokenWrapperAllowImmutable is PullTokenWrapperImmutableBase {\n using SafeERC20 for IERC20;\n\n constructor(\n address _token,\n address _distributionCreator,\n address _holder\n )\n ERC20(string(abi.encodePacked(IERC20Metadata(_token).name(), \" (wrapped)\")), IERC20Metadata(_token).symbol())\n PullTokenWrapperImmutableBase(_token, _distributionCreator, _holder)\n {}\n\n /// @notice Hook called before every transfer: pulls underlying tokens from the holder when the transfer\n /// originates from the distributor (claim) or is directed to the fee recipient\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal override {\n if (from == distributor || to == feeRecipient) IERC20(token).safeTransferFrom(holder, to, amount);\n }\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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 * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\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 * 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 default value returned by this function, unless\n * it's 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-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/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 /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` 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 */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\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 implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation 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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n"},"node_modules/@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"},"contracts/partners/tokenWrappers/PullTokenWrapperImmutableBase.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.17;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { IERC20, IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport { IAccessControlManager } from \"../../interfaces/IAccessControlManager.sol\";\nimport { DistributionCreator } from \"../../DistributionCreator.sol\";\nimport { Errors } from \"../../utils/Errors.sol\";\n\n/// @title PullTokenWrapperImmutableBase\n/// @notice Abstract base for non-upgradeable pull token wrappers on Merkl\n/// @dev Provides shared state, access control, allowance tracking, and common functions.\n/// Child contracts must implement `_beforeTokenTransfer` to define how tokens are delivered on claim,\n/// and call the ERC20 constructor with the appropriate name and symbol.\nabstract contract PullTokenWrapperImmutableBase is ERC20 {\n using SafeERC20 for IERC20;\n\n // ================================= VARIABLES =================================\n\n /// @notice `AccessControlManager` contract handling access control\n IAccessControlManager public immutable accessControlManager;\n /// @notice Address of the token involved in the pull mechanism\n address public immutable token;\n /// @notice Address of the Merkl distributor contract\n address public immutable distributor;\n /// @notice Address of the Merkl distribution creator contract\n address public immutable distributionCreator;\n /// @notice Address holding the tokens and granting allowance to this contract\n address public holder;\n /// @notice Address receiving protocol fees on claim\n address public feeRecipient;\n /// @notice Whether an address is allowed to hold wrapper tokens\n mapping(address => uint256) public isAllowed;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` is the holder or a governor\n modifier onlyHolderOrGovernor() {\n if (msg.sender != holder && !accessControlManager.isGovernor(msg.sender)) revert Errors.NotAllowed();\n _;\n }\n\n // ================================= CONSTRUCTOR =================================\n\n constructor(address _token, address _distributionCreator, address _holder) {\n if (_holder == address(0) || _distributionCreator == address(0)) revert Errors.ZeroAddress();\n DistributionCreator dc = DistributionCreator(_distributionCreator);\n address _distributor = dc.distributor();\n accessControlManager = dc.accessControlManager();\n distributor = _distributor;\n feeRecipient = dc.feeRecipient();\n token = _token;\n distributionCreator = _distributionCreator;\n holder = _holder;\n isAllowed[_distributor] = 1;\n isAllowed[_holder] = 1;\n isAllowed[address(0)] = 1;\n }\n\n // ================================= FUNCTIONS =================================\n\n /// @notice Hook called after every transfer: burns wrapper tokens for any recipient that is not allowed\n function _afterTokenTransfer(address, address to, uint256 amount) internal virtual override {\n if (isAllowed[to] == 0) _burn(to, amount);\n }\n\n /// @notice Mints wrapper tokens to a recipient and allows them to hold wrapper tokens\n /// @param recipient Address to receive the minted wrapper tokens\n /// @param amount Amount of wrapper tokens to mint\n function mint(address recipient, uint256 amount) external virtual onlyHolderOrGovernor {\n isAllowed[recipient] = 1;\n _mint(recipient, amount);\n }\n\n /// @notice Updates the holder address and adjusts allowances accordingly\n /// @param _newHolder New holder address\n function setHolder(address _newHolder) external onlyHolderOrGovernor {\n isAllowed[holder] = 0;\n isAllowed[_newHolder] = 1;\n holder = _newHolder;\n }\n\n /// @notice Toggles whether an address is allowed to hold wrapper tokens\n /// @param _address Address to toggle allowance for\n function toggleAllowance(address _address) external onlyHolderOrGovernor {\n isAllowed[_address] = 1 - isAllowed[_address];\n }\n\n /// @notice Recovers ERC20 tokens held by this contract\n /// @param _token Address of the token to recover\n /// @param _to Address to send the recovered tokens to\n /// @param amount Amount to recover\n function recover(address _token, address _to, uint256 amount) external onlyHolderOrGovernor {\n IERC20(_token).safeTransfer(_to, amount);\n }\n\n /// @notice Syncs the fee recipient from the DistributionCreator contract\n function setFeeRecipient() external {\n feeRecipient = DistributionCreator(distributionCreator).feeRecipient();\n }\n\n /// @notice Returns the number of decimals of the token\n function decimals() public view virtual override returns (uint8) {\n return IERC20Metadata(token).decimals();\n }\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(address from, address to, uint256 amount) external returns (bool);\n}\n"},"node_modules/@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (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 function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n"},"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/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 *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n * doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n * token.safeTransferFrom(msg.sender, address(this), value);\n * ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\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 * CAUTION: See Security Considerations above.\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"},"node_modules/@openzeppelin/contracts/utils/Address.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 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 * 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"},"contracts/interfaces/IAccessControlManager.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.17;\n\n/// @title IAccessControlManager\n/// @author Merkl SAS\n/// @notice Interface for the `AccessControlManager` contracts of Merkl contracts\ninterface IAccessControlManager {\n /// @notice Checks whether an address is governor\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is a governor or a guardian of a module\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n"},"contracts/DistributionCreator.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.17;\n\nimport { ReentrancyGuardUpgradeable } from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { ECDSA } from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\nimport { UUPSHelper } from \"./utils/UUPSHelper.sol\";\nimport { IAccessControlManager } from \"./interfaces/IAccessControlManager.sol\";\nimport { Errors } from \"./utils/Errors.sol\";\nimport { CampaignParameters } from \"./struct/CampaignParameters.sol\";\nimport { DistributionParameters } from \"./struct/DistributionParameters.sol\";\nimport { RewardTokenAmounts } from \"./struct/RewardTokenAmounts.sol\";\n\n/// @title DistributionCreator\n/// @author Merkl SAS\n/// @notice Manages the creation and administration of reward distribution campaigns through the Merkl system\n/// @dev This contract serves as the primary interface for campaign creators and provides helper functions for APIs built on Merkl\n/// @dev Deprecated variables are maintained in storage for upgrade compatibility\n//solhint-disable\ncontract DistributionCreator is UUPSHelper, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n CONSTANTS / VARIABLES \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Duration of one hour in seconds\n uint32 public constant HOUR = 3600;\n\n /// @notice Base denominator for fee calculations (represents 100%)\n uint256 public constant BASE_9 = 1e9;\n\n /// @notice Chain ID where this contract is deployed\n uint256 public immutable CHAIN_ID = block.chainid;\n\n /// @notice `AccessControlManager` contract handling access control\n IAccessControlManager public accessControlManager;\n\n /// @notice Address of the Distributor contract that distributes rewards to users\n address public distributor;\n\n /// @notice Address that receives protocol fees from campaign creation\n address public feeRecipient;\n\n /// @notice Default fee rate (in base 10^9) applied when creating a campaign\n uint256 public defaultFees;\n\n /// @notice Terms and conditions message that users must acknowledge before creating campaigns\n string public message;\n\n /// @notice Keccak256 hash of the conditions that users must accept before creating campaigns\n /// @dev The message may be a link to the full terms hosted offchain\n bytes32 public messageHash;\n\n /// @notice Deprecated - kept for storage layout compatibility\n DistributionParameters[] public distributionList;\n\n /// @notice Maps an address to its fee rebate percentage\n mapping(address => uint256) public feeRebate;\n\n /// @notice Deprecated - kept for storage layout compatibility\n mapping(address => uint256) public isWhitelistedToken;\n\n /// @notice Deprecated - kept for storage layout compatibility\n mapping(address => uint256) public _nonces;\n\n /// @notice Maps user addresses to the hash of the last terms and conditions they accepted\n /// @dev The name includes 'signature' for legacy reasons, reflecting the original requirement for users to sign conditions\n mapping(address => bytes32) public userSignatures;\n\n /// @notice Maps user addresses to their whitelist status for signature requirements\n /// @dev The name includes 'signature' for legacy reasons, reflecting the original requirement for users to sign conditions\n mapping(address => uint256) public userSignatureWhitelist;\n\n /// @notice Maps each reward token to its minimum required amount per epoch for campaign validity\n /// @dev A value of 0 indicates the token is not whitelisted and cannot be used as a reward\n mapping(address => uint256) public rewardTokenMinAmounts;\n\n /// @notice Array of all reward tokens that have been whitelisted at any point\n address[] public rewardTokens;\n\n /// @notice Array of all campaigns ever created in the contract (past, current, and future)\n /// @dev This list can grow unbounded, but is only accessed by view functions\n CampaignParameters[] public campaignList;\n\n /// @notice Maps a campaign ID to its index in the campaign list plus one (0 = does not exist)\n mapping(bytes32 => uint256) internal _campaignLookup;\n\n /// @notice Maps campaign types to their specific fee rates, overriding the default fee\n mapping(uint32 => uint256) public campaignSpecificFees;\n\n /// @notice Maps campaign IDs to override parameters that modify the original campaign\n mapping(bytes32 => CampaignParameters) public campaignOverrides;\n\n /// @notice Maps campaign IDs to timestamps when overrides were applied\n mapping(bytes32 => uint256[]) public campaignOverridesTimestamp;\n\n /// @notice Maps campaign IDs to reward reallocations (from address -> to address)\n mapping(bytes32 => mapping(address => address)) public campaignReallocation;\n\n /// @notice Maps campaign IDs to lists of addresses whose rewards have been reallocated\n mapping(bytes32 => address[]) public campaignListReallocation;\n\n /// @notice Maps creator addresses to their predeposited token balances for each reward token\n mapping(address => mapping(address => uint256)) public creatorBalance;\n\n /// @notice Maps creator addresses to operator approvals for spending predeposited tokens\n /// @dev creator => operator => rewardToken => allowance amount\n mapping(address => mapping(address => mapping(address => uint256))) public creatorAllowance;\n\n /// @notice Maps manager addresses to authorized campaign operators who can manage campaigns on their behalf\n mapping(address => mapping(address => uint256)) public campaignOperators;\n\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n EVENTS \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n event CreatorAllowanceUpdated(address indexed user, address indexed operator, address indexed token, uint256 amount);\n event CreatorBalanceUpdated(address indexed user, address indexed token, uint256 amount);\n event DistributorUpdated(address indexed _distributor);\n event FeeRebateUpdated(address indexed user, uint256 userFeeRebate);\n event FeeRecipientUpdated(address indexed _feeRecipient);\n event FeesSet(uint256 _fees);\n event CampaignOperatorToggled(address indexed user, address indexed operator, bool isWhitelisted);\n event CampaignOverride(bytes32 _campaignId, CampaignParameters campaign);\n event CampaignReallocation(bytes32 _campaignId, address[] from, address indexed to);\n event CampaignSpecificFeesSet(uint32 campaignType, uint256 _fees);\n event ConditionsAccepted(address indexed user, bytes32 conditionsHash);\n event MessageUpdated(bytes32 _messageHash);\n event NewCampaign(CampaignParameters campaign);\n event RewardTokenMinimumAmountUpdated(address indexed token, uint256 amount);\n event UserSigningWhitelistToggled(address indexed user, uint256 toggleStatus);\n\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n MODIFIERS \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Restricts function access to addresses with governor or guardian role\n modifier onlyGovernorOrGuardian() {\n if (!accessControlManager.isGovernorOrGuardian(msg.sender)) revert Errors.NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Restricts function access to addresses with governor role only\n modifier onlyGovernor() {\n if (!accessControlManager.isGovernor(msg.sender)) revert Errors.NotGovernor();\n _;\n }\n\n /// @notice Ensures the caller has accepted the current terms or is whitelisted for this\n /// @dev Checks both msg.sender and tx.origin for signature or whitelist status\n modifier hasSigned() {\n if (\n userSignatureWhitelist[msg.sender] == 0 &&\n userSignatureWhitelist[tx.origin] == 0 &&\n userSignatures[msg.sender] != messageHash &&\n userSignatures[tx.origin] != messageHash\n ) revert Errors.NotSigned();\n _;\n }\n\n /// @notice Restricts function access to the specified user or any governor\n /// @param user The user address allowed to call the function\n modifier onlyUserOrGovernor(address user) {\n if (user != msg.sender && !accessControlManager.isGovernor(msg.sender)) revert Errors.NotAllowed();\n _;\n }\n\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n CONSTRUCTOR \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Initializes the contract with access control, distributor, and default fees\n /// @param _accessControlManager Address of the access control manager contract\n /// @param _distributor Address of the Distributor contract\n /// @param _fees Default fee rate in base 10^9 (must be less than BASE_9)\n function initialize(IAccessControlManager _accessControlManager, address _distributor, uint256 _fees) external initializer {\n if (address(_accessControlManager) == address(0) || _distributor == address(0)) revert Errors.ZeroAddress();\n if (_fees >= BASE_9) revert Errors.InvalidParam();\n distributor = _distributor;\n accessControlManager = _accessControlManager;\n defaultFees = _fees;\n }\n\n constructor() initializer {}\n\n /// @inheritdoc UUPSHelper\n function _authorizeUpgrade(address) internal view override onlyGovernorUpgrader(accessControlManager) {}\n\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n USER FACING FUNCTIONS \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Creates a new reward distribution campaign\n /// @param newCampaign Parameters defining the campaign structure and rewards\n /// @return campaignId Unique identifier for the newly created campaign\n /// @dev Campaigns with invalid formatting may not be processed by the reward engine, potentially losing rewards\n /// @dev Reward tokens must be whitelisted and amounts must exceed the token-specific minimum threshold\n /// @dev Reverts if the sender has not accepted the terms and conditions via acceptConditions()\n function createCampaign(CampaignParameters memory newCampaign) external nonReentrant hasSigned returns (bytes32) {\n return _createCampaign(newCampaign);\n }\n\n /// @notice Same as createCampaign but with an unused signature parameter for backward compatibility\n /// @dev It is functionally equivalent to createCampaign() - the signature parameter is unused\n function signAndCreateCampaign(CampaignParameters memory newCampaign, bytes calldata) external nonReentrant hasSigned returns (bytes32) {\n return _createCampaign(newCampaign);\n }\n\n /// @notice Creates multiple reward distribution campaigns in a single transaction\n /// @param campaigns Array of campaign parameters to create\n /// @return Array of campaign IDs for all newly created campaigns\n function createCampaigns(CampaignParameters[] memory campaigns) external nonReentrant hasSigned returns (bytes32[] memory) {\n uint256 campaignsLength = campaigns.length;\n bytes32[] memory campaignIds = new bytes32[](campaignsLength);\n for (uint256 i; i < campaignsLength; ) {\n campaignIds[i] = _createCampaign(campaigns[i]);\n unchecked {\n ++i;\n }\n }\n return campaignIds;\n }\n\n /// @notice Allows a user to accept Merkl's terms and conditions to enable campaign creation\n /// @dev If the conditions change (through setMessage), users must accept again the new terms\n /// @dev If the messageHash is not set, it means that there are no conditions to accept\n function acceptConditions() external {\n userSignatures[msg.sender] = messageHash;\n emit ConditionsAccepted(msg.sender, messageHash);\n }\n\n /// @notice Updates parameters of an existing campaign while preserving core immutable fields\n /// @param _campaignId ID of the campaign to override\n /// @param newCampaign New campaign parameters (some fields will be ignored or validated)\n /// @dev Cannot change rewardToken, amount, or creator address\n /// @dev The Merkl engine validates overrides and rejects invalid modifications, including attempts to circumvent campaign-specific fee rates\n /// @dev The rejection of invalid modifications leads to the campaign being parsed as invalid and the leftover reward tokens allocated to the campaign creator address\n /// @dev Invalid overrides may result in the campaign not being processed while fees are still deducted\n function overrideCampaign(bytes32 _campaignId, CampaignParameters memory newCampaign) external {\n CampaignParameters memory _campaign = _getLatestCampaignParams(_campaignId);\n _isSenderValidOperatorForCampaign(_campaign.creator);\n // Preserve immutable campaign fields that cannot be modified through overrides\n newCampaign.campaignId = _campaignId;\n newCampaign.creator = _campaign.creator; // Creator address must remain unchanged\n newCampaign.amount = _campaign.amount; // Total reward amount is immutable\n newCampaign.rewardToken = _campaign.rewardToken; // Reward token cannot be changed\n if (\n (newCampaign.startTimestamp != _campaign.startTimestamp && block.timestamp > _campaign.startTimestamp) || // Allow to update startTimestamp before campaign start\n newCampaign.amount * HOUR < rewardTokenMinAmounts[newCampaign.rewardToken] * newCampaign.duration\n ) revert Errors.InvalidOverride();\n\n campaignOverrides[_campaignId] = newCampaign;\n // There could be duplicate timestamps in the array if multiple overrides happen in the same block\n campaignOverridesTimestamp[_campaignId].push(block.timestamp);\n emit CampaignOverride(_campaignId, newCampaign);\n }\n\n /// @notice Reallocates unclaimed rewards from specific addresses to a new recipient after campaign ends\n /// @param _campaignId ID of the completed campaign to reallocate from\n /// @param froms Array of addresses whose unclaimed rewards should be reallocated\n /// @param to Address that will receive the reallocated rewards\n /// @dev Can only be called after the campaign has ended (startTimestamp + duration has passed)\n /// @dev Reallocation validity is determined by the Merkl engine; invalid reallocations are ignored\n function reallocateCampaignRewards(bytes32 _campaignId, address[] memory froms, address to) external {\n CampaignParameters memory _campaign = _getLatestCampaignParams(_campaignId);\n _isSenderValidOperatorForCampaign(_campaign.creator);\n // Check campaign end time using the overridden parameters if they exist\n if (block.timestamp < _campaign.startTimestamp + _campaign.duration) revert Errors.InvalidReallocation();\n if (to == address(0)) revert Errors.ZeroAddress();\n\n uint256 fromsLength = froms.length;\n for (uint256 i; i < fromsLength; ) {\n campaignReallocation[_campaignId][froms[i]] = to;\n campaignListReallocation[_campaignId].push(froms[i]);\n unchecked {\n ++i;\n }\n }\n emit CampaignReallocation(_campaignId, froms, to);\n }\n\n /// @notice Increases a user's predeposited token balance for campaign funding\n /// @param user Address whose balance will be increased\n /// @param rewardToken Token to deposit\n /// @param amount Amount to deposit\n /// @dev When called by a governor, the user MUST have sent tokens to the contract beforehand\n /// @dev Can be used to deposit on behalf of another user\n /// @dev WARNING: Do not use with any non strictly standard ERC20 (like rebasing tokens) as they will cause accounting issues\n function increaseTokenBalance(address user, address rewardToken, uint256 amount) external {\n if (user == address(0)) revert Errors.ZeroAddress();\n if (!accessControlManager.isGovernor(msg.sender)) IERC20(rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n _updateBalance(user, rewardToken, creatorBalance[user][rewardToken] + amount);\n }\n\n /// @notice Decreases a user's predeposited token balance and transfers tokens out\n /// @param user Address whose balance will be decreased\n /// @param rewardToken Token to withdraw\n /// @param to Address that will receive the withdrawn tokens\n /// @param amount Amount to withdraw\n /// @dev Only callable by the user themselves or a governor\n function decreaseTokenBalance(address user, address rewardToken, address to, uint256 amount) external onlyUserOrGovernor(user) {\n _updateBalance(user, rewardToken, creatorBalance[user][rewardToken] - amount);\n IERC20(rewardToken).safeTransfer(to, amount);\n }\n\n /// @notice Increases an operator's allowance to spend a user's predeposited tokens\n /// @param user User granting the allowance\n /// @param operator Operator receiving spending permission\n /// @param rewardToken Token for which allowance is granted\n /// @param amount Amount to increase the allowance by\n /// @dev Only callable by the user themselves or a governor\n function increaseTokenAllowance(address user, address operator, address rewardToken, uint256 amount) external onlyUserOrGovernor(user) {\n _updateAllowance(user, operator, rewardToken, creatorAllowance[user][operator][rewardToken] + amount);\n }\n\n /// @notice Decreases an operator's allowance to spend a user's predeposited tokens\n /// @param user User reducing the allowance\n /// @param operator Operator whose allowance is being reduced\n /// @param rewardToken Token for which allowance is reduced\n /// @param amount Amount to decrease the allowance by\n /// @dev Only callable by the user themselves or a governor\n function decreaseTokenAllowance(address user, address operator, address rewardToken, uint256 amount) external onlyUserOrGovernor(user) {\n uint256 currentAllowance = creatorAllowance[user][operator][rewardToken];\n uint256 newAllowance;\n if (amount >= currentAllowance) {\n newAllowance = 0;\n } else {\n newAllowance = currentAllowance - amount;\n }\n\n _updateAllowance(user, operator, rewardToken, newAllowance);\n }\n\n /// @notice Toggles an operator's authorization to create and manage campaigns on behalf of a user\n /// @param user User granting or revoking operator access\n /// @param operator Operator whose authorization is being toggled\n /// @dev Only callable by the user themselves or a governor\n /// @dev Toggles between authorized (1) and unauthorized (0)\n function toggleCampaignOperator(address user, address operator) external onlyUserOrGovernor(user) {\n uint256 currentStatus = campaignOperators[user][operator];\n campaignOperators[user][operator] = 1 - currentStatus;\n emit CampaignOperatorToggled(user, operator, currentStatus == 0);\n }\n\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n GETTERS \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Returns the array index of a campaign in the campaign list\n /// @param _campaignId ID of the campaign to look up\n /// @return Zero-based index of the campaign in the campaignList array\n /// @dev Reverts if the campaign does not exist\n function campaignLookup(bytes32 _campaignId) public view returns (uint256) {\n uint256 index = _campaignLookup[_campaignId];\n if (index == 0) revert Errors.CampaignDoesNotExist();\n return index - 1;\n }\n\n /// @notice Returns the original parameters of a campaign\n /// @param _campaignId ID of the campaign to retrieve\n /// @return Campaign parameters as originally created\n /// @dev Returns original parameters even if the campaign has been overridden\n function campaign(bytes32 _campaignId) public view returns (CampaignParameters memory) {\n return campaignList[campaignLookup(_campaignId)];\n }\n\n /// @notice Returns the most up-to-date campaign parameters, including any overrides\n /// @param _campaignId ID of the campaign to retrieve\n /// @return Campaign parameters with overrides applied if they exist, otherwise original parameters\n /// @dev If an override exists (non-zero campaignId), returns the override; otherwise returns original campaign\n /// @dev Even if an override is invalid, we return the latest override data. This is safe because invalid\n /// overrides result in the campaign being parsed as invalid by the Merkl engine\n function getLatestCampaignParams(bytes32 _campaignId) public view returns (CampaignParameters memory) {\n return _getLatestCampaignParams(_campaignId);\n }\n\n /// @notice Computes the unique campaign ID for a given set of campaign parameters\n /// @param campaignData Campaign parameters to hash\n /// @return Unique campaign ID derived from hashing key parameters\n /// @dev Campaign ID is computed as keccak256 of creator, rewardToken, campaignType, startTimestamp, duration, and campaignData\n function campaignId(CampaignParameters memory campaignData) public view returns (bytes32) {\n return\n bytes32(\n keccak256(\n abi.encodePacked(\n CHAIN_ID,\n campaignData.creator,\n campaignData.rewardToken,\n campaignData.campaignType,\n campaignData.startTimestamp,\n campaignData.duration,\n campaignData.campaignData\n )\n )\n );\n }\n\n /// @notice Returns all whitelisted reward tokens and their minimum required amounts\n /// @return Array of reward tokens with their minimum amounts per epoch\n /// @dev Not optimized for onchain queries; intended for off-chain/API use\n function getValidRewardTokens() external view returns (RewardTokenAmounts[] memory) {\n (RewardTokenAmounts[] memory validRewardTokens, ) = _getValidRewardTokens(0, type(uint32).max);\n return validRewardTokens;\n }\n\n /// @notice Returns a paginated list of whitelisted reward tokens\n /// @param skip Number of tokens to skip\n /// @param first Maximum number of tokens to return\n /// @return Array of reward tokens and total count\n /// @dev Not optimized for onchain queries; intended for off-chain/API use\n function getValidRewardTokens(uint32 skip, uint32 first) external view returns (RewardTokenAmounts[] memory, uint256) {\n return _getValidRewardTokens(skip, first);\n }\n\n /// @notice Returns all timestamps when a campaign was overridden\n /// @param _campaignId ID of the campaign\n /// @return Array of block timestamps when overrides occurred\n function getCampaignOverridesTimestamp(bytes32 _campaignId) external view returns (uint256[] memory) {\n return campaignOverridesTimestamp[_campaignId];\n }\n\n /// @notice Returns all addresses from which rewards were reallocated for a campaign\n /// @param _campaignId ID of the campaign\n /// @return Array of addresses that had rewards reallocated away from them\n function getCampaignListReallocation(bytes32 _campaignId) external view returns (address[] memory) {\n return campaignListReallocation[_campaignId];\n }\n\n /// @notice Returns the address at a specific index in the campaign reallocation list\n /// @param _campaignId ID of the campaign\n /// @param index Index in the reallocation list\n /// @return Address at the specified index that had rewards reallocated away\n function getCampaignListReallocationAt(bytes32 _campaignId, uint256 index) external view returns (address) {\n return campaignListReallocation[_campaignId][index];\n }\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n GOVERNANCE FUNCTIONS \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Updates the Distributor contract address that receives and distributes rewards\n /// @param _distributor New Distributor contract address\n /// @dev Only callable by governor\n /// @dev This function is not meant to be used and mostly kept here to help with testing\n function setNewDistributor(address _distributor) external onlyGovernor {\n if (_distributor == address(0)) revert Errors.InvalidParam();\n distributor = _distributor;\n emit DistributorUpdated(_distributor);\n }\n\n /// @notice Recovers tokens from the contract\n /// @param token Token address to recover\n /// @param to Address that will receive the recovered tokens\n /// @param amount Amount of tokens to recover\n /// @dev Only callable by governor\n /// @dev WARNING: Be extremely careful not to withdraw tokens that have been predeposited by users via increaseTokenBalance\n /// @dev Withdrawing predeposited user tokens will break the accounting system and cause loss of funds for users\n /// @dev This function should only be used to recover tokens accidentally sent to the contract or accumulated protocol fees\n /// @dev Always verify that the amount being recovered does not exceed fees and does not include user predeposits\n function recover(address token, address to, uint256 amount) external onlyGovernor {\n if (to == address(0)) revert Errors.ZeroAddress();\n IERC20(token).safeTransfer(to, amount);\n }\n\n /// @notice Updates the address that receives protocol fees from campaign creation\n /// @param _feeRecipient New fee recipient address\n /// @dev Only callable by governor\n function setFeeRecipient(address _feeRecipient) external onlyGovernor {\n feeRecipient = _feeRecipient;\n emit FeeRecipientUpdated(_feeRecipient);\n }\n\n /// @notice Updates the terms and conditions that users must accept before creating campaigns\n /// @param _message New terms and conditions message text\n /// @dev Only callable by governor or guardian\n /// @dev Automatically computes and stores the keccak256 hash\n /// @dev The message may be a link to the full terms hosted offchain\n function setMessage(string memory _message) external onlyGovernorOrGuardian {\n message = _message;\n bytes32 _messageHash;\n if (bytes(_message).length != 0) _messageHash = ECDSA.toEthSignedMessageHash(bytes(_message));\n messageHash = _messageHash;\n emit MessageUpdated(_messageHash);\n }\n\n /// @notice Updates the default fee rate applied to campaign creation\n /// @param _defaultFees New default fee rate in base 10^9\n /// @dev Only callable by governor or guardian\n /// @dev Fee rate must be less than BASE_9 (100%)\n function setFees(uint256 _defaultFees) external onlyGovernorOrGuardian {\n if (_defaultFees >= BASE_9) revert Errors.InvalidParam();\n defaultFees = _defaultFees;\n emit FeesSet(_defaultFees);\n }\n\n /// @notice Sets campaign-type-specific fee rates that override the default fee\n /// @param campaignType Type identifier for the campaign\n /// @param _fees Fee rate for this campaign type in base 10^9\n /// @dev Only callable by governor or guardian\n /// @dev Set fee to 1 to effectively waive fees for a campaign type\n /// @dev Fee rate must be less than BASE_9 (100%)\n function setCampaignFees(uint32 campaignType, uint256 _fees) external onlyGovernorOrGuardian {\n if (_fees >= BASE_9) revert Errors.InvalidParam();\n campaignSpecificFees[campaignType] = _fees;\n emit CampaignSpecificFeesSet(campaignType, _fees);\n }\n\n /// @notice Sets a fee rebate for a specific user\n /// @param user User address receiving the fee rebate\n /// @param userFeeRebate Rebate amount in base 10^9\n /// @dev Only callable by governor or guardian\n function setUserFeeRebate(address user, uint256 userFeeRebate) external onlyGovernorOrGuardian {\n if (userFeeRebate > BASE_9) revert Errors.InvalidParam();\n feeRebate[user] = userFeeRebate;\n emit FeeRebateUpdated(user, userFeeRebate);\n }\n\n /// @notice Toggles whether a user must sign the terms message before creating campaigns\n /// @param user User address whose whitelist status is being toggled\n /// @dev Only callable by governor or guardian\n /// @dev Whitelisted users (status = 1) can create campaigns without accepting Merkl terms\n function toggleSigningWhitelist(address user) external onlyGovernorOrGuardian {\n uint256 whitelistStatus = 1 - userSignatureWhitelist[user];\n userSignatureWhitelist[user] = whitelistStatus;\n emit UserSigningWhitelistToggled(user, whitelistStatus);\n }\n\n /// @notice Configures minimum reward amounts per epoch for whitelisted tokens\n /// @param tokens Array of reward token addresses\n /// @param amounts Array of minimum amounts (0 = remove from whitelist, >0 = add/update)\n /// @dev Only callable by governor or guardian\n /// @dev Setting amount to 0 effectively removes the token from the whitelist\n /// @dev Prevents duplicate entries when adding previously removed tokens\n /// @dev WARNING: Non-standard tokens (e.g., tokens with fee-on-transfer, rebasing tokens) must not be whitelisted as they break the Merkl accounting logic\n function setRewardTokenMinAmounts(address[] calldata tokens, uint256[] calldata amounts) external onlyGovernorOrGuardian {\n uint256 tokensLength = tokens.length;\n if (tokensLength != amounts.length) revert Errors.InvalidLengths();\n for (uint256 i; i < tokensLength; ) {\n uint256 amount = amounts[i];\n // Basic logic check to make sure there are no duplicates in the `rewardTokens` table. If a token is\n // removed then re-added, it will appear as a duplicate in the list\n if (amount != 0 && rewardTokenMinAmounts[tokens[i]] == 0) rewardTokens.push(tokens[i]);\n rewardTokenMinAmounts[tokens[i]] = amount;\n emit RewardTokenMinimumAmountUpdated(tokens[i], amount);\n unchecked {\n ++i;\n }\n }\n }\n\n /*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n INTERNAL \n //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Internal function to create a new campaign with validation and fee processing\n /// @param newCampaign Campaign parameters to create\n /// @return Unique campaign ID of the created campaign\n /// @dev Validates campaign duration, reward token whitelist status, and minimum reward amounts\n /// @dev Computes and deducts protocol fees from the campaign amount\n /// @dev Reverts if campaign already exists or validation fails\n function _createCampaign(CampaignParameters memory newCampaign) internal returns (bytes32) {\n uint256 rewardTokenMinAmount = rewardTokenMinAmounts[newCampaign.rewardToken];\n // if the campaign doesn't last at least one second\n if (newCampaign.duration < 1) revert Errors.CampaignDurationNull();\n // if the reward token is not whitelisted as an incentive token\n if (rewardTokenMinAmount == 0) revert Errors.CampaignRewardTokenNotWhitelisted();\n // if the amount distributed is too small with respect to what is allowed\n // This check is performed before fees are deducted for better UX: campaign creators don't need\n // to account for Merkl fees when determining if their campaign amount meets the minimum threshold\n if (newCampaign.amount * HOUR < rewardTokenMinAmount * newCampaign.duration) revert Errors.CampaignRewardTooLow();\n // Computing fees and pulling tokens\n uint256 campaignAmountMinusFees = _computeFees(newCampaign.campaignType, newCampaign.amount);\n if (newCampaign.creator == address(0)) newCampaign.creator = msg.sender;\n _pullTokens(newCampaign.creator, newCampaign.rewardToken, newCampaign.amount, campaignAmountMinusFees);\n newCampaign.amount = campaignAmountMinusFees;\n newCampaign.campaignId = campaignId(newCampaign);\n\n if (_campaignLookup[newCampaign.campaignId] != 0) revert Errors.CampaignAlreadyExists();\n _campaignLookup[newCampaign.campaignId] = campaignList.length + 1;\n campaignList.push(newCampaign);\n emit NewCampaign(newCampaign);\n\n return newCampaign.campaignId;\n }\n\n /// @notice Validates that the msg.sender is authorized to manage campaigns for the specified manager\n /// @param manager Address of the campaign manager\n /// @dev Reverts if msg.sender is not the manager and not an authorized operator\n function _isSenderValidOperatorForCampaign(address manager) internal view {\n if (manager != msg.sender && campaignOperators[manager][msg.sender] == 0) {\n revert Errors.OperatorNotAllowed();\n }\n }\n\n /// @notice Updates an operator's allowance to spend a user's predeposited tokens\n /// @param user User granting the allowance\n /// @param operator Operator receiving the allowance\n /// @param rewardToken Token for which allowance is being set\n /// @param newAllowance New allowance amount\n function _updateAllowance(address user, address operator, address rewardToken, uint256 newAllowance) internal {\n creatorAllowance[user][operator][rewardToken] = newAllowance;\n emit CreatorAllowanceUpdated(user, operator, rewardToken, newAllowance);\n }\n\n /// @notice Updates a user's predeposited token balance\n /// @param user User whose balance is being updated\n /// @param rewardToken Token whose balance is being updated\n /// @param newBalance New balance amount\n function _updateBalance(address user, address rewardToken, uint256 newBalance) internal {\n creatorBalance[user][rewardToken] = newBalance;\n emit CreatorBalanceUpdated(user, rewardToken, newBalance);\n }\n\n /// @notice Transfers reward tokens from creator's balance or msg.sender to the distributor\n /// @param creator Address of the campaign creator\n /// @param rewardToken Token being transferred\n /// @param campaignAmount Total amount including fees\n /// @param campaignAmountMinusFees Net amount after fees to send to distributor\n /// @dev Attempts to use predeposited balance first, checking operator allowance if applicable\n /// @dev Falls back to direct transfer from msg.sender if insufficient predeposited balance\n /// @dev Sends fees to feeRecipient (or this contract if feeRecipient is zero address)\n function _pullTokens(address creator, address rewardToken, uint256 campaignAmount, uint256 campaignAmountMinusFees) internal {\n uint256 fees = campaignAmount - campaignAmountMinusFees;\n address _feeRecipient;\n if (fees > 0) {\n _feeRecipient = feeRecipient;\n _feeRecipient = _feeRecipient == address(0) ? address(this) : _feeRecipient;\n }\n uint256 userBalance = creatorBalance[creator][rewardToken];\n if (userBalance >= campaignAmount) {\n if (msg.sender != creator) {\n uint256 senderAllowance = creatorAllowance[creator][msg.sender][rewardToken];\n if (senderAllowance >= campaignAmount) {\n _updateAllowance(creator, msg.sender, rewardToken, senderAllowance - campaignAmount);\n } else {\n // WARNING: If the creator's allowance for msg.sender is insufficient or revoked,\n // tokens are pulled directly from msg.sender's address. Operators should monitor\n // the creator's allowance and balance to avoid unexpected token transfers.\n if (fees > 0) IERC20(rewardToken).safeTransferFrom(msg.sender, _feeRecipient, fees);\n IERC20(rewardToken).safeTransferFrom(msg.sender, distributor, campaignAmountMinusFees);\n return;\n }\n }\n _updateBalance(creator, rewardToken, userBalance - campaignAmount);\n if (fees > 0 && _feeRecipient != address(this)) IERC20(rewardToken).safeTransfer(_feeRecipient, fees);\n IERC20(rewardToken).safeTransfer(distributor, campaignAmountMinusFees);\n } else {\n if (fees > 0) IERC20(rewardToken).safeTransferFrom(msg.sender, _feeRecipient, fees);\n IERC20(rewardToken).safeTransferFrom(msg.sender, distributor, campaignAmountMinusFees);\n }\n }\n\n /// @notice Calculates the net campaign amount after deducting applicable fees\n /// @param campaignType Type of campaign for fee calculation\n /// @param distributionAmount Gross distribution amount before fees\n /// @return distributionAmountMinusFees Net amount after fees are deducted\n /// @dev Uses campaign-specific fees if set, otherwise uses default fees\n /// @dev Campaign-specific fee of 1 is treated as 0 (fee waiver)\n /// @dev Applies fee rebates to msg.sender (not creator)\n function _computeFees(uint32 campaignType, uint256 distributionAmount) internal view returns (uint256 distributionAmountMinusFees) {\n uint256 baseFeesValue = campaignSpecificFees[campaignType];\n if (baseFeesValue == 1) baseFeesValue = 0;\n else if (baseFeesValue == 0) baseFeesValue = defaultFees;\n // Fee rebates are applied to the msg.sender and not to the creator of the campaign\n uint256 _fees = (baseFeesValue * (BASE_9 - feeRebate[msg.sender])) / BASE_9;\n distributionAmountMinusFees = distributionAmount;\n if (_fees != 0) {\n distributionAmountMinusFees = (distributionAmount * (BASE_9 - _fees)) / BASE_9;\n }\n }\n\n /// @notice Internal version of the `getLatestCampaignParams` function\n function _getLatestCampaignParams(bytes32 _campaignId) internal view returns (CampaignParameters memory _campaign) {\n CampaignParameters memory overriddenCampaign = campaignOverrides[_campaignId];\n if (overriddenCampaign.campaignId != bytes32(0)) {\n return overriddenCampaign;\n }\n return campaign(_campaignId);\n }\n\n /// @notice Builds a paginated list of whitelisted reward tokens with their minimum amounts\n /// @param skip Number of tokens to skip in the iteration\n /// @param first Maximum number of tokens to return\n /// @return Array of valid reward tokens and the index where iteration stopped\n /// @dev Only includes tokens with non-zero minimum amounts (active whitelist entries)\n /// @dev Uses assembly to resize the return array to actual length\n function _getValidRewardTokens(uint32 skip, uint32 first) internal view returns (RewardTokenAmounts[] memory, uint256) {\n uint256 length;\n uint256 rewardTokenListLength = rewardTokens.length;\n uint256 returnSize = first > rewardTokenListLength ? rewardTokenListLength : first;\n RewardTokenAmounts[] memory validRewardTokens = new RewardTokenAmounts[](returnSize);\n uint32 i = skip;\n while (i < rewardTokenListLength) {\n address token = rewardTokens[i];\n uint256 minAmount = rewardTokenMinAmounts[token];\n if (minAmount > 0) {\n validRewardTokens[length] = RewardTokenAmounts(token, minAmount);\n length += 1;\n }\n unchecked {\n ++i;\n }\n if (length == returnSize) break;\n }\n assembly {\n mstore(validRewardTokens, length)\n }\n return (validRewardTokens, i);\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[28] private __gap;\n}\n"},"contracts/utils/Errors.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.17;\n\nlibrary Errors {\n error CampaignAlreadyEnded();\n error CampaignDoesNotExist();\n error CampaignAlreadyExists();\n error CampaignDurationNull();\n error CampaignRewardTokenNotWhitelisted();\n error CampaignRewardTooLow();\n error CampaignShouldStartInFuture();\n error InvalidDispute();\n error InvalidLengths();\n error InvalidOverride();\n error InvalidParam();\n error InvalidParams();\n error InvalidProof();\n error InvalidUninitializedRoot();\n error InvalidReallocation();\n error InvalidReturnMessage();\n error InvalidReward();\n error InvalidSignature();\n error KeyAlreadyUsed();\n error NoDispute();\n error NoOverrideForCampaign();\n error NotAllowed();\n error NotEnoughAllowance();\n error NotEnoughBalance();\n error NotEnoughPayment();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotSigned();\n error NotTrusted();\n error NotUpgradeable();\n error NotWhitelisted();\n error OperatorNotAllowed();\n error UnresolvedDispute();\n error ZeroAddress();\n error DisputeFundsTransferFailed();\n error EthNotAccepted();\n error ReentrantCall();\n error WithdrawalFailed();\n error InvalidClaim();\n error RefererNotSet();\n}\n"},"node_modules/@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\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 ReentrancyGuardUpgradeable is Initializable {\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 function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\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"},"node_modules/@openzeppelin/contracts/utils/cryptography/ECDSA.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n \u00f7 2 + 1, and for v in (302): v \u2208 {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n"},"contracts/utils/UUPSHelper.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.17;\n\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\n\nimport { IAccessControlManager } from \"../interfaces/IAccessControlManager.sol\";\nimport { Errors } from \"./Errors.sol\";\n\n/// @title UUPSHelper\n/// @notice Helper contract for UUPSUpgradeable contracts where the upgradeability is controlled by a specific address\n/// @author Merkl SAS\n/// @dev The 0 address check in the modifier allows the use of these modifiers during initialization\nabstract contract UUPSHelper is UUPSUpgradeable {\n modifier onlyGuardianUpgrader(IAccessControlManager _accessControlManager) {\n if (address(_accessControlManager) != address(0) && !_accessControlManager.isGovernorOrGuardian(msg.sender))\n revert Errors.NotGovernorOrGuardian();\n _;\n }\n\n modifier onlyGovernorUpgrader(IAccessControlManager _accessControlManager) {\n if (address(_accessControlManager) != address(0) && !_accessControlManager.isGovernor(msg.sender)) revert Errors.NotGovernor();\n _;\n }\n\n constructor() initializer {}\n\n /// @inheritdoc UUPSUpgradeable\n function _authorizeUpgrade(address newImplementation) internal virtual override {}\n}\n"},"contracts/struct/CampaignParameters.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.0;\n\n/// @notice Parameters defining a Merkl reward distribution campaign\nstruct CampaignParameters {\n // ========== POPULATED BY CONTRACT ==========\n\n /// @notice Unique identifier for the campaign\n /// @dev Can be left as bytes32(0) when creating a new campaign - will be computed by the contract\n bytes32 campaignId;\n // ========== CONFIGURED BY CREATOR ==========\n\n /// @notice Address of the campaign creator\n /// @dev If set to address(0), will be automatically set to msg.sender when the campaign is created\n address creator;\n /// @notice Token distributed as rewards to campaign participants\n address rewardToken;\n /// @notice Total amount of rewardToken to distribute over the entire campaign duration\n /// @dev Must meet the minimum amount requirement for the reward token\n uint256 amount;\n /// @notice Type identifier for the campaign structure and rules\n /// @dev Different types may have different campaignData encoding schemes\n uint32 campaignType;\n /// @notice Unix timestamp when reward distribution begins\n uint32 startTimestamp;\n /// @notice Total duration of the campaign in seconds\n uint32 duration;\n /// @notice Encoded campaign-specific parameters\n /// @dev Encoding structure depends on campaignType\n /// @dev May include pool addresses, reward distribution rules, whitelists, etc.\n bytes campaignData;\n}\n"},"contracts/struct/DistributionParameters.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.0;\n\nstruct DistributionParameters {\n // ID of the reward (populated once created). This can be left as a null bytes32 when creating distributions\n // on Merkl.\n bytes32 rewardId;\n // Address of the UniswapV3 pool that needs to be incentivized\n address uniV3Pool;\n // Address of the reward token for the incentives\n address rewardToken;\n // Amount of `rewardToken` to distribute across all the epochs\n // Amount distributed per epoch is `amount/numEpoch`\n uint256 amount;\n // List of all position wrappers to consider or not for this contract. Some wrappers like Gamma or Arrakis\n // are automatically detected and so there is no need to specify them here. Check out the docs to find out\n // which need to be specified and which are not automatically detected.\n address[] positionWrappers;\n // Type (blacklist==3, whitelist==0, ...) encoded as a `uint32` for each wrapper in the list above. Mapping between\n // wrapper types and their corresponding `uint32` value can be found in Merkl Docs\n uint32[] wrapperTypes;\n // In the incentivization formula, how much of the fees should go to holders of token0\n // in base 10**4\n uint32 propToken0;\n // Proportion for holding token1 (in base 10**4)\n uint32 propToken1;\n // Proportion for providing a useful liquidity (in base 10**4) that generates fees\n uint32 propFees;\n // Timestamp at which the incentivization should start. This is in the same units as `block.timestamp`.\n uint32 epochStart;\n // Amount of epochs for which incentivization should last. Epochs are expressed in hours here, so for a\n // campaign of 1 week `numEpoch` should for instance be 168.\n uint32 numEpoch;\n // Whether out of range liquidity should still be incentivized or not\n // This should be equal to 1 if out of range liquidity should still be incentivized\n // and 0 otherwise.\n uint32 isOutOfRangeIncentivized;\n // How much more addresses with a maximum boost can get with respect to addresses\n // which do not have a boost (in base 4). In the case of Curve where addresses get 2.5x more\n // this would be 25000.\n uint32 boostedReward;\n // Address of the token which dictates who gets boosted rewards or not. This is optional\n // and if the zero address is given no boost will be taken into account. In the case of Curve, this address\n // would for instance be the veBoostProxy address, or in other cases the veToken address.\n address boostingAddress;\n // Additional data passed when distributing rewards. This parameter may be used in case\n // the reward distribution script needs to look into other parameters beyond the ones above.\n // In most cases, when creating a campaign on Merkl, you can leave this as an empty bytes.\n bytes additionalData;\n}\n"},"contracts/struct/RewardTokenAmounts.sol":{"content":"// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.8.0;\n\nstruct RewardTokenAmounts {\n address token;\n uint256 minimumAmountPerEpoch;\n}\n"},"node_modules/@openzeppelin/contracts-upgradeable/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"},"node_modules/@openzeppelin/contracts/utils/Strings.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.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 `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\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 /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n"},"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../ERC1967/ERC1967UpgradeUpgradeable.sol\";\nimport \"./Initializable.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 Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {\n function __UUPSUpgradeable_init() internal onlyInitializing {\n }\n\n function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n }\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 * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeTo(address newImplementation) public 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 * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) public 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 control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\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"},"node_modules/@openzeppelin/contracts-upgradeable/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"},"node_modules/@openzeppelin/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.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(uint256 x, uint256 y, uint256 denominator) 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 // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\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 one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // \u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // \u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n"},"node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n"},"node_modules/@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.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 IERC1822ProxiableUpgradeable {\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"},"node_modules/@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeaconUpgradeable.sol\";\nimport \"../../interfaces/IERC1967Upgradeable.sol\";\nimport \"../../interfaces/draft-IERC1822Upgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/StorageSlotUpgradeable.sol\";\nimport \"../utils/Initializable.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 */\nabstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {\n function __ERC1967Upgrade_init() internal onlyInitializing {\n }\n\n function __ERC1967Upgrade_init_unchained() internal onlyInitializing {\n }\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 Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlotUpgradeable.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(AddressUpgradeable.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlotUpgradeable.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(address newImplementation, bytes memory data, bool forceCall) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.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(address newImplementation, bytes memory data, bool forceCall) 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 (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822ProxiableUpgradeable(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 Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(AddressUpgradeable.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);\n }\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"},"node_modules/@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.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 IBeaconUpgradeable {\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"},"node_modules/@openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967Upgradeable {\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Emitted when the beacon is changed.\n */\n event BeaconUpgraded(address indexed beacon);\n}\n"},"node_modules/@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\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 * ```solidity\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`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\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 struct StringSlot {\n string value;\n }\n\n struct BytesSlot {\n bytes 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 /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n */\n function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n */\n function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n"}},"settings":{"remappings":["@openzeppelin/=node_modules/@openzeppelin/","forge-std/=node_modules/forge-std/src/","oz/=node_modules/@openzeppelin/contracts/","@utils/=node_modules/utils/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":100},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"outputSelection":{"*":{"*":["abi","evm.bytecode.object","evm.bytecode.sourceMap","evm.bytecode.linkReferences","evm.deployedBytecode.object","evm.deployedBytecode.sourceMap","evm.deployedBytecode.linkReferences","evm.deployedBytecode.immutableReferences","evm.methodIdentifiers","metadata"]}},"evmVersion":"shanghai","viaIR":false,"libraries":{}}}