文件 1 的 32:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 32:AggregatorV3Interface.sol
pragma solidity >=0.6.0;
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function version() external view returns (uint256);
function getRoundData(uint80 _roundId)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
文件 3 的 32:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 32:IDirectPaymentAddress.sol
pragma solidity 0.8.6;
import "./ITerminalDirectory.sol";
import "./ITerminal.sol";
interface IDirectPaymentAddress {
event Forward(
address indexed payer,
uint256 indexed projectId,
address beneficiary,
uint256 value,
string memo,
bool preferUnstakedTickets
);
function terminalDirectory() external returns (ITerminalDirectory);
function projectId() external returns (uint256);
function memo() external returns (string memory);
}
文件 5 的 32:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 6 的 32:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 7 的 32:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 8 的 32:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 9 的 32:IFundingCycleBallot.sol
pragma solidity 0.8.6;
import "./ITerminalV1.sol";
enum BallotState {
Approved,
Active,
Failed,
Standby
}
interface IFundingCycleBallot {
function duration() external view returns (uint256);
function state(uint256 _fundingCycleId, uint256 _configured)
external
view
returns (BallotState);
}
文件 10 的 32:IFundingCycles.sol
pragma solidity 0.8.6;
import "./IPrices.sol";
import "./IProjects.sol";
import "./IFundingCycleBallot.sol";
struct FundingCycle {
uint256 id;
uint256 projectId;
uint256 number;
uint256 basedOn;
uint256 configured;
uint256 cycleLimit;
uint256 weight;
IFundingCycleBallot ballot;
uint256 start;
uint256 duration;
uint256 target;
uint256 currency;
uint256 fee;
uint256 discountRate;
uint256 tapped;
uint256 metadata;
}
struct FundingCycleProperties {
uint256 target;
uint256 currency;
uint256 duration;
uint256 cycleLimit;
uint256 discountRate;
IFundingCycleBallot ballot;
}
interface IFundingCycles {
event Configure(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
uint256 reconfigured,
FundingCycleProperties _properties,
uint256 metadata,
address caller
);
event Tap(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
uint256 amount,
uint256 newTappedAmount,
address caller
);
event Init(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
uint256 number,
uint256 previous,
uint256 weight,
uint256 start
);
function latestIdOf(uint256 _projectId) external view returns (uint256);
function count() external view returns (uint256);
function BASE_WEIGHT() external view returns (uint256);
function MAX_CYCLE_LIMIT() external view returns (uint256);
function get(uint256 _fundingCycleId)
external
view
returns (FundingCycle memory);
function queuedOf(uint256 _projectId)
external
view
returns (FundingCycle memory);
function currentOf(uint256 _projectId)
external
view
returns (FundingCycle memory);
function currentBallotStateOf(uint256 _projectId)
external
view
returns (BallotState);
function configure(
uint256 _projectId,
FundingCycleProperties calldata _properties,
uint256 _metadata,
uint256 _fee,
bool _configureActiveFundingCycle
) external returns (FundingCycle memory fundingCycle);
function tap(uint256 _projectId, uint256 _amount)
external
returns (FundingCycle memory fundingCycle);
}
文件 11 的 32:IModAllocator.sol
pragma solidity 0.8.6;
interface IModAllocator {
event Allocate(
uint256 indexed projectId,
uint256 indexed forProjectId,
address indexed beneficiary,
uint256 amount,
address caller
);
function allocate(
uint256 _projectId,
uint256 _forProjectId,
address _beneficiary
) external payable;
}
文件 12 的 32:IModStore.sol
pragma solidity 0.8.6;
import "./IOperatorStore.sol";
import "./IProjects.sol";
import "./IModAllocator.sol";
struct PayoutMod {
bool preferUnstaked;
uint16 percent;
uint48 lockedUntil;
address payable beneficiary;
IModAllocator allocator;
uint56 projectId;
}
struct TicketMod {
bool preferUnstaked;
uint16 percent;
uint48 lockedUntil;
address payable beneficiary;
}
interface IModStore {
event SetPayoutMod(
uint256 indexed projectId,
uint256 indexed configuration,
PayoutMod mods,
address caller
);
event SetTicketMod(
uint256 indexed projectId,
uint256 indexed configuration,
TicketMod mods,
address caller
);
function projects() external view returns (IProjects);
function payoutModsOf(uint256 _projectId, uint256 _configuration)
external
view
returns (PayoutMod[] memory);
function ticketModsOf(uint256 _projectId, uint256 _configuration)
external
view
returns (TicketMod[] memory);
function setPayoutMods(
uint256 _projectId,
uint256 _configuration,
PayoutMod[] memory _mods
) external;
function setTicketMods(
uint256 _projectId,
uint256 _configuration,
TicketMod[] memory _mods
) external;
}
文件 13 的 32:IOperatable.sol
pragma solidity 0.8.6;
import "./IOperatorStore.sol";
interface IOperatable {
function operatorStore() external view returns (IOperatorStore);
}
文件 14 的 32:IOperatorStore.sol
pragma solidity 0.8.6;
interface IOperatorStore {
event SetOperator(
address indexed operator,
address indexed account,
uint256 indexed domain,
uint256[] permissionIndexes,
uint256 packed
);
function permissionsOf(
address _operator,
address _account,
uint256 _domain
) external view returns (uint256);
function hasPermission(
address _operator,
address _account,
uint256 _domain,
uint256 _permissionIndex
) external view returns (bool);
function hasPermissions(
address _operator,
address _account,
uint256 _domain,
uint256[] calldata _permissionIndexes
) external view returns (bool);
function setOperator(
address _operator,
uint256 _domain,
uint256[] calldata _permissionIndexes
) external;
function setOperators(
address[] calldata _operators,
uint256[] calldata _domains,
uint256[][] calldata _permissionIndexes
) external;
}
文件 15 的 32:IPrices.sol
pragma solidity 0.8.6;
import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
interface IPrices {
event AddFeed(uint256 indexed currency, AggregatorV3Interface indexed feed);
function feedDecimalAdjuster(uint256 _currency) external returns (uint256);
function targetDecimals() external returns (uint256);
function feedFor(uint256 _currency)
external
returns (AggregatorV3Interface);
function getETHPriceFor(uint256 _currency) external view returns (uint256);
function addFeed(AggregatorV3Interface _priceFeed, uint256 _currency)
external;
}
文件 16 的 32:IProjects.sol
pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./ITerminal.sol";
import "./IOperatorStore.sol";
interface IProjects is IERC721 {
event Create(
uint256 indexed projectId,
address indexed owner,
bytes32 indexed handle,
string uri,
ITerminal terminal,
address caller
);
event SetHandle(
uint256 indexed projectId,
bytes32 indexed handle,
address caller
);
event SetUri(uint256 indexed projectId, string uri, address caller);
event TransferHandle(
uint256 indexed projectId,
address indexed to,
bytes32 indexed handle,
bytes32 newHandle,
address caller
);
event ClaimHandle(
address indexed account,
uint256 indexed projectId,
bytes32 indexed handle,
address caller
);
event ChallengeHandle(
bytes32 indexed handle,
uint256 challengeExpiry,
address caller
);
event RenewHandle(
bytes32 indexed handle,
uint256 indexed projectId,
address caller
);
function count() external view returns (uint256);
function uriOf(uint256 _projectId) external view returns (string memory);
function handleOf(uint256 _projectId) external returns (bytes32 handle);
function projectFor(bytes32 _handle) external returns (uint256 projectId);
function transferAddressFor(bytes32 _handle)
external
returns (address receiver);
function challengeExpiryOf(bytes32 _handle) external returns (uint256);
function exists(uint256 _projectId) external view returns (bool);
function create(
address _owner,
bytes32 _handle,
string calldata _uri,
ITerminal _terminal
) external returns (uint256 id);
function setHandle(uint256 _projectId, bytes32 _handle) external;
function setUri(uint256 _projectId, string calldata _uri) external;
function transferHandle(
uint256 _projectId,
address _to,
bytes32 _newHandle
) external returns (bytes32 _handle);
function claimHandle(
bytes32 _handle,
address _for,
uint256 _projectId
) external;
}
文件 17 的 32:ITerminal.sol
pragma solidity 0.8.6;
import './ITerminalDirectory.sol';
interface ITerminal {
function terminalDirectory() external view returns (ITerminalDirectory);
function migrationIsAllowed(ITerminal _terminal) external view returns (bool);
function pay(
uint256 _projectId,
address _beneficiary,
string calldata _memo,
bool _preferUnstakedTickets
) external payable returns (uint256 fundingCycleId);
function addToBalance(uint256 _projectId) external payable;
function allowMigration(ITerminal _contract) external;
function migrate(uint256 _projectId, ITerminal _to) external;
}
文件 18 的 32:ITerminalDirectory.sol
pragma solidity 0.8.6;
import "./IDirectPaymentAddress.sol";
import "./ITerminal.sol";
import "./IProjects.sol";
import "./IProjects.sol";
interface ITerminalDirectory {
event DeployAddress(
uint256 indexed projectId,
string memo,
address indexed caller
);
event SetTerminal(
uint256 indexed projectId,
ITerminal indexed terminal,
address caller
);
event SetPayerPreferences(
address indexed account,
address beneficiary,
bool preferUnstakedTickets
);
function projects() external view returns (IProjects);
function terminalOf(uint256 _projectId) external view returns (ITerminal);
function beneficiaryOf(address _account) external returns (address);
function unstakedTicketsPreferenceOf(address _account)
external
returns (bool);
function addressesOf(uint256 _projectId)
external
view
returns (IDirectPaymentAddress[] memory);
function deployAddress(uint256 _projectId, string calldata _memo) external;
function setTerminal(uint256 _projectId, ITerminal _terminal) external;
function setPayerPreferences(
address _beneficiary,
bool _preferUnstakedTickets
) external;
}
文件 19 的 32:ITerminalV1.sol
pragma solidity 0.8.6;
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import './ITicketBooth.sol';
import './IFundingCycles.sol';
import './IYielder.sol';
import './IProjects.sol';
import './IModStore.sol';
import './IPrices.sol';
import './ITerminal.sol';
import './IOperatorStore.sol';
struct FundingCycleMetadata {
uint256 reservedRate;
uint256 bondingCurveRate;
uint256 reconfigurationBondingCurveRate;
}
interface ITerminalV1 {
event Pay(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
address indexed beneficiary,
uint256 amount,
string note,
address caller
);
event AddToBalance(uint256 indexed projectId, uint256 value, address caller);
event AllowMigration(ITerminal allowed);
event Migrate(uint256 indexed projectId, ITerminal indexed to, uint256 _amount, address caller);
event Configure(uint256 indexed fundingCycleId, uint256 indexed projectId, address caller);
event Tap(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
address indexed beneficiary,
uint256 amount,
uint256 currency,
uint256 netTransferAmount,
uint256 beneficiaryTransferAmount,
uint256 govFeeAmount,
address caller
);
event Redeem(
address indexed holder,
address indexed beneficiary,
uint256 indexed _projectId,
uint256 amount,
uint256 returnAmount,
address caller
);
event PrintReserveTickets(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
address indexed beneficiary,
uint256 count,
uint256 beneficiaryTicketAmount,
address caller
);
event DistributeToPayoutMod(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
PayoutMod mod,
uint256 modCut,
address caller
);
event DistributeToTicketMod(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
TicketMod mod,
uint256 modCut,
address caller
);
event AppointGovernance(address governance);
event AcceptGovernance(address governance);
event PrintPreminedTickets(
uint256 indexed projectId,
address indexed beneficiary,
uint256 amount,
uint256 currency,
string memo,
address caller
);
event Deposit(uint256 amount);
event EnsureTargetLocalWei(uint256 target);
event SetYielder(IYielder newYielder);
event SetFee(uint256 _amount);
event SetTargetLocalWei(uint256 amount);
function governance() external view returns (address payable);
function pendingGovernance() external view returns (address payable);
function projects() external view returns (IProjects);
function fundingCycles() external view returns (IFundingCycles);
function ticketBooth() external view returns (ITicketBooth);
function prices() external view returns (IPrices);
function modStore() external view returns (IModStore);
function reservedTicketBalanceOf(uint256 _projectId, uint256 _reservedRate)
external
view
returns (uint256);
function canPrintPreminedTickets(uint256 _projectId) external view returns (bool);
function balanceOf(uint256 _projectId) external view returns (uint256);
function currentOverflowOf(uint256 _projectId) external view returns (uint256);
function claimableOverflowOf(
address _account,
uint256 _amount,
uint256 _projectId
) external view returns (uint256);
function fee() external view returns (uint256);
function deploy(
address _owner,
bytes32 _handle,
string calldata _uri,
FundingCycleProperties calldata _properties,
FundingCycleMetadata calldata _metadata,
PayoutMod[] memory _payoutMods,
TicketMod[] memory _ticketMods
) external;
function configure(
uint256 _projectId,
FundingCycleProperties calldata _properties,
FundingCycleMetadata calldata _metadata,
PayoutMod[] memory _payoutMods,
TicketMod[] memory _ticketMods
) external returns (uint256);
function printPreminedTickets(
uint256 _projectId,
uint256 _amount,
uint256 _currency,
address _beneficiary,
string memory _memo,
bool _preferUnstakedTickets
) external;
function tap(
uint256 _projectId,
uint256 _amount,
uint256 _currency,
uint256 _minReturnedWei
) external returns (uint256);
function redeem(
address _account,
uint256 _projectId,
uint256 _amount,
uint256 _minReturnedWei,
address payable _beneficiary,
bool _preferUnstaked
) external returns (uint256 returnAmount);
function printReservedTickets(uint256 _projectId)
external
returns (uint256 reservedTicketsToPrint);
function setFee(uint256 _fee) external;
function appointGovernance(address payable _pendingGovernance) external;
function acceptGovernance() external;
}
文件 20 的 32:ITerminalV1_1.sol
pragma solidity 0.8.6;
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import './ITicketBooth.sol';
import './IFundingCycles.sol';
import './IYielder.sol';
import './IProjects.sol';
import './IModStore.sol';
import './ITerminal.sol';
import './IOperatorStore.sol';
import './ITreasuryExtension.sol';
struct FundingCycleMetadata2 {
uint256 reservedRate;
uint256 bondingCurveRate;
uint256 reconfigurationBondingCurveRate;
bool payIsPaused;
bool ticketPrintingIsAllowed;
ITreasuryExtension treasuryExtension;
}
interface ITerminalV1_1 {
event Pay(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
address indexed beneficiary,
uint256 amount,
uint256 beneficiaryTokens,
uint256 totalTokens,
string note,
address caller
);
event AddToBalance(uint256 indexed projectId, uint256 value, address caller);
event AllowMigration(ITerminal allowed);
event Migrate(uint256 indexed projectId, ITerminal indexed to, uint256 _amount, address caller);
event Configure(uint256 indexed fundingCycleId, uint256 indexed projectId, address caller);
event Tap(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
address indexed beneficiary,
uint256 amount,
uint256 currency,
uint256 netTransferAmount,
uint256 beneficiaryTransferAmount,
uint256 govFeeAmount,
address caller
);
event Redeem(
address indexed holder,
address indexed beneficiary,
uint256 indexed _projectId,
uint256 amount,
uint256 returnAmount,
address caller
);
event PrintReserveTickets(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
address indexed beneficiary,
uint256 count,
uint256 beneficiaryTicketAmount,
address caller
);
event DistributeToPayoutMod(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
PayoutMod mod,
uint256 modCut,
address caller
);
event DistributeToTicketMod(
uint256 indexed fundingCycleId,
uint256 indexed projectId,
TicketMod mod,
uint256 modCut,
address caller
);
event PrintTickets(
uint256 indexed projectId,
address indexed beneficiary,
uint256 amount,
string memo,
address caller
);
event Deposit(uint256 amount);
event EnsureTargetLocalWei(uint256 target);
event SetYielder(IYielder newYielder);
event SetFee(uint256 _amount);
event SetTargetLocalWei(uint256 amount);
function projects() external view returns (IProjects);
function fundingCycles() external view returns (IFundingCycles);
function ticketBooth() external view returns (ITicketBooth);
function prices() external view returns (IPrices);
function modStore() external view returns (IModStore);
function reservedTicketBalanceOf(uint256 _projectId, uint256 _reservedRate)
external
view
returns (uint256);
function balanceOf(uint256 _projectId) external view returns (uint256);
function currentOverflowOf(uint256 _projectId) external view returns (uint256);
function claimableOverflowOf(
address _account,
uint256 _amount,
uint256 _projectId
) external view returns (uint256);
function fee() external view returns (uint256);
function deploy(
address _owner,
bytes32 _handle,
string calldata _uri,
FundingCycleProperties calldata _properties,
FundingCycleMetadata2 calldata _metadata,
PayoutMod[] memory _payoutMods,
TicketMod[] memory _ticketMods
) external;
function configure(
uint256 _projectId,
FundingCycleProperties calldata _properties,
FundingCycleMetadata2 calldata _metadata,
PayoutMod[] memory _payoutMods,
TicketMod[] memory _ticketMods
) external returns (uint256);
function printTickets(
uint256 _projectId,
uint256 _amount,
address _beneficiary,
string memory _memo,
bool _preferUnstakedTickets
) external;
function tap(
uint256 _projectId,
uint256 _amount,
uint256 _currency,
uint256 _minReturnedWei
) external returns (uint256);
function redeem(
address _account,
uint256 _projectId,
uint256 _amount,
uint256 _minReturnedWei,
address payable _beneficiary,
bool _preferUnstaked
) external returns (uint256 returnAmount);
function printReservedTickets(uint256 _projectId)
external
returns (uint256 reservedTicketsToPrint);
function setFee(uint256 _fee) external;
function burnFromDeadAddress(uint256 _projectId) external;
}
文件 21 的 32:ITicketBooth.sol
pragma solidity 0.8.6;
import "./IProjects.sol";
import "./IOperatorStore.sol";
import "./ITickets.sol";
interface ITicketBooth {
event Issue(
uint256 indexed projectId,
string name,
string symbol,
address caller
);
event Print(
address indexed holder,
uint256 indexed projectId,
uint256 amount,
bool convertedTickets,
bool preferUnstakedTickets,
address controller
);
event Redeem(
address indexed holder,
uint256 indexed projectId,
uint256 amount,
uint256 stakedTickets,
bool preferUnstaked,
address controller
);
event Stake(
address indexed holder,
uint256 indexed projectId,
uint256 amount,
address caller
);
event Unstake(
address indexed holder,
uint256 indexed projectId,
uint256 amount,
address caller
);
event Lock(
address indexed holder,
uint256 indexed projectId,
uint256 amount,
address caller
);
event Unlock(
address indexed holder,
uint256 indexed projectId,
uint256 amount,
address caller
);
event Transfer(
address indexed holder,
uint256 indexed projectId,
address indexed recipient,
uint256 amount,
address caller
);
function ticketsOf(uint256 _projectId) external view returns (ITickets);
function projects() external view returns (IProjects);
function lockedBalanceOf(address _holder, uint256 _projectId)
external
view
returns (uint256);
function lockedBalanceBy(
address _operator,
address _holder,
uint256 _projectId
) external view returns (uint256);
function stakedBalanceOf(address _holder, uint256 _projectId)
external
view
returns (uint256);
function stakedTotalSupplyOf(uint256 _projectId)
external
view
returns (uint256);
function totalSupplyOf(uint256 _projectId) external view returns (uint256);
function balanceOf(address _holder, uint256 _projectId)
external
view
returns (uint256 _result);
function issue(
uint256 _projectId,
string calldata _name,
string calldata _symbol
) external;
function print(
address _holder,
uint256 _projectId,
uint256 _amount,
bool _preferUnstakedTickets
) external;
function redeem(
address _holder,
uint256 _projectId,
uint256 _amount,
bool _preferUnstaked
) external;
function stake(
address _holder,
uint256 _projectId,
uint256 _amount
) external;
function unstake(
address _holder,
uint256 _projectId,
uint256 _amount
) external;
function lock(
address _holder,
uint256 _projectId,
uint256 _amount
) external;
function unlock(
address _holder,
uint256 _projectId,
uint256 _amount
) external;
function transfer(
address _holder,
uint256 _projectId,
uint256 _amount,
address _recipient
) external;
}
文件 22 的 32:ITickets.sol
pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface ITickets is IERC20 {
function print(address _account, uint256 _amount) external;
function redeem(address _account, uint256 _amount) external;
}
文件 23 的 32:ITreasuryExtension.sol
pragma solidity 0.8.6;
interface ITreasuryExtension {
function ETHValue(uint256 _projectId) external view returns (uint256);
}
文件 24 的 32:IYielder.sol
pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./ITerminalV1.sol";
interface IYielder {
function deposited() external view returns (uint256);
function getCurrentBalance() external view returns (uint256);
function deposit() external payable;
function withdraw(uint256 _amount, address payable _beneficiary) external;
function withdrawAll(address payable _beneficiary)
external
returns (uint256);
}
文件 25 的 32:JuiceboxProject.sol
pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./../interfaces/ITerminalV1.sol";
abstract contract JuiceboxProject is IERC721Receiver, Ownable {
ITerminalDirectory public immutable terminalDirectory;
uint256 public projectId;
constructor(uint256 _projectId, ITerminalDirectory _terminalDirectory) {
projectId = _projectId;
terminalDirectory = _terminalDirectory;
}
receive() external payable {}
function withdraw(address payable _beneficiary, uint256 _amount)
external
onlyOwner
{
Address.sendValue(_beneficiary, _amount);
}
function setProjectId(uint256 _projectId) external onlyOwner {
projectId = _projectId;
}
function pay(
address _beneficiary,
string calldata _memo,
bool _preferUnstakedTickets
) external payable {
require(projectId != 0, "JuiceboxProject::pay: PROJECT_NOT_FOUND");
ITerminal _terminal = terminalDirectory.terminalOf(projectId);
require(
_terminal != ITerminal(address(0)),
"JuiceboxProject::pay: TERMINAL_NOT_FOUND"
);
_terminal.pay{value: msg.value}(
projectId,
_beneficiary,
_memo,
_preferUnstakedTickets
);
}
function transferProjectOwnership(
IProjects _projects,
address _newOwner,
uint256 _projectId,
bytes calldata _data
) external onlyOwner {
_projects.safeTransferFrom(address(this), _newOwner, _projectId, _data);
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) public pure override returns (bytes4) {
return this.onERC721Received.selector;
}
function setOperator(
IOperatorStore _operatorStore,
address _operator,
uint256 _projectId,
uint256[] calldata _permissionIndexes
) external onlyOwner {
_operatorStore.setOperator(_operator, _projectId, _permissionIndexes);
}
function setOperators(
IOperatorStore _operatorStore,
address[] calldata _operators,
uint256[] calldata _projectIds,
uint256[][] calldata _permissionIndexes
) external onlyOwner {
_operatorStore.setOperators(
_operators,
_projectIds,
_permissionIndexes
);
}
function _takeFee(
uint256 _amount,
address _beneficiary,
string memory _memo,
bool _preferUnstakedTickets
) internal {
require(projectId != 0, "JuiceboxProject::takeFee: PROJECT_NOT_FOUND");
ITerminal _terminal = terminalDirectory.terminalOf(projectId);
require(
_terminal != ITerminal(address(0)),
"JuiceboxProject::takeFee: TERMINAL_NOT_FOUND"
);
require(
address(this).balance >= _amount,
"JuiceboxProject::takeFee: INSUFFICIENT_FUNDS"
);
_terminal.pay{value: _amount}(
projectId,
_beneficiary,
_memo,
_preferUnstakedTickets
);
}
}
文件 26 的 32:Operatable.sol
pragma solidity 0.8.6;
import "./../interfaces/IOperatable.sol";
abstract contract Operatable is IOperatable {
modifier requirePermission(
address _account,
uint256 _domain,
uint256 _index
) {
require(
msg.sender == _account ||
operatorStore.hasPermission(
msg.sender,
_account,
_domain,
_index
),
"Operatable: UNAUTHORIZED"
);
_;
}
modifier requirePermissionAllowingWildcardDomain(
address _account,
uint256 _domain,
uint256 _index
) {
require(
msg.sender == _account ||
operatorStore.hasPermission(
msg.sender,
_account,
_domain,
_index
) ||
operatorStore.hasPermission(msg.sender, _account, 0, _index),
"Operatable: UNAUTHORIZED"
);
_;
}
modifier requirePermissionAcceptingAlternateAddress(
address _account,
uint256 _domain,
uint256 _index,
address _alternate
) {
require(
msg.sender == _account ||
operatorStore.hasPermission(
msg.sender,
_account,
_domain,
_index
) ||
msg.sender == _alternate,
"Operatable: UNAUTHORIZED"
);
_;
}
IOperatorStore public immutable override operatorStore;
constructor(IOperatorStore _operatorStore) {
operatorStore = _operatorStore;
}
}
文件 27 的 32:Operations.sol
pragma solidity 0.8.6;
library Operations {
uint256 public constant Configure = 1;
uint256 public constant PrintPreminedTickets = 2;
uint256 public constant Redeem = 3;
uint256 public constant Migrate = 4;
uint256 public constant SetHandle = 5;
uint256 public constant SetUri = 6;
uint256 public constant ClaimHandle = 7;
uint256 public constant RenewHandle = 8;
uint256 public constant Issue = 9;
uint256 public constant Stake = 10;
uint256 public constant Unstake = 11;
uint256 public constant Transfer = 12;
uint256 public constant Lock = 13;
uint256 public constant SetPayoutMods = 14;
uint256 public constant SetTicketMods = 15;
uint256 public constant SetTerminal = 16;
uint256 public constant PrintTickets = 17;
}
文件 28 的 32:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 29 的 32:PRBMath.sol
pragma solidity >=0.8.4;
error PRBMath__MulDivFixedPointOverflow(uint256 prod1);
error PRBMath__MulDivOverflow(uint256 prod1, uint256 denominator);
error PRBMath__MulDivSignedInputTooSmall();
error PRBMath__MulDivSignedOverflow(uint256 rAbs);
error PRBMathSD59x18__AbsInputTooSmall();
error PRBMathSD59x18__CeilOverflow(int256 x);
error PRBMathSD59x18__DivInputTooSmall();
error PRBMathSD59x18__DivOverflow(uint256 rAbs);
error PRBMathSD59x18__ExpInputTooBig(int256 x);
error PRBMathSD59x18__Exp2InputTooBig(int256 x);
error PRBMathSD59x18__FloorUnderflow(int256 x);
error PRBMathSD59x18__FromIntOverflow(int256 x);
error PRBMathSD59x18__FromIntUnderflow(int256 x);
error PRBMathSD59x18__GmNegativeProduct(int256 x, int256 y);
error PRBMathSD59x18__GmOverflow(int256 x, int256 y);
error PRBMathSD59x18__LogInputTooSmall(int256 x);
error PRBMathSD59x18__MulInputTooSmall();
error PRBMathSD59x18__MulOverflow(uint256 rAbs);
error PRBMathSD59x18__PowuOverflow(uint256 rAbs);
error PRBMathSD59x18__SqrtNegativeInput(int256 x);
error PRBMathSD59x18__SqrtOverflow(int256 x);
error PRBMathUD60x18__AddOverflow(uint256 x, uint256 y);
error PRBMathUD60x18__CeilOverflow(uint256 x);
error PRBMathUD60x18__ExpInputTooBig(uint256 x);
error PRBMathUD60x18__Exp2InputTooBig(uint256 x);
error PRBMathUD60x18__FromUintOverflow(uint256 x);
error PRBMathUD60x18__GmOverflow(uint256 x, uint256 y);
error PRBMathUD60x18__LogInputTooSmall(uint256 x);
error PRBMathUD60x18__SqrtOverflow(uint256 x);
error PRBMathUD60x18__SubUnderflow(uint256 x, uint256 y);
library PRBMath {
struct SD59x18 {
int256 value;
}
struct UD60x18 {
uint256 value;
}
uint256 internal constant SCALE = 1e18;
uint256 internal constant SCALE_LPOTD = 262144;
uint256 internal constant SCALE_INVERSE = 78156646155174841979727994598816262306175212592076161876661508869554232690281;
function exp2(uint256 x) internal pure returns (uint256 result) {
unchecked {
result = 0x800000000000000000000000000000000000000000000000;
if (x & 0x8000000000000000 > 0) {
result = (result * 0x16A09E667F3BCC909) >> 64;
}
if (x & 0x4000000000000000 > 0) {
result = (result * 0x1306FE0A31B7152DF) >> 64;
}
if (x & 0x2000000000000000 > 0) {
result = (result * 0x1172B83C7D517ADCE) >> 64;
}
if (x & 0x1000000000000000 > 0) {
result = (result * 0x10B5586CF9890F62A) >> 64;
}
if (x & 0x800000000000000 > 0) {
result = (result * 0x1059B0D31585743AE) >> 64;
}
if (x & 0x400000000000000 > 0) {
result = (result * 0x102C9A3E778060EE7) >> 64;
}
if (x & 0x200000000000000 > 0) {
result = (result * 0x10163DA9FB33356D8) >> 64;
}
if (x & 0x100000000000000 > 0) {
result = (result * 0x100B1AFA5ABCBED61) >> 64;
}
if (x & 0x80000000000000 > 0) {
result = (result * 0x10058C86DA1C09EA2) >> 64;
}
if (x & 0x40000000000000 > 0) {
result = (result * 0x1002C605E2E8CEC50) >> 64;
}
if (x & 0x20000000000000 > 0) {
result = (result * 0x100162F3904051FA1) >> 64;
}
if (x & 0x10000000000000 > 0) {
result = (result * 0x1000B175EFFDC76BA) >> 64;
}
if (x & 0x8000000000000 > 0) {
result = (result * 0x100058BA01FB9F96D) >> 64;
}
if (x & 0x4000000000000 > 0) {
result = (result * 0x10002C5CC37DA9492) >> 64;
}
if (x & 0x2000000000000 > 0) {
result = (result * 0x1000162E525EE0547) >> 64;
}
if (x & 0x1000000000000 > 0) {
result = (result * 0x10000B17255775C04) >> 64;
}
if (x & 0x800000000000 > 0) {
result = (result * 0x1000058B91B5BC9AE) >> 64;
}
if (x & 0x400000000000 > 0) {
result = (result * 0x100002C5C89D5EC6D) >> 64;
}
if (x & 0x200000000000 > 0) {
result = (result * 0x10000162E43F4F831) >> 64;
}
if (x & 0x100000000000 > 0) {
result = (result * 0x100000B1721BCFC9A) >> 64;
}
if (x & 0x80000000000 > 0) {
result = (result * 0x10000058B90CF1E6E) >> 64;
}
if (x & 0x40000000000 > 0) {
result = (result * 0x1000002C5C863B73F) >> 64;
}
if (x & 0x20000000000 > 0) {
result = (result * 0x100000162E430E5A2) >> 64;
}
if (x & 0x10000000000 > 0) {
result = (result * 0x1000000B172183551) >> 64;
}
if (x & 0x8000000000 > 0) {
result = (result * 0x100000058B90C0B49) >> 64;
}
if (x & 0x4000000000 > 0) {
result = (result * 0x10000002C5C8601CC) >> 64;
}
if (x & 0x2000000000 > 0) {
result = (result * 0x1000000162E42FFF0) >> 64;
}
if (x & 0x1000000000 > 0) {
result = (result * 0x10000000B17217FBB) >> 64;
}
if (x & 0x800000000 > 0) {
result = (result * 0x1000000058B90BFCE) >> 64;
}
if (x & 0x400000000 > 0) {
result = (result * 0x100000002C5C85FE3) >> 64;
}
if (x & 0x200000000 > 0) {
result = (result * 0x10000000162E42FF1) >> 64;
}
if (x & 0x100000000 > 0) {
result = (result * 0x100000000B17217F8) >> 64;
}
if (x & 0x80000000 > 0) {
result = (result * 0x10000000058B90BFC) >> 64;
}
if (x & 0x40000000 > 0) {
result = (result * 0x1000000002C5C85FE) >> 64;
}
if (x & 0x20000000 > 0) {
result = (result * 0x100000000162E42FF) >> 64;
}
if (x & 0x10000000 > 0) {
result = (result * 0x1000000000B17217F) >> 64;
}
if (x & 0x8000000 > 0) {
result = (result * 0x100000000058B90C0) >> 64;
}
if (x & 0x4000000 > 0) {
result = (result * 0x10000000002C5C860) >> 64;
}
if (x & 0x2000000 > 0) {
result = (result * 0x1000000000162E430) >> 64;
}
if (x & 0x1000000 > 0) {
result = (result * 0x10000000000B17218) >> 64;
}
if (x & 0x800000 > 0) {
result = (result * 0x1000000000058B90C) >> 64;
}
if (x & 0x400000 > 0) {
result = (result * 0x100000000002C5C86) >> 64;
}
if (x & 0x200000 > 0) {
result = (result * 0x10000000000162E43) >> 64;
}
if (x & 0x100000 > 0) {
result = (result * 0x100000000000B1721) >> 64;
}
if (x & 0x80000 > 0) {
result = (result * 0x10000000000058B91) >> 64;
}
if (x & 0x40000 > 0) {
result = (result * 0x1000000000002C5C8) >> 64;
}
if (x & 0x20000 > 0) {
result = (result * 0x100000000000162E4) >> 64;
}
if (x & 0x10000 > 0) {
result = (result * 0x1000000000000B172) >> 64;
}
if (x & 0x8000 > 0) {
result = (result * 0x100000000000058B9) >> 64;
}
if (x & 0x4000 > 0) {
result = (result * 0x10000000000002C5D) >> 64;
}
if (x & 0x2000 > 0) {
result = (result * 0x1000000000000162E) >> 64;
}
if (x & 0x1000 > 0) {
result = (result * 0x10000000000000B17) >> 64;
}
if (x & 0x800 > 0) {
result = (result * 0x1000000000000058C) >> 64;
}
if (x & 0x400 > 0) {
result = (result * 0x100000000000002C6) >> 64;
}
if (x & 0x200 > 0) {
result = (result * 0x10000000000000163) >> 64;
}
if (x & 0x100 > 0) {
result = (result * 0x100000000000000B1) >> 64;
}
if (x & 0x80 > 0) {
result = (result * 0x10000000000000059) >> 64;
}
if (x & 0x40 > 0) {
result = (result * 0x1000000000000002C) >> 64;
}
if (x & 0x20 > 0) {
result = (result * 0x10000000000000016) >> 64;
}
if (x & 0x10 > 0) {
result = (result * 0x1000000000000000B) >> 64;
}
if (x & 0x8 > 0) {
result = (result * 0x10000000000000006) >> 64;
}
if (x & 0x4 > 0) {
result = (result * 0x10000000000000003) >> 64;
}
if (x & 0x2 > 0) {
result = (result * 0x10000000000000001) >> 64;
}
if (x & 0x1 > 0) {
result = (result * 0x10000000000000001) >> 64;
}
result *= SCALE;
result >>= (191 - (x >> 64));
}
}
function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) {
if (x >= 2**128) {
x >>= 128;
msb += 128;
}
if (x >= 2**64) {
x >>= 64;
msb += 64;
}
if (x >= 2**32) {
x >>= 32;
msb += 32;
}
if (x >= 2**16) {
x >>= 16;
msb += 16;
}
if (x >= 2**8) {
x >>= 8;
msb += 8;
}
if (x >= 2**4) {
x >>= 4;
msb += 4;
}
if (x >= 2**2) {
x >>= 2;
msb += 2;
}
if (x >= 2**1) {
msb += 1;
}
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
unchecked {
result = prod0 / denominator;
}
return result;
}
if (prod1 >= denominator) {
revert PRBMath__MulDivOverflow(prod1, denominator);
}
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
unchecked {
uint256 lpotdod = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, lpotdod)
prod0 := div(prod0, lpotdod)
lpotdod := add(div(sub(0, lpotdod), lpotdod), 1)
}
prod0 |= prod1 * lpotdod;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 >= SCALE) {
revert PRBMath__MulDivFixedPointOverflow(prod1);
}
uint256 remainder;
uint256 roundUpUnit;
assembly {
remainder := mulmod(x, y, SCALE)
roundUpUnit := gt(remainder, 499999999999999999)
}
if (prod1 == 0) {
unchecked {
result = (prod0 / SCALE) + roundUpUnit;
return result;
}
}
assembly {
result := add(
mul(
or(
div(sub(prod0, remainder), SCALE_LPOTD),
mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1))
),
SCALE_INVERSE
),
roundUpUnit
)
}
}
function mulDivSigned(
int256 x,
int256 y,
int256 denominator
) internal pure returns (int256 result) {
if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {
revert PRBMath__MulDivSignedInputTooSmall();
}
uint256 ax;
uint256 ay;
uint256 ad;
unchecked {
ax = x < 0 ? uint256(-x) : uint256(x);
ay = y < 0 ? uint256(-y) : uint256(y);
ad = denominator < 0 ? uint256(-denominator) : uint256(denominator);
}
uint256 rAbs = mulDiv(ax, ay, ad);
if (rAbs > uint256(type(int256).max)) {
revert PRBMath__MulDivSignedOverflow(rAbs);
}
uint256 sx;
uint256 sy;
uint256 sd;
assembly {
sx := sgt(x, sub(0, 1))
sy := sgt(y, sub(0, 1))
sd := sgt(denominator, sub(0, 1))
}
result = sx ^ sy ^ sd == 0 ? -int256(rAbs) : int256(rAbs);
}
function sqrt(uint256 x) internal pure returns (uint256 result) {
if (x == 0) {
return 0;
}
uint256 xAux = uint256(x);
result = 1;
if (xAux >= 0x100000000000000000000000000000000) {
xAux >>= 128;
result <<= 64;
}
if (xAux >= 0x10000000000000000) {
xAux >>= 64;
result <<= 32;
}
if (xAux >= 0x100000000) {
xAux >>= 32;
result <<= 16;
}
if (xAux >= 0x10000) {
xAux >>= 16;
result <<= 8;
}
if (xAux >= 0x100) {
xAux >>= 8;
result <<= 4;
}
if (xAux >= 0x10) {
xAux >>= 4;
result <<= 2;
}
if (xAux >= 0x8) {
result <<= 1;
}
unchecked {
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
result = (result + x / result) >> 1;
uint256 roundedDownResult = x / result;
return result >= roundedDownResult ? roundedDownResult : result;
}
}
}
文件 30 的 32:PRBMathUD60x18.sol
pragma solidity >=0.8.4;
import "./PRBMath.sol";
library PRBMathUD60x18 {
uint256 internal constant HALF_SCALE = 5e17;
uint256 internal constant LOG2_E = 1442695040888963407;
uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457000000000000000000;
uint256 internal constant SCALE = 1e18;
function avg(uint256 x, uint256 y) internal pure returns (uint256 result) {
unchecked {
result = (x >> 1) + (y >> 1) + (x & y & 1);
}
}
function ceil(uint256 x) internal pure returns (uint256 result) {
if (x > MAX_WHOLE_UD60x18) {
revert PRBMathUD60x18__CeilOverflow(x);
}
assembly {
let remainder := mod(x, SCALE)
let delta := sub(SCALE, remainder)
result := add(x, mul(delta, gt(remainder, 0)))
}
}
function div(uint256 x, uint256 y) internal pure returns (uint256 result) {
result = PRBMath.mulDiv(x, SCALE, y);
}
function e() internal pure returns (uint256 result) {
result = 2718281828459045235;
}
function exp(uint256 x) internal pure returns (uint256 result) {
if (x >= 133084258667509499441) {
revert PRBMathUD60x18__ExpInputTooBig(x);
}
unchecked {
uint256 doubleScaleProduct = x * LOG2_E;
result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);
}
}
function exp2(uint256 x) internal pure returns (uint256 result) {
if (x >= 192e18) {
revert PRBMathUD60x18__Exp2InputTooBig(x);
}
unchecked {
uint256 x192x64 = (x << 64) / SCALE;
result = PRBMath.exp2(x192x64);
}
}
function floor(uint256 x) internal pure returns (uint256 result) {
assembly {
let remainder := mod(x, SCALE)
result := sub(x, mul(remainder, gt(remainder, 0)))
}
}
function frac(uint256 x) internal pure returns (uint256 result) {
assembly {
result := mod(x, SCALE)
}
}
function fromUint(uint256 x) internal pure returns (uint256 result) {
unchecked {
if (x > MAX_UD60x18 / SCALE) {
revert PRBMathUD60x18__FromUintOverflow(x);
}
result = x * SCALE;
}
}
function gm(uint256 x, uint256 y) internal pure returns (uint256 result) {
if (x == 0) {
return 0;
}
unchecked {
uint256 xy = x * y;
if (xy / x != y) {
revert PRBMathUD60x18__GmOverflow(x, y);
}
result = PRBMath.sqrt(xy);
}
}
function inv(uint256 x) internal pure returns (uint256 result) {
unchecked {
result = 1e36 / x;
}
}
function ln(uint256 x) internal pure returns (uint256 result) {
unchecked {
result = (log2(x) * SCALE) / LOG2_E;
}
}
function log10(uint256 x) internal pure returns (uint256 result) {
if (x < SCALE) {
revert PRBMathUD60x18__LogInputTooSmall(x);
}
assembly {
switch x
case 1 { result := mul(SCALE, sub(0, 18)) }
case 10 { result := mul(SCALE, sub(1, 18)) }
case 100 { result := mul(SCALE, sub(2, 18)) }
case 1000 { result := mul(SCALE, sub(3, 18)) }
case 10000 { result := mul(SCALE, sub(4, 18)) }
case 100000 { result := mul(SCALE, sub(5, 18)) }
case 1000000 { result := mul(SCALE, sub(6, 18)) }
case 10000000 { result := mul(SCALE, sub(7, 18)) }
case 100000000 { result := mul(SCALE, sub(8, 18)) }
case 1000000000 { result := mul(SCALE, sub(9, 18)) }
case 10000000000 { result := mul(SCALE, sub(10, 18)) }
case 100000000000 { result := mul(SCALE, sub(11, 18)) }
case 1000000000000 { result := mul(SCALE, sub(12, 18)) }
case 10000000000000 { result := mul(SCALE, sub(13, 18)) }
case 100000000000000 { result := mul(SCALE, sub(14, 18)) }
case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }
case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }
case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }
case 1000000000000000000 { result := 0 }
case 10000000000000000000 { result := SCALE }
case 100000000000000000000 { result := mul(SCALE, 2) }
case 1000000000000000000000 { result := mul(SCALE, 3) }
case 10000000000000000000000 { result := mul(SCALE, 4) }
case 100000000000000000000000 { result := mul(SCALE, 5) }
case 1000000000000000000000000 { result := mul(SCALE, 6) }
case 10000000000000000000000000 { result := mul(SCALE, 7) }
case 100000000000000000000000000 { result := mul(SCALE, 8) }
case 1000000000000000000000000000 { result := mul(SCALE, 9) }
case 10000000000000000000000000000 { result := mul(SCALE, 10) }
case 100000000000000000000000000000 { result := mul(SCALE, 11) }
case 1000000000000000000000000000000 { result := mul(SCALE, 12) }
case 10000000000000000000000000000000 { result := mul(SCALE, 13) }
case 100000000000000000000000000000000 { result := mul(SCALE, 14) }
case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }
case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }
case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }
case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }
case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }
case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }
case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }
case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }
case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }
case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }
case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }
case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }
case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }
case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }
case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }
case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }
case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }
case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }
case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }
case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }
case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }
case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }
case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }
case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }
case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }
case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }
case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }
case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }
case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }
case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }
case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }
case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }
case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }
case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }
case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }
case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }
case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }
case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }
case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }
case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }
case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }
case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }
case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }
case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }
case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) }
default {
result := MAX_UD60x18
}
}
if (result == MAX_UD60x18) {
unchecked {
result = (log2(x) * SCALE) / 3321928094887362347;
}
}
}
function log2(uint256 x) internal pure returns (uint256 result) {
if (x < SCALE) {
revert PRBMathUD60x18__LogInputTooSmall(x);
}
unchecked {
uint256 n = PRBMath.mostSignificantBit(x / SCALE);
result = n * SCALE;
uint256 y = x >> n;
if (y == SCALE) {
return result;
}
for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) {
y = (y * y) / SCALE;
if (y >= 2 * SCALE) {
result += delta;
y >>= 1;
}
}
}
}
function mul(uint256 x, uint256 y) internal pure returns (uint256 result) {
result = PRBMath.mulDivFixedPoint(x, y);
}
function pi() internal pure returns (uint256 result) {
result = 3141592653589793238;
}
function pow(uint256 x, uint256 y) internal pure returns (uint256 result) {
if (x == 0) {
result = y == 0 ? SCALE : uint256(0);
} else {
result = exp2(mul(log2(x), y));
}
}
function powu(uint256 x, uint256 y) internal pure returns (uint256 result) {
result = y & 1 > 0 ? x : SCALE;
for (y >>= 1; y > 0; y >>= 1) {
x = PRBMath.mulDivFixedPoint(x, x);
if (y & 1 > 0) {
result = PRBMath.mulDivFixedPoint(result, x);
}
}
}
function scale() internal pure returns (uint256 result) {
result = SCALE;
}
function sqrt(uint256 x) internal pure returns (uint256 result) {
unchecked {
if (x > MAX_UD60x18 / SCALE) {
revert PRBMathUD60x18__SqrtOverflow(x);
}
result = PRBMath.sqrt(x * SCALE);
}
}
function toUint(uint256 x) internal pure returns (uint256 result) {
unchecked {
result = x / SCALE;
}
}
}
文件 31 的 32:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 32 的 32:TerminalV1_1.sol
pragma solidity 0.8.6;
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@openzeppelin/contracts/utils/Address.sol';
import '@paulrberg/contracts/math/PRBMath.sol';
import '@paulrberg/contracts/math/PRBMathUD60x18.sol';
import './interfaces/ITerminalV1_1.sol';
import './abstract/JuiceboxProject.sol';
import './abstract/Operatable.sol';
import './libraries/Operations.sol';
contract TerminalV1_1 is Operatable, ITerminalV1_1, ITerminal, ReentrancyGuard, Ownable {
mapping(uint256 => int256) private _processedTicketTrackerOf;
address private constant _deadAddress = address(0x000000000000000000000000000000000000dEaD);
IProjects public immutable override projects;
IFundingCycles public immutable override fundingCycles;
ITicketBooth public immutable override ticketBooth;
IModStore public immutable override modStore;
IPrices public immutable override prices;
ITerminalDirectory public immutable override terminalDirectory;
mapping(uint256 => uint256) public override balanceOf;
uint256 public override fee = 10;
mapping(ITerminal => bool) public override migrationIsAllowed;
function currentOverflowOf(uint256 _projectId) external view override returns (uint256 overflow) {
FundingCycle memory _fundingCycle = fundingCycles.currentOf(_projectId);
return _overflowFrom(_fundingCycle);
}
function reservedTicketBalanceOf(uint256 _projectId, uint256 _reservedRate)
external
view
override
returns (uint256)
{
return
_reservedTicketAmountFrom(
_processedTicketTrackerOf[_projectId],
_reservedRate,
ticketBooth.totalSupplyOf(_projectId)
);
}
function claimableOverflowOf(
address _account,
uint256 _projectId,
uint256 _count
) public view override returns (uint256 _claimableOverflow) {
require(
ticketBooth.balanceOf(_account, _projectId) >= _count,
'TV1_1::claimableOverflow: INSUFFICIENT_TICKETS'
);
FundingCycle memory _fundingCycle = fundingCycles.currentOf(_projectId);
if (_fundingCycle.number == 0) return 0;
uint256 _overflow = _overflowFrom(_fundingCycle);
_claimableOverflow = _overflow;
if (uint160(_fundingCycle.metadata >> 34) > 0)
_claimableOverflow =
_claimableOverflow +
ITreasuryExtension(address(uint160(_fundingCycle.metadata >> 34))).ETHValue(_projectId);
if (_claimableOverflow == 0)
return 0;
uint256 _totalSupply = ticketBooth.totalSupplyOf(_projectId);
uint256 _reservedTicketAmount = _reservedTicketAmountFrom(
_processedTicketTrackerOf[_projectId],
uint256(uint8(_fundingCycle.metadata >> 8)),
_totalSupply
);
if (_reservedTicketAmount > 0) _totalSupply = _totalSupply + _reservedTicketAmount;
if (_count == _totalSupply)
return _claimableOverflow > _overflow ? _overflow : _claimableOverflow;
uint256 _base = PRBMath.mulDiv(_claimableOverflow, _count, _totalSupply);
uint256 _bondingCurveRate = fundingCycles.currentBallotStateOf(_projectId) == BallotState.Active
? uint256(uint8(_fundingCycle.metadata >> 24))
: uint256(uint8(_fundingCycle.metadata >> 16));
if (_bondingCurveRate == 200) {
_claimableOverflow = _base;
} else if (_bondingCurveRate == 0) {
_claimableOverflow = PRBMath.mulDiv(_base, _count, _totalSupply);
} else {
_claimableOverflow = PRBMath.mulDiv(
_base,
_bondingCurveRate + PRBMath.mulDiv(_count, 200 - _bondingCurveRate, _totalSupply),
200
);
}
if (_claimableOverflow > _overflow) return _overflow;
}
constructor(
IProjects _projects,
IFundingCycles _fundingCycles,
ITicketBooth _ticketBooth,
IOperatorStore _operatorStore,
IModStore _modStore,
IPrices _prices,
ITerminalDirectory _terminalDirectory,
address _owner
) Operatable(_operatorStore) {
require(
_projects != IProjects(address(0)) &&
_fundingCycles != IFundingCycles(address(0)) &&
_ticketBooth != ITicketBooth(address(0)) &&
_modStore != IModStore(address(0)) &&
_prices != IPrices(address(0)) &&
_terminalDirectory != ITerminalDirectory(address(0)) &&
_owner != address(0),
'TerminalV1: ZERO_ADDRESS'
);
projects = _projects;
fundingCycles = _fundingCycles;
ticketBooth = _ticketBooth;
modStore = _modStore;
prices = _prices;
terminalDirectory = _terminalDirectory;
transferOwnership(_owner);
}
function deploy(
address _owner,
bytes32 _handle,
string calldata _uri,
FundingCycleProperties calldata _properties,
FundingCycleMetadata2 calldata _metadata,
PayoutMod[] memory _payoutMods,
TicketMod[] memory _ticketMods
) external override {
uint256 _packedMetadata = _validateAndPackFundingCycleMetadata(_metadata);
uint256 _projectId = projects.create(_owner, _handle, _uri, this);
FundingCycle memory _fundingCycle = fundingCycles.configure(
_projectId,
_properties,
_packedMetadata,
fee,
true
);
if (_payoutMods.length > 0)
modStore.setPayoutMods(_projectId, _fundingCycle.configured, _payoutMods);
if (_ticketMods.length > 0)
modStore.setTicketMods(_projectId, _fundingCycle.configured, _ticketMods);
}
function configure(
uint256 _projectId,
FundingCycleProperties calldata _properties,
FundingCycleMetadata2 calldata _metadata,
PayoutMod[] memory _payoutMods,
TicketMod[] memory _ticketMods
)
external
override
requirePermission(projects.ownerOf(_projectId), _projectId, Operations.Configure)
returns (uint256)
{
uint256 _packedMetadata = _validateAndPackFundingCycleMetadata(_metadata);
FundingCycle memory _fundingCycle = fundingCycles.configure(
_projectId,
_properties,
_packedMetadata,
fee,
false
);
if (_payoutMods.length > 0)
modStore.setPayoutMods(_projectId, _fundingCycle.configured, _payoutMods);
if (_ticketMods.length > 0)
modStore.setTicketMods(_projectId, _fundingCycle.configured, _ticketMods);
return _fundingCycle.id;
}
function printTickets(
uint256 _projectId,
uint256 _amount,
address _beneficiary,
string memory _memo,
bool _preferUnstakedTickets
)
external
override
requirePermission(projects.ownerOf(_projectId), _projectId, Operations.PrintTickets)
{
require(_beneficiary != address(0), 'TV1_1::printTickets: ZERO_ADDRESS');
FundingCycle memory _fundingCycle = fundingCycles.currentOf(_projectId);
require(
_fundingCycle.number == 0 || ((_fundingCycle.metadata >> 33) & 1) == 1,
'TV1_1::printTickets: NOT_ALLOWED'
);
require(
_processedTicketTrackerOf[_projectId] < 0 ||
uint256(_processedTicketTrackerOf[_projectId]) + _amount <= uint256(type(int256).max),
'TV1_1::printTickets: INT_LIMIT_REACHED'
);
_processedTicketTrackerOf[_projectId] = _processedTicketTrackerOf[_projectId] + int256(_amount);
ticketBooth.print(_beneficiary, _projectId, _amount, _preferUnstakedTickets);
emit PrintTickets(_projectId, _beneficiary, _amount, _memo, msg.sender);
}
function burnFromDeadAddress(uint256 _projectId) external override {
uint256 _deadBalance = ticketBooth.balanceOf(_deadAddress, _projectId);
require(_deadBalance > 0, '0x00 NOTHING_TO_BURN');
ticketBooth.redeem(_deadAddress, _projectId, _deadBalance, true);
}
function pay(
uint256 _projectId,
address _beneficiary,
string calldata _memo,
bool _preferUnstakedTickets
) external payable override returns (uint256) {
require(msg.value > 0, 'TV1_1::pay: BAD_AMOUNT');
require(_beneficiary != address(0), 'TV1_1::pay: ZERO_ADDRESS');
return _pay(_projectId, msg.value, _beneficiary, _memo, _preferUnstakedTickets);
}
function tap(
uint256 _projectId,
uint256 _amount,
uint256 _currency,
uint256 _minReturnedWei
) external override nonReentrant returns (uint256) {
FundingCycle memory _fundingCycle = fundingCycles.tap(_projectId, _amount);
if (_fundingCycle.id == 0) return 0;
require(_currency == _fundingCycle.currency, 'TV1_1::tap: UNEXPECTED_CURRENCY');
uint256 _ethPrice = prices.getETHPriceFor(_fundingCycle.currency);
uint256 _tappedWeiAmount = PRBMathUD60x18.div(_amount, _ethPrice);
require(_minReturnedWei <= _tappedWeiAmount, 'TV1_1::tap: INADEQUATE');
uint256 _balance = balanceOf[_fundingCycle.projectId];
require(_tappedWeiAmount <= _balance, 'TV1_1::tap: INSUFFICIENT_FUNDS');
balanceOf[_projectId] = _balance - _tappedWeiAmount;
address payable _projectOwner = payable(projects.ownerOf(_fundingCycle.projectId));
bytes32 _handle = projects.handleOf(_projectId);
uint256 _feeAmount = _fundingCycle.fee > 0
? _takeFee(
_tappedWeiAmount,
_fundingCycle.fee,
_projectOwner,
string(bytes.concat('Fee from @', _handle))
)
: 0;
uint256 _leftoverTransferAmount = _distributeToPayoutMods(
_fundingCycle,
_tappedWeiAmount - _feeAmount,
string(bytes.concat('Payout from @', _handle))
);
if (_leftoverTransferAmount > 0) Address.sendValue(_projectOwner, _leftoverTransferAmount);
emit Tap(
_fundingCycle.id,
_fundingCycle.projectId,
_projectOwner,
_amount,
_fundingCycle.currency,
_tappedWeiAmount - _feeAmount,
_leftoverTransferAmount,
_feeAmount,
msg.sender
);
return _fundingCycle.id;
}
function redeem(
address _account,
uint256 _projectId,
uint256 _count,
uint256 _minReturnedWei,
address payable _beneficiary,
bool _preferUnstaked
)
external
override
nonReentrant
requirePermissionAllowingWildcardDomain(_account, _projectId, Operations.Redeem)
returns (uint256 amount)
{
require(_count > 0, 'TV1_1::redeem: NO_OP');
require(_beneficiary != address(0), 'TV1_1::redeem: ZERO_ADDRESS');
amount = claimableOverflowOf(_account, _projectId, _count);
require(amount >= _minReturnedWei, 'TV1_1::redeem: INADEQUATE');
if (amount > 0)
balanceOf[_projectId] = balanceOf[_projectId] - amount;
int256 _processedTicketTracker = _processedTicketTrackerOf[_projectId];
_processedTicketTrackerOf[_projectId] = _processedTicketTracker < 0
? -int256(uint256(-_processedTicketTracker) + _count)
: _processedTicketTracker < int256(_count)
? -(int256(_count) - _processedTicketTracker)
: _processedTicketTracker - int256(_count);
ticketBooth.redeem(_account, _projectId, _count, _preferUnstaked);
if (amount > 0)
Address.sendValue(_beneficiary, amount);
emit Redeem(_account, _beneficiary, _projectId, _count, amount, msg.sender);
}
function migrate(uint256 _projectId, ITerminal _to)
external
override
requirePermission(projects.ownerOf(_projectId), _projectId, Operations.Migrate)
nonReentrant
{
require(terminalDirectory.terminalOf(_projectId) == this, 'TV1_1::migrate: UNAUTHORIZED');
require(migrationIsAllowed[_to], 'TV1_1::migrate: NOT_ALLOWED');
if (uint256(_processedTicketTrackerOf[_projectId]) != ticketBooth.totalSupplyOf(_projectId))
printReservedTickets(_projectId);
uint256 _balanceOf = balanceOf[_projectId];
balanceOf[_projectId] = 0;
if (_balanceOf > 0) _to.addToBalance{value: _balanceOf}(_projectId);
terminalDirectory.setTerminal(_projectId, _to);
emit Migrate(_projectId, _to, _balanceOf, msg.sender);
}
function addToBalance(uint256 _projectId) external payable override {
require(msg.value > 0, 'TV1_1::addToBalance: BAD_AMOUNT');
if (terminalDirectory.terminalOf(_projectId) != this)
_processedTicketTrackerOf[_projectId] = int256(ticketBooth.totalSupplyOf(_projectId));
balanceOf[_projectId] = balanceOf[_projectId] + msg.value;
emit AddToBalance(_projectId, msg.value, msg.sender);
}
function allowMigration(ITerminal _contract) external override onlyOwner {
require(_contract != ITerminal(address(0)), 'TV1_1::allowMigration: ZERO_ADDRESS');
require(_contract != this, 'TV1_1::allowMigration: NO_OP');
migrationIsAllowed[_contract] = true;
emit AllowMigration(_contract);
}
function setFee(uint256 _fee) external override onlyOwner {
require(_fee <= 10, 'TV1_1::setFee: BAD_FEE');
fee = _fee;
emit SetFee(_fee);
}
function printReservedTickets(uint256 _projectId) public override returns (uint256 amount) {
FundingCycle memory _fundingCycle = fundingCycles.currentOf(_projectId);
if (_fundingCycle.id == 0) return 0;
uint256 _totalTickets = ticketBooth.totalSupplyOf(_projectId);
amount = _reservedTicketAmountFrom(
_processedTicketTrackerOf[_projectId],
uint256(uint8(_fundingCycle.metadata >> 8)),
_totalTickets
);
require(
_totalTickets + amount <= uint256(type(int256).max),
'TV1_1::printReservedTickets: INT_LIMIT_REACHED'
);
_processedTicketTrackerOf[_projectId] = int256(_totalTickets + amount);
uint256 _leftoverTicketAmount = amount == 0
? 0
: _distributeToTicketMods(_fundingCycle, amount);
address _owner = projects.ownerOf(_projectId);
if (_leftoverTicketAmount > 0)
ticketBooth.print(_owner, _projectId, _leftoverTicketAmount, false);
emit PrintReserveTickets(
_fundingCycle.id,
_projectId,
_owner,
amount,
_leftoverTicketAmount,
msg.sender
);
}
function _distributeToPayoutMods(
FundingCycle memory _fundingCycle,
uint256 _amount,
string memory _memo
) private returns (uint256 leftoverAmount) {
leftoverAmount = _amount;
PayoutMod[] memory _mods = modStore.payoutModsOf(
_fundingCycle.projectId,
_fundingCycle.configured
);
if (_mods.length == 0) return leftoverAmount;
for (uint256 _i = 0; _i < _mods.length; _i++) {
PayoutMod memory _mod = _mods[_i];
uint256 _modCut = PRBMath.mulDiv(_amount, _mod.percent, 10000);
if (_modCut > 0) {
if (_mod.allocator != IModAllocator(address(0))) {
_mod.allocator.allocate{value: _modCut}(
_fundingCycle.projectId,
_mod.projectId,
_mod.beneficiary
);
} else if (_mod.projectId != 0) {
ITerminal _terminal = terminalDirectory.terminalOf(_mod.projectId);
require(_terminal != ITerminal(address(0)), 'TV1_1::tap: BAD_MOD');
if (_terminal == this) {
_pay(_mod.projectId, _modCut, _mod.beneficiary, _memo, _mod.preferUnstaked);
} else {
_terminal.pay{value: _modCut}(
_mod.projectId,
_mod.beneficiary,
_memo,
_mod.preferUnstaked
);
}
} else {
Address.sendValue(_mod.beneficiary, _modCut);
}
}
leftoverAmount = leftoverAmount - _modCut;
emit DistributeToPayoutMod(
_fundingCycle.id,
_fundingCycle.projectId,
_mod,
_modCut,
msg.sender
);
}
}
function _distributeToTicketMods(FundingCycle memory _fundingCycle, uint256 _amount)
private
returns (uint256 leftoverAmount)
{
leftoverAmount = _amount;
TicketMod[] memory _mods = modStore.ticketModsOf(
_fundingCycle.projectId,
_fundingCycle.configured
);
for (uint256 _i = 0; _i < _mods.length; _i++) {
TicketMod memory _mod = _mods[_i];
uint256 _modCut = PRBMath.mulDiv(_amount, _mod.percent, 10000);
if (_modCut > 0)
ticketBooth.print(_mod.beneficiary, _fundingCycle.projectId, _modCut, _mod.preferUnstaked);
leftoverAmount = leftoverAmount - _modCut;
emit DistributeToTicketMod(
_fundingCycle.id,
_fundingCycle.projectId,
_mod,
_modCut,
msg.sender
);
}
}
function _pay(
uint256 _projectId,
uint256 _amount,
address _beneficiary,
string memory _memo,
bool _preferUnstakedTickets
) private returns (uint256) {
FundingCycle memory _fundingCycle = fundingCycles.currentOf(_projectId);
require(((_fundingCycle.metadata >> 32) & 1) == 0, 'TV1_1::pay: PAUSED');
uint256 _weight = _fundingCycle.number == 0
? fundingCycles.BASE_WEIGHT()
: _fundingCycle.weight;
uint256 _weightedAmount = PRBMathUD60x18.mul(_amount, _weight);
uint256 _reservedRate = _fundingCycle.number == 0
? 0
: uint256(uint8(_fundingCycle.metadata >> 8));
uint256 _unreservedWeightedAmount = PRBMath.mulDiv(_weightedAmount, 200 - _reservedRate, 200);
balanceOf[_projectId] = balanceOf[_projectId] + _amount;
if (_unreservedWeightedAmount > 0) {
if (_fundingCycle.number == 0) {
require(
_processedTicketTrackerOf[_projectId] < 0 ||
uint256(_processedTicketTrackerOf[_projectId]) + uint256(_weightedAmount) <=
uint256(type(int256).max),
'TV1_1::pay INT_LIMIT_REACHED'
);
_processedTicketTrackerOf[_projectId] =
_processedTicketTrackerOf[_projectId] +
int256(_unreservedWeightedAmount);
}
ticketBooth.print(
_beneficiary,
_projectId,
_unreservedWeightedAmount,
_preferUnstakedTickets
);
} else if (_weightedAmount > 0) {
require(
_processedTicketTrackerOf[_projectId] > 0 ||
uint256(-_processedTicketTrackerOf[_projectId]) + uint256(_weightedAmount) <=
uint256(type(int256).max),
'TV1_1::printTickets: INT_LIMIT_REACHED'
);
_processedTicketTrackerOf[_projectId] =
_processedTicketTrackerOf[_projectId] -
int256(_weightedAmount);
}
emit Pay(
_fundingCycle.id,
_projectId,
_beneficiary,
_amount,
_unreservedWeightedAmount,
_weightedAmount,
_memo,
msg.sender
);
return _fundingCycle.id;
}
function _overflowFrom(FundingCycle memory _currentFundingCycle) private view returns (uint256) {
uint256 _ethPrice = prices.getETHPriceFor(_currentFundingCycle.currency);
uint256 _limit = _currentFundingCycle.target - _currentFundingCycle.tapped;
uint256 _ethLimit = _limit == 0 ? 0 : PRBMathUD60x18.div(_limit, _ethPrice);
uint256 _balanceOf = balanceOf[_currentFundingCycle.projectId];
return _balanceOf < _ethLimit ? 0 : _balanceOf - _ethLimit;
}
function _reservedTicketAmountFrom(
int256 _processedTicketTracker,
uint256 _reservedRate,
uint256 _totalEligibleTickets
) private pure returns (uint256) {
uint256 _unprocessedTicketBalanceOf = _processedTicketTracker >= 0
? _totalEligibleTickets - uint256(_processedTicketTracker)
: _totalEligibleTickets + uint256(-_processedTicketTracker);
if (_unprocessedTicketBalanceOf == 0) return 0;
if (_reservedRate == 200) return _unprocessedTicketBalanceOf;
return
PRBMath.mulDiv(_unprocessedTicketBalanceOf, 200, 200 - _reservedRate) -
_unprocessedTicketBalanceOf;
}
function _validateAndPackFundingCycleMetadata(FundingCycleMetadata2 memory _metadata)
private
pure
returns (uint256 packed)
{
require(
_metadata.reservedRate <= 200,
'TV1_1::_validateAndPackFundingCycleMetadata: BAD_RESERVED_RATE'
);
require(
_metadata.bondingCurveRate <= 200,
'TV1_1::_validateAndPackFundingCycleMetadata: BAD_BONDING_CURVE_RATE'
);
require(
_metadata.reconfigurationBondingCurveRate <= 200,
'TV1_1::_validateAndPackFundingCycleMetadata: BAD_RECONFIGURATION_BONDING_CURVE_RATE'
);
packed = 1;
packed |= _metadata.reservedRate << 8;
packed |= _metadata.bondingCurveRate << 16;
packed |= _metadata.reconfigurationBondingCurveRate << 24;
if (_metadata.payIsPaused) packed |= 1 << 32;
if (_metadata.ticketPrintingIsAllowed) packed |= 1 << 33;
packed |= uint256(uint160(address(_metadata.treasuryExtension))) << 34;
}
function _takeFee(
uint256 _from,
uint256 _percent,
address _beneficiary,
string memory _memo
) private returns (uint256 feeAmount) {
feeAmount = _from - PRBMath.mulDiv(_from, 200, _percent + 200);
if (feeAmount == 0) return 0;
if (terminalDirectory.terminalOf(1) == this) {
_pay(1, feeAmount, _beneficiary, _memo, false);
} else {
ITerminal _terminal = terminalDirectory.terminalOf(1);
require(_terminal != ITerminal(address(0)), 'TV1_1::_takeFee: TERMINAL_NOT_FOUND');
_terminal.pay{value: feeAmount}(1, _beneficiary, _memo, false);
}
}
}
{
"compilationTarget": {
"contracts/TerminalV1_1.sol": "TerminalV1_1"
},
"evmVersion": "berlin",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 10000
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IProjects","name":"_projects","type":"address"},{"internalType":"contract IFundingCycles","name":"_fundingCycles","type":"address"},{"internalType":"contract ITicketBooth","name":"_ticketBooth","type":"address"},{"internalType":"contract IOperatorStore","name":"_operatorStore","type":"address"},{"internalType":"contract IModStore","name":"_modStore","type":"address"},{"internalType":"contract IPrices","name":"_prices","type":"address"},{"internalType":"contract ITerminalDirectory","name":"_terminalDirectory","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"prod1","type":"uint256"}],"name":"PRBMath__MulDivFixedPointOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"prod1","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"PRBMath__MulDivOverflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"AddToBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract ITerminal","name":"allowed","type":"address"}],"name":"AllowMigration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fundingCycleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"Configure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fundingCycleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"components":[{"internalType":"bool","name":"preferUnstaked","type":"bool"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"uint48","name":"lockedUntil","type":"uint48"},{"internalType":"address payable","name":"beneficiary","type":"address"},{"internalType":"contract IModAllocator","name":"allocator","type":"address"},{"internalType":"uint56","name":"projectId","type":"uint56"}],"indexed":false,"internalType":"struct PayoutMod","name":"mod","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"modCut","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"DistributeToPayoutMod","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fundingCycleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"components":[{"internalType":"bool","name":"preferUnstaked","type":"bool"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"uint48","name":"lockedUntil","type":"uint48"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"indexed":false,"internalType":"struct TicketMod","name":"mod","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"modCut","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"DistributeToTicketMod","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"target","type":"uint256"}],"name":"EnsureTargetLocalWei","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":true,"internalType":"contract ITerminal","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"Migrate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fundingCycleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"beneficiaryTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalTokens","type":"uint256"},{"indexed":false,"internalType":"string","name":"note","type":"string"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"Pay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fundingCycleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"beneficiaryTicketAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"PrintReserveTickets","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"memo","type":"string"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"PrintTickets","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"returnAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"SetFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SetTargetLocalWei","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IYielder","name":"newYielder","type":"address"}],"name":"SetYielder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fundingCycleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currency","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"netTransferAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"beneficiaryTransferAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"govFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"Tap","type":"event"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"addToBalance","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract ITerminal","name":"_contract","type":"address"}],"name":"allowMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"burnFromDeadAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"claimableOverflowOf","outputs":[{"internalType":"uint256","name":"_claimableOverflow","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"components":[{"internalType":"uint256","name":"target","type":"uint256"},{"internalType":"uint256","name":"currency","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"cycleLimit","type":"uint256"},{"internalType":"uint256","name":"discountRate","type":"uint256"},{"internalType":"contract IFundingCycleBallot","name":"ballot","type":"address"}],"internalType":"struct FundingCycleProperties","name":"_properties","type":"tuple"},{"components":[{"internalType":"uint256","name":"reservedRate","type":"uint256"},{"internalType":"uint256","name":"bondingCurveRate","type":"uint256"},{"internalType":"uint256","name":"reconfigurationBondingCurveRate","type":"uint256"},{"internalType":"bool","name":"payIsPaused","type":"bool"},{"internalType":"bool","name":"ticketPrintingIsAllowed","type":"bool"},{"internalType":"contract ITreasuryExtension","name":"treasuryExtension","type":"address"}],"internalType":"struct FundingCycleMetadata2","name":"_metadata","type":"tuple"},{"components":[{"internalType":"bool","name":"preferUnstaked","type":"bool"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"uint48","name":"lockedUntil","type":"uint48"},{"internalType":"address payable","name":"beneficiary","type":"address"},{"internalType":"contract IModAllocator","name":"allocator","type":"address"},{"internalType":"uint56","name":"projectId","type":"uint56"}],"internalType":"struct PayoutMod[]","name":"_payoutMods","type":"tuple[]"},{"components":[{"internalType":"bool","name":"preferUnstaked","type":"bool"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"uint48","name":"lockedUntil","type":"uint48"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"internalType":"struct TicketMod[]","name":"_ticketMods","type":"tuple[]"}],"name":"configure","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"currentOverflowOf","outputs":[{"internalType":"uint256","name":"overflow","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"bytes32","name":"_handle","type":"bytes32"},{"internalType":"string","name":"_uri","type":"string"},{"components":[{"internalType":"uint256","name":"target","type":"uint256"},{"internalType":"uint256","name":"currency","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"cycleLimit","type":"uint256"},{"internalType":"uint256","name":"discountRate","type":"uint256"},{"internalType":"contract IFundingCycleBallot","name":"ballot","type":"address"}],"internalType":"struct FundingCycleProperties","name":"_properties","type":"tuple"},{"components":[{"internalType":"uint256","name":"reservedRate","type":"uint256"},{"internalType":"uint256","name":"bondingCurveRate","type":"uint256"},{"internalType":"uint256","name":"reconfigurationBondingCurveRate","type":"uint256"},{"internalType":"bool","name":"payIsPaused","type":"bool"},{"internalType":"bool","name":"ticketPrintingIsAllowed","type":"bool"},{"internalType":"contract ITreasuryExtension","name":"treasuryExtension","type":"address"}],"internalType":"struct FundingCycleMetadata2","name":"_metadata","type":"tuple"},{"components":[{"internalType":"bool","name":"preferUnstaked","type":"bool"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"uint48","name":"lockedUntil","type":"uint48"},{"internalType":"address payable","name":"beneficiary","type":"address"},{"internalType":"contract IModAllocator","name":"allocator","type":"address"},{"internalType":"uint56","name":"projectId","type":"uint56"}],"internalType":"struct PayoutMod[]","name":"_payoutMods","type":"tuple[]"},{"components":[{"internalType":"bool","name":"preferUnstaked","type":"bool"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"uint48","name":"lockedUntil","type":"uint48"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"internalType":"struct TicketMod[]","name":"_ticketMods","type":"tuple[]"}],"name":"deploy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fundingCycles","outputs":[{"internalType":"contract IFundingCycles","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"contract ITerminal","name":"_to","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITerminal","name":"","type":"address"}],"name":"migrationIsAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"modStore","outputs":[{"internalType":"contract IModStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorStore","outputs":[{"internalType":"contract IOperatorStore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"string","name":"_memo","type":"string"},{"internalType":"bool","name":"_preferUnstakedTickets","type":"bool"}],"name":"pay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"prices","outputs":[{"internalType":"contract IPrices","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"printReservedTickets","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"string","name":"_memo","type":"string"},{"internalType":"bool","name":"_preferUnstakedTickets","type":"bool"}],"name":"printTickets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"projects","outputs":[{"internalType":"contract IProjects","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_count","type":"uint256"},{"internalType":"uint256","name":"_minReturnedWei","type":"uint256"},{"internalType":"address payable","name":"_beneficiary","type":"address"},{"internalType":"bool","name":"_preferUnstaked","type":"bool"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_reservedRate","type":"uint256"}],"name":"reservedTicketBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_currency","type":"uint256"},{"internalType":"uint256","name":"_minReturnedWei","type":"uint256"}],"name":"tap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"terminalDirectory","outputs":[{"internalType":"contract ITerminalDirectory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ticketBooth","outputs":[{"internalType":"contract ITicketBooth","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]