@jbx-protocol/contracts-v1
Version:
65 lines • 430 kB
JSON
{
"language": "Solidity",
"sources": {
"contracts/abstract/JuiceboxProject.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\nimport \"./../interfaces/ITerminalV1.sol\";\n\n/** \n @notice A contract that inherits from JuiceboxProject can use Juicebox as a business-model-as-a-service.\n @dev The owner of the contract makes admin decisions such as:\n - Which address is the funding cycle owner, which can tap funds from the funding cycle.\n - Should this project's Tickets be migrated to a new TerminalV1. \n*/\nabstract contract JuiceboxProject is IERC721Receiver, Ownable {\n /// @notice The direct deposit terminals.\n ITerminalDirectory public immutable terminalDirectory;\n\n /// @notice The ID of the project that should be used to forward this contract's received payments.\n uint256 public projectId;\n\n /** \n @param _projectId The ID of the project that should be used to forward this contract's received payments.\n @param _terminalDirectory A directory of a project's current Juicebox terminal to receive payments in.\n */\n constructor(uint256 _projectId, ITerminalDirectory _terminalDirectory) {\n projectId = _projectId;\n terminalDirectory = _terminalDirectory;\n }\n\n receive() external payable {}\n\n /** \n @notice Withdraws funds stored in this contract.\n @param _beneficiary The address to send the funds to.\n @param _amount The amount to send.\n */\n function withdraw(address payable _beneficiary, uint256 _amount)\n external\n onlyOwner\n {\n Address.sendValue(_beneficiary, _amount);\n }\n\n /** \n @notice Allows the project that is being managed to be set.\n @param _projectId The ID of the project that is being managed.\n */\n function setProjectId(uint256 _projectId) external onlyOwner {\n projectId = _projectId;\n }\n\n /** \n @notice Make a payment to this project.\n @param _beneficiary The address who will receive tickets from this fee.\n @param _memo A memo that will be included in the published event.\n @param _preferUnstakedTickets Whether ERC20's should be claimed automatically if they have been issued.\n */\n function pay(\n address _beneficiary,\n string calldata _memo,\n bool _preferUnstakedTickets\n ) external payable {\n require(projectId != 0, \"JuiceboxProject::pay: PROJECT_NOT_FOUND\");\n\n // Get the terminal for this contract's project.\n ITerminal _terminal = terminalDirectory.terminalOf(projectId);\n\n // There must be a terminal.\n require(\n _terminal != ITerminal(address(0)),\n \"JuiceboxProject::pay: TERMINAL_NOT_FOUND\"\n );\n\n _terminal.pay{value: msg.value}(\n projectId,\n _beneficiary,\n _memo,\n _preferUnstakedTickets\n );\n }\n\n /** \n @notice Transfer the ownership of the project to a new owner. \n @dev This contract will no longer be able to reconfigure or tap funds from this project.\n @param _projects The projects contract.\n @param _newOwner The new project owner.\n @param _projectId The ID of the project to transfer ownership of.\n @param _data Arbitrary data to include in the transaction.\n */\n function transferProjectOwnership(\n IProjects _projects,\n address _newOwner,\n uint256 _projectId,\n bytes calldata _data\n ) external onlyOwner {\n _projects.safeTransferFrom(address(this), _newOwner, _projectId, _data);\n }\n\n /** \n @notice Allows this contract to receive a project.\n */\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) public pure override returns (bytes4) {\n return this.onERC721Received.selector;\n }\n\n function setOperator(\n IOperatorStore _operatorStore,\n address _operator,\n uint256 _projectId,\n uint256[] calldata _permissionIndexes\n ) external onlyOwner {\n _operatorStore.setOperator(_operator, _projectId, _permissionIndexes);\n }\n\n function setOperators(\n IOperatorStore _operatorStore,\n address[] calldata _operators,\n uint256[] calldata _projectIds,\n uint256[][] calldata _permissionIndexes\n ) external onlyOwner {\n _operatorStore.setOperators(\n _operators,\n _projectIds,\n _permissionIndexes\n );\n }\n\n /** \n @notice Take a fee for this project from this contract.\n @param _amount The payment amount.\n @param _beneficiary The address who will receive tickets from this fee.\n @param _memo A memo that will be included in the published event.\n @param _preferUnstakedTickets Whether ERC20's should be claimed automatically if they have been issued.\n */\n function _takeFee(\n uint256 _amount,\n address _beneficiary,\n string memory _memo,\n bool _preferUnstakedTickets\n ) internal {\n require(projectId != 0, \"JuiceboxProject::takeFee: PROJECT_NOT_FOUND\");\n // Find the terminal for this contract's project.\n ITerminal _terminal = terminalDirectory.terminalOf(projectId);\n\n // There must be a terminal.\n require(\n _terminal != ITerminal(address(0)),\n \"JuiceboxProject::takeFee: TERMINAL_NOT_FOUND\"\n );\n\n // There must be enough funds in the contract to take the fee.\n require(\n address(this).balance >= _amount,\n \"JuiceboxProject::takeFee: INSUFFICIENT_FUNDS\"\n );\n\n // Send funds to the terminal.\n _terminal.pay{value: _amount}(\n projectId,\n _beneficiary,\n _memo,\n _preferUnstakedTickets\n );\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
},
"@openzeppelin/contracts/access/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _setOwner(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _setOwner(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _setOwner(newOwner);\n }\n\n function _setOwner(address newOwner) private {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n"
},
"@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return _verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) private pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\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\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}\n"
},
"contracts/interfaces/ITerminalV1.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport '@openzeppelin/contracts/token/ERC721/IERC721.sol';\n\nimport './ITicketBooth.sol';\nimport './IFundingCycles.sol';\nimport './IYielder.sol';\nimport './IProjects.sol';\nimport './IModStore.sol';\nimport './IPrices.sol';\nimport './ITerminal.sol';\nimport './IOperatorStore.sol';\n\nstruct FundingCycleMetadata {\n uint256 reservedRate;\n uint256 bondingCurveRate;\n uint256 reconfigurationBondingCurveRate;\n}\n\ninterface ITerminalV1 {\n event Pay(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n address indexed beneficiary,\n uint256 amount,\n string note,\n address caller\n );\n\n event AddToBalance(uint256 indexed projectId, uint256 value, address caller);\n\n event AllowMigration(ITerminal allowed);\n\n event Migrate(uint256 indexed projectId, ITerminal indexed to, uint256 _amount, address caller);\n\n event Configure(uint256 indexed fundingCycleId, uint256 indexed projectId, address caller);\n\n event Tap(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n address indexed beneficiary,\n uint256 amount,\n uint256 currency,\n uint256 netTransferAmount,\n uint256 beneficiaryTransferAmount,\n uint256 govFeeAmount,\n address caller\n );\n event Redeem(\n address indexed holder,\n address indexed beneficiary,\n uint256 indexed _projectId,\n uint256 amount,\n uint256 returnAmount,\n address caller\n );\n\n event PrintReserveTickets(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n address indexed beneficiary,\n uint256 count,\n uint256 beneficiaryTicketAmount,\n address caller\n );\n\n event DistributeToPayoutMod(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n PayoutMod mod,\n uint256 modCut,\n address caller\n );\n event DistributeToTicketMod(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n TicketMod mod,\n uint256 modCut,\n address caller\n );\n event AppointGovernance(address governance);\n\n event AcceptGovernance(address governance);\n\n event PrintPreminedTickets(\n uint256 indexed projectId,\n address indexed beneficiary,\n uint256 amount,\n uint256 currency,\n string memo,\n address caller\n );\n\n event Deposit(uint256 amount);\n\n event EnsureTargetLocalWei(uint256 target);\n\n event SetYielder(IYielder newYielder);\n\n event SetFee(uint256 _amount);\n\n event SetTargetLocalWei(uint256 amount);\n\n function governance() external view returns (address payable);\n\n function pendingGovernance() external view returns (address payable);\n\n function projects() external view returns (IProjects);\n\n function fundingCycles() external view returns (IFundingCycles);\n\n function ticketBooth() external view returns (ITicketBooth);\n\n function prices() external view returns (IPrices);\n\n function modStore() external view returns (IModStore);\n\n function reservedTicketBalanceOf(uint256 _projectId, uint256 _reservedRate)\n external\n view\n returns (uint256);\n\n function canPrintPreminedTickets(uint256 _projectId) external view returns (bool);\n\n function balanceOf(uint256 _projectId) external view returns (uint256);\n\n function currentOverflowOf(uint256 _projectId) external view returns (uint256);\n\n function claimableOverflowOf(\n address _account,\n uint256 _amount,\n uint256 _projectId\n ) external view returns (uint256);\n\n function fee() external view returns (uint256);\n\n function deploy(\n address _owner,\n bytes32 _handle,\n string calldata _uri,\n FundingCycleProperties calldata _properties,\n FundingCycleMetadata calldata _metadata,\n PayoutMod[] memory _payoutMods,\n TicketMod[] memory _ticketMods\n ) external;\n\n function configure(\n uint256 _projectId,\n FundingCycleProperties calldata _properties,\n FundingCycleMetadata calldata _metadata,\n PayoutMod[] memory _payoutMods,\n TicketMod[] memory _ticketMods\n ) external returns (uint256);\n\n function printPreminedTickets(\n uint256 _projectId,\n uint256 _amount,\n uint256 _currency,\n address _beneficiary,\n string memory _memo,\n bool _preferUnstakedTickets\n ) external;\n\n function tap(\n uint256 _projectId,\n uint256 _amount,\n uint256 _currency,\n uint256 _minReturnedWei\n ) external returns (uint256);\n\n function redeem(\n address _account,\n uint256 _projectId,\n uint256 _amount,\n uint256 _minReturnedWei,\n address payable _beneficiary,\n bool _preferUnstaked\n ) external returns (uint256 returnAmount);\n\n function printReservedTickets(uint256 _projectId)\n external\n returns (uint256 reservedTicketsToPrint);\n\n function setFee(uint256 _fee) external;\n\n function appointGovernance(address payable _pendingGovernance) external;\n\n function acceptGovernance() external;\n}\n"
},
"@openzeppelin/contracts/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"
},
"@openzeppelin/contracts/token/ERC721/IERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n}\n"
},
"contracts/interfaces/ITicketBooth.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"./IProjects.sol\";\nimport \"./IOperatorStore.sol\";\nimport \"./ITickets.sol\";\n\ninterface ITicketBooth {\n event Issue(\n uint256 indexed projectId,\n string name,\n string symbol,\n address caller\n );\n event Print(\n address indexed holder,\n uint256 indexed projectId,\n uint256 amount,\n bool convertedTickets,\n bool preferUnstakedTickets,\n address controller\n );\n\n event Redeem(\n address indexed holder,\n uint256 indexed projectId,\n uint256 amount,\n uint256 stakedTickets,\n bool preferUnstaked,\n address controller\n );\n\n event Stake(\n address indexed holder,\n uint256 indexed projectId,\n uint256 amount,\n address caller\n );\n\n event Unstake(\n address indexed holder,\n uint256 indexed projectId,\n uint256 amount,\n address caller\n );\n\n event Lock(\n address indexed holder,\n uint256 indexed projectId,\n uint256 amount,\n address caller\n );\n\n event Unlock(\n address indexed holder,\n uint256 indexed projectId,\n uint256 amount,\n address caller\n );\n\n event Transfer(\n address indexed holder,\n uint256 indexed projectId,\n address indexed recipient,\n uint256 amount,\n address caller\n );\n\n function ticketsOf(uint256 _projectId) external view returns (ITickets);\n\n function projects() external view returns (IProjects);\n\n function lockedBalanceOf(address _holder, uint256 _projectId)\n external\n view\n returns (uint256);\n\n function lockedBalanceBy(\n address _operator,\n address _holder,\n uint256 _projectId\n ) external view returns (uint256);\n\n function stakedBalanceOf(address _holder, uint256 _projectId)\n external\n view\n returns (uint256);\n\n function stakedTotalSupplyOf(uint256 _projectId)\n external\n view\n returns (uint256);\n\n function totalSupplyOf(uint256 _projectId) external view returns (uint256);\n\n function balanceOf(address _holder, uint256 _projectId)\n external\n view\n returns (uint256 _result);\n\n function issue(\n uint256 _projectId,\n string calldata _name,\n string calldata _symbol\n ) external;\n\n function print(\n address _holder,\n uint256 _projectId,\n uint256 _amount,\n bool _preferUnstakedTickets\n ) external;\n\n function redeem(\n address _holder,\n uint256 _projectId,\n uint256 _amount,\n bool _preferUnstaked\n ) external;\n\n function stake(\n address _holder,\n uint256 _projectId,\n uint256 _amount\n ) external;\n\n function unstake(\n address _holder,\n uint256 _projectId,\n uint256 _amount\n ) external;\n\n function lock(\n address _holder,\n uint256 _projectId,\n uint256 _amount\n ) external;\n\n function unlock(\n address _holder,\n uint256 _projectId,\n uint256 _amount\n ) external;\n\n function transfer(\n address _holder,\n uint256 _projectId,\n uint256 _amount,\n address _recipient\n ) external;\n}\n"
},
"contracts/interfaces/IFundingCycles.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"./IPrices.sol\";\nimport \"./IProjects.sol\";\nimport \"./IFundingCycleBallot.sol\";\n\n/// @notice The funding cycle structure represents a project stewarded by an address, and accounts for which addresses have helped sustain the project.\nstruct FundingCycle {\n // A unique number that's incremented for each new funding cycle, starting with 1.\n uint256 id;\n // The ID of the project contract that this funding cycle belongs to.\n uint256 projectId;\n // The number of this funding cycle for the project.\n uint256 number;\n // The ID of a previous funding cycle that this one is based on.\n uint256 basedOn;\n // The time when this funding cycle was last configured.\n uint256 configured;\n // The number of cycles that this configuration should last for before going back to the last permanent.\n uint256 cycleLimit;\n // A number determining the amount of redistribution shares this funding cycle will issue to each sustainer.\n uint256 weight;\n // The ballot contract to use to determine a subsequent funding cycle's reconfiguration status.\n IFundingCycleBallot ballot;\n // The time when this funding cycle will become active.\n uint256 start;\n // The number of seconds until this funding cycle's surplus is redistributed.\n uint256 duration;\n // The amount that this funding cycle is targeting in terms of the currency.\n uint256 target;\n // The currency that the target is measured in.\n uint256 currency;\n // The percentage of each payment to send as a fee to the Juicebox admin.\n uint256 fee;\n // A percentage indicating how much more weight to give a funding cycle compared to its predecessor.\n uint256 discountRate;\n // The amount of available funds that have been tapped by the project in terms of the currency.\n uint256 tapped;\n // A packed list of extra data. The first 8 bytes are reserved for versioning.\n uint256 metadata;\n}\n\nstruct FundingCycleProperties {\n uint256 target;\n uint256 currency;\n uint256 duration;\n uint256 cycleLimit;\n uint256 discountRate;\n IFundingCycleBallot ballot;\n}\n\ninterface IFundingCycles {\n event Configure(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n uint256 reconfigured,\n FundingCycleProperties _properties,\n uint256 metadata,\n address caller\n );\n\n event Tap(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n uint256 amount,\n uint256 newTappedAmount,\n address caller\n );\n\n event Init(\n uint256 indexed fundingCycleId,\n uint256 indexed projectId,\n uint256 number,\n uint256 previous,\n uint256 weight,\n uint256 start\n );\n\n function latestIdOf(uint256 _projectId) external view returns (uint256);\n\n function count() external view returns (uint256);\n\n function BASE_WEIGHT() external view returns (uint256);\n\n function MAX_CYCLE_LIMIT() external view returns (uint256);\n\n function get(uint256 _fundingCycleId)\n external\n view\n returns (FundingCycle memory);\n\n function queuedOf(uint256 _projectId)\n external\n view\n returns (FundingCycle memory);\n\n function currentOf(uint256 _projectId)\n external\n view\n returns (FundingCycle memory);\n\n function currentBallotStateOf(uint256 _projectId)\n external\n view\n returns (BallotState);\n\n function configure(\n uint256 _projectId,\n FundingCycleProperties calldata _properties,\n uint256 _metadata,\n uint256 _fee,\n bool _configureActiveFundingCycle\n ) external returns (FundingCycle memory fundingCycle);\n\n function tap(uint256 _projectId, uint256 _amount)\n external\n returns (FundingCycle memory fundingCycle);\n}\n"
},
"contracts/interfaces/IYielder.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"./ITerminalV1.sol\";\n\n// In constructure, give unlimited access for TerminalV1 to take money from this.\ninterface IYielder {\n function deposited() external view returns (uint256);\n\n function getCurrentBalance() external view returns (uint256);\n\n function deposit() external payable;\n\n function withdraw(uint256 _amount, address payable _beneficiary) external;\n\n function withdrawAll(address payable _beneficiary)\n external\n returns (uint256);\n}\n"
},
"contracts/interfaces/IProjects.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\nimport \"./ITerminal.sol\";\nimport \"./IOperatorStore.sol\";\n\ninterface IProjects is IERC721 {\n event Create(\n uint256 indexed projectId,\n address indexed owner,\n bytes32 indexed handle,\n string uri,\n ITerminal terminal,\n address caller\n );\n\n event SetHandle(\n uint256 indexed projectId,\n bytes32 indexed handle,\n address caller\n );\n\n event SetUri(uint256 indexed projectId, string uri, address caller);\n\n event TransferHandle(\n uint256 indexed projectId,\n address indexed to,\n bytes32 indexed handle,\n bytes32 newHandle,\n address caller\n );\n\n event ClaimHandle(\n address indexed account,\n uint256 indexed projectId,\n bytes32 indexed handle,\n address caller\n );\n\n event ChallengeHandle(\n bytes32 indexed handle,\n uint256 challengeExpiry,\n address caller\n );\n\n event RenewHandle(\n bytes32 indexed handle,\n uint256 indexed projectId,\n address caller\n );\n\n function count() external view returns (uint256);\n\n function uriOf(uint256 _projectId) external view returns (string memory);\n\n function handleOf(uint256 _projectId) external returns (bytes32 handle);\n\n function projectFor(bytes32 _handle) external returns (uint256 projectId);\n\n function transferAddressFor(bytes32 _handle)\n external\n returns (address receiver);\n\n function challengeExpiryOf(bytes32 _handle) external returns (uint256);\n\n function exists(uint256 _projectId) external view returns (bool);\n\n function create(\n address _owner,\n bytes32 _handle,\n string calldata _uri,\n ITerminal _terminal\n ) external returns (uint256 id);\n\n function setHandle(uint256 _projectId, bytes32 _handle) external;\n\n function setUri(uint256 _projectId, string calldata _uri) external;\n\n function transferHandle(\n uint256 _projectId,\n address _to,\n bytes32 _newHandle\n ) external returns (bytes32 _handle);\n\n function claimHandle(\n bytes32 _handle,\n address _for,\n uint256 _projectId\n ) external;\n}\n"
},
"contracts/interfaces/IModStore.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"./IOperatorStore.sol\";\nimport \"./IProjects.sol\";\nimport \"./IModAllocator.sol\";\n\nstruct PayoutMod {\n bool preferUnstaked;\n uint16 percent;\n uint48 lockedUntil;\n address payable beneficiary;\n IModAllocator allocator;\n uint56 projectId;\n}\n\nstruct TicketMod {\n bool preferUnstaked;\n uint16 percent;\n uint48 lockedUntil;\n address payable beneficiary;\n}\n\ninterface IModStore {\n event SetPayoutMod(\n uint256 indexed projectId,\n uint256 indexed configuration,\n PayoutMod mods,\n address caller\n );\n\n event SetTicketMod(\n uint256 indexed projectId,\n uint256 indexed configuration,\n TicketMod mods,\n address caller\n );\n\n function projects() external view returns (IProjects);\n\n function payoutModsOf(uint256 _projectId, uint256 _configuration)\n external\n view\n returns (PayoutMod[] memory);\n\n function ticketModsOf(uint256 _projectId, uint256 _configuration)\n external\n view\n returns (TicketMod[] memory);\n\n function setPayoutMods(\n uint256 _projectId,\n uint256 _configuration,\n PayoutMod[] memory _mods\n ) external;\n\n function setTicketMods(\n uint256 _projectId,\n uint256 _configuration,\n TicketMod[] memory _mods\n ) external;\n}\n"
},
"contracts/interfaces/IPrices.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol\";\n\ninterface IPrices {\n event AddFeed(uint256 indexed currency, AggregatorV3Interface indexed feed);\n\n function feedDecimalAdjuster(uint256 _currency) external returns (uint256);\n\n function targetDecimals() external returns (uint256);\n\n function feedFor(uint256 _currency)\n external\n returns (AggregatorV3Interface);\n\n function getETHPriceFor(uint256 _currency) external view returns (uint256);\n\n function addFeed(AggregatorV3Interface _priceFeed, uint256 _currency)\n external;\n}\n"
},
"contracts/interfaces/ITerminal.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport './ITerminalDirectory.sol';\n\ninterface ITerminal {\n function terminalDirectory() external view returns (ITerminalDirectory);\n\n function migrationIsAllowed(ITerminal _terminal) external view returns (bool);\n\n function pay(\n uint256 _projectId,\n address _beneficiary,\n string calldata _memo,\n bool _preferUnstakedTickets\n ) external payable returns (uint256 fundingCycleId);\n\n function addToBalance(uint256 _projectId) external payable;\n\n function allowMigration(ITerminal _contract) external;\n\n function migrate(uint256 _projectId, ITerminal _to) external;\n}\n"
},
"contracts/interfaces/IOperatorStore.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\ninterface IOperatorStore {\n event SetOperator(\n address indexed operator,\n address indexed account,\n uint256 indexed domain,\n uint256[] permissionIndexes,\n uint256 packed\n );\n\n function permissionsOf(\n address _operator,\n address _account,\n uint256 _domain\n ) external view returns (uint256);\n\n function hasPermission(\n address _operator,\n address _account,\n uint256 _domain,\n uint256 _permissionIndex\n ) external view returns (bool);\n\n function hasPermissions(\n address _operator,\n address _account,\n uint256 _domain,\n uint256[] calldata _permissionIndexes\n ) external view returns (bool);\n\n function setOperator(\n address _operator,\n uint256 _domain,\n uint256[] calldata _permissionIndexes\n ) external;\n\n function setOperators(\n address[] calldata _operators,\n uint256[] calldata _domains,\n uint256[][] calldata _permissionIndexes\n ) external;\n}\n"
},
"@openzeppelin/contracts/utils/introspection/IERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
},
"contracts/interfaces/ITickets.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ITickets is IERC20 {\n function print(address _account, uint256 _amount) external;\n\n function redeem(address _account, uint256 _amount) external;\n}\n"
},
"contracts/interfaces/ITerminalDirectory.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"./IDirectPaymentAddress.sol\";\nimport \"./ITerminal.sol\";\nimport \"./IProjects.sol\";\nimport \"./IProjects.sol\";\n\ninterface ITerminalDirectory {\n event DeployAddress(\n uint256 indexed projectId,\n string memo,\n address indexed caller\n );\n\n event SetTerminal(\n uint256 indexed projectId,\n ITerminal indexed terminal,\n address caller\n );\n\n event SetPayerPreferences(\n address indexed account,\n address beneficiary,\n bool preferUnstakedTickets\n );\n\n function projects() external view returns (IProjects);\n\n function terminalOf(uint256 _projectId) external view returns (ITerminal);\n\n function beneficiaryOf(address _account) external returns (address);\n\n function unstakedTicketsPreferenceOf(address _account)\n external\n returns (bool);\n\n function addressesOf(uint256 _projectId)\n external\n view\n returns (IDirectPaymentAddress[] memory);\n\n function deployAddress(uint256 _projectId, string calldata _memo) external;\n\n function setTerminal(uint256 _projectId, ITerminal _terminal) external;\n\n function setPayerPreferences(\n address _beneficiary,\n bool _preferUnstakedTickets\n ) external;\n}\n"
},
"contracts/interfaces/IDirectPaymentAddress.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"./ITerminalDirectory.sol\";\nimport \"./ITerminal.sol\";\n\ninterface IDirectPaymentAddress {\n event Forward(\n address indexed payer,\n uint256 indexed projectId,\n address beneficiary,\n uint256 value,\n string memo,\n bool preferUnstakedTickets\n );\n\n function terminalDirectory() external returns (ITerminalDirectory);\n\n function projectId() external returns (uint256);\n\n function memo() external returns (string memory);\n}\n"
},
"@openzeppelin/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\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 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 `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, 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 `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\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"
},
"contracts/interfaces/IFundingCycleBallot.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.6;\n\nimport \"./ITerminalV1.sol\";\n\nenum BallotState {\n Approved,\n Active,\n Failed,\n Standby\n}\n\ninterface IFundingCycleBallot {\n function duration() external view returns (uint256);\n\n function state(uint256 _fundingCycleId, uint256 _configur