Overview
ETH Balance
0 ETH
Eth Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60c06040 | 23334198 | 185 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
JBDirectory
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {JBPermissionIds} from "@bananapus/permission-ids-v5/src/JBPermissionIds.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {JBPermissioned} from "./abstract/JBPermissioned.sol";
import {IJBDirectory} from "./interfaces/IJBDirectory.sol";
import {IJBDirectoryAccessControl} from "./interfaces/IJBDirectoryAccessControl.sol";
import {IJBMigratable} from "./interfaces/IJBMigratable.sol";
import {IJBPermissions} from "./interfaces/IJBPermissions.sol";
import {IJBProjects} from "./interfaces/IJBProjects.sol";
import {IJBTerminal} from "./interfaces/IJBTerminal.sol";
/// @notice `JBDirectory` tracks the terminals and the controller used by each project.
/// @dev Tracks which `IJBTerminal`s each project is currently accepting funds through, and which `IJBController` is
/// managing each project's tokens and rulesets.
contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
//*********************************************************************//
// --------------------------- custom errors ------------------------- //
//*********************************************************************//
error JBDirectory_DuplicateTerminals(IJBTerminal terminal);
error JBDirectory_InvalidProjectIdInDirectory(uint256 projectId, uint256 limit);
error JBDirectory_SetControllerNotAllowed();
error JBDirectory_SetTerminalsNotAllowed();
error JBDirectory_TokenNotAccepted(uint256 projectId, address token, IJBTerminal terminal);
//*********************************************************************//
// ---------------- public immutable stored properties --------------- //
//*********************************************************************//
/// @notice Mints ERC-721s that represent project ownership and transfers.
IJBProjects public immutable override PROJECTS;
//*********************************************************************//
// --------------------- public stored properties -------------------- //
//*********************************************************************//
/// @notice The specified project's controller, which dictates how its terminals interact with its tokens and
/// rulesets.
/// @custom:param projectId The ID of the project to get the controller of.
mapping(uint256 projectId => IERC165) public override controllerOf;
/// @notice Whether the specified address is allowed to set a project's first controller on their behalf.
/// @dev These addresses/contracts have been vetted by this contract's owner.
/// @custom:param addr The address to check.
mapping(address addr => bool) public override isAllowedToSetFirstController;
//*********************************************************************//
// --------------------- internal stored properties ------------------ //
//*********************************************************************//
/// @notice The primary terminal that a project uses for the specified token.
/// @custom:param projectId The ID of the project to get the primary terminal of.
/// @custom:param token The token that the terminal accepts.
mapping(uint256 projectId => mapping(address token => IJBTerminal)) internal _primaryTerminalOf;
/// @notice The specified project's terminals.
/// @custom:param projectId The ID of the project to get the terminals of.
mapping(uint256 projectId => IJBTerminal[]) internal _terminalsOf;
//*********************************************************************//
// -------------------------- constructor ---------------------------- //
//*********************************************************************//
/// @param permissions A contract storing permissions.
/// @param projects A contract which mints ERC-721s that represent project ownership and transfers.
/// @param owner The address that will own the contract.
constructor(
IJBPermissions permissions,
IJBProjects projects,
address owner
)
JBPermissioned(permissions)
Ownable(owner)
{
PROJECTS = projects;
}
//*********************************************************************//
// ------------------------- external views -------------------------- //
//*********************************************************************//
/// @notice The primary terminal that a project uses for the specified token.
/// @dev Returns the first terminal that accepts the token if the project hasn't explicitly set a primary terminal
/// for it.
/// @dev Returns the zero address if no terminal accepts the token.
/// @param projectId The ID of the project to get the primary terminal of.
/// @param token The token that the terminal accepts.
/// @return The primary terminal's address.
function primaryTerminalOf(uint256 projectId, address token) external view override returns (IJBTerminal) {
// Keep a reference to the primary terminal for the provided project ID and token.
IJBTerminal primaryTerminal = _primaryTerminalOf[projectId][token];
// If a primary terminal for the token was explicitly set and it's one of the project's terminals, return it.
if (primaryTerminal != IJBTerminal(address(0)) && isTerminalOf(projectId, primaryTerminal)) {
return primaryTerminal;
}
// Keep a reference to the project's terminals.
IJBTerminal[] memory terminals = _terminalsOf[projectId];
// Keep a reference to the number of terminals the project has.
uint256 numberOfTerminals = terminals.length;
// Return the first terminal which accepts the specified token.
for (uint256 i; i < numberOfTerminals; i++) {
// Keep a reference to the terminal being iterated on.
IJBTerminal terminal = terminals[i];
// If the terminal accepts the specified token, return it.
// slither-disable-next-line calls-loop
if (terminal.accountingContextForTokenOf(projectId, token).token != address(0)) {
return terminal;
}
}
// Not found.
return IJBTerminal(address(0));
}
/// @notice The specified project's terminals.
/// @param projectId The ID of the project to get the terminals of.
/// @return An array of the project's terminal addresses.
function terminalsOf(uint256 projectId) external view override returns (IJBTerminal[] memory) {
return _terminalsOf[projectId];
}
//*********************************************************************//
// -------------------------- public views --------------------------- //
//*********************************************************************//
/// @notice Check if a project uses a specific terminal.
/// @param projectId The ID of the project to check.
/// @param terminal The terminal to check for.
/// @return A flag indicating whether the project uses the terminal.
function isTerminalOf(uint256 projectId, IJBTerminal terminal) public view override returns (bool) {
// Keep a reference to the project's terminals.
IJBTerminal[] memory terminals = _terminalsOf[projectId];
// Keep a reference to the number of terminals the project has.
uint256 numberOfTerminals = terminals.length;
// Loop through and return true if the terminal is found.
for (uint256 i; i < numberOfTerminals; i++) {
if (terminals[i] == terminal) return true;
}
// Otherwise, return false.
return false;
}
//*********************************************************************//
// ---------------------- external transactions ---------------------- //
//*********************************************************************//
/// @notice Add or remove an address/contract from a list of trusted addresses which are allowed to set a first
/// controller for projects.
/// @dev Only this contract's owner can call this function.
/// @dev These addresses are vetted controllers as well as contracts designed to launch new projects.
/// @dev A project can set its own controller without being on this list.
/// @dev If you would like to add an address/contract to this list, please reach out to this contract's owner.
/// @param addr The address to allow or not allow.
/// @param flag Whether the address is allowed to set first controllers for projects. Use `true` to allow and
/// `false` to not allow.
function setIsAllowedToSetFirstController(address addr, bool flag) external override onlyOwner {
// Set the flag in the allowlist.
isAllowedToSetFirstController[addr] = flag;
emit SetIsAllowedToSetFirstController({addr: addr, isAllowed: flag, caller: msg.sender});
}
/// @notice Set a project's controller. Controllers manage how terminals interact with tokens and rulesets.
/// @dev Can only be called if:
/// - The ruleset's metadata has `allowSetController` enabled, and the message's sender is the project's owner or an
/// address with the owner's permission to `SET_CONTROLLER`.
/// - OR the message's sender is the project's current controller.
/// - OR an address which `isAllowedToSetFirstController` is setting a project's first controller.
/// @param projectId The ID of the project whose controller is being set.
/// @param controller The address of the controller to set.
function setControllerOf(uint256 projectId, IERC165 controller) external override {
// Keep a reference to the current controller.
IERC165 currentController = controllerOf[projectId];
// Enforce permissions.
_requirePermissionAllowingOverrideFrom({
account: PROJECTS.ownerOf(projectId),
projectId: projectId,
permissionId: JBPermissionIds.SET_CONTROLLER,
alsoGrantAccessIf: (isAllowedToSetFirstController[msg.sender] && address(currentController) == address(0))
});
// The project must exist.
if (projectId > PROJECTS.count()) revert JBDirectory_InvalidProjectIdInDirectory(projectId, PROJECTS.count());
// Get a reference to a flag indicating whether the project is allowed to set its controller.
// Setting the controller is allowed if the project doesn't have a controller,
// OR if the caller is the current controller,
// OR if the project's ruleset allows setting the controller.
bool allowSetController = address(currentController) == address(0)
|| !currentController.supportsInterface(type(IJBDirectoryAccessControl).interfaceId)
? true
: IJBDirectoryAccessControl(address(currentController)).setControllerAllowed(projectId);
// If setting the controller is not allowed, revert.
if (!allowSetController) {
revert JBDirectory_SetControllerNotAllowed();
}
// Prepare the new controller to receive the project.
if (address(currentController) != address(0) && controller.supportsInterface(type(IJBMigratable).interfaceId)) {
IJBMigratable(address(controller)).beforeReceiveMigrationFrom(currentController, projectId);
}
// Set the new controller.
// slither-disable-next-line reentrancy-no-eth
controllerOf[projectId] = controller;
emit SetController({projectId: projectId, controller: controller, caller: msg.sender});
// Migrate if needed.
if (
address(currentController) != address(0)
&& currentController.supportsInterface(type(IJBMigratable).interfaceId)
) {
IJBMigratable(address(currentController)).migrate(projectId, controller);
}
}
/// @notice Set a project's primary terminal for a token.
/// @dev The primary terminal for a token is where payments in that token are routed to by default.
/// @dev This is useful in cases where a project has multiple terminals which accept the same token.
/// @dev Can only be called by the project's owner, or an address with the owner's permission to
/// `SET_PRIMARY_TERMINAL`.
/// @param projectId The ID of the project whose primary terminal is being set.
/// @param token The token to set the primary terminal for.
/// @param terminal The terminal being set as the primary terminal.
function setPrimaryTerminalOf(uint256 projectId, address token, IJBTerminal terminal) external override {
// Enforce permissions.
_requirePermissionFrom({
account: PROJECTS.ownerOf(projectId),
projectId: projectId,
permissionId: JBPermissionIds.SET_PRIMARY_TERMINAL
});
// If the terminal doesn't accept the token, revert.
if (terminal.accountingContextForTokenOf(projectId, token).token == address(0)) {
revert JBDirectory_TokenNotAccepted(projectId, token, terminal);
}
// If the terminal hasn't already been added to the project, add it.
_addTerminalIfNeeded(projectId, terminal);
// Store the terminal as the project's primary terminal for the token.
_primaryTerminalOf[projectId][token] = terminal;
emit SetPrimaryTerminal({projectId: projectId, token: token, terminal: terminal, caller: msg.sender});
}
/// @notice Set a project's terminals.
/// @dev Can only be called by the project's owner, an address with the owner's permission to `SET_TERMINALS`, or
/// the project's controller.
/// @dev Unless the caller is the project's controller, the project's ruleset must allow setting terminals.
/// @param projectId The ID of the project whose terminals are being set.
/// @param terminals An array of terminal addresses to set for the project.
function setTerminalsOf(uint256 projectId, IJBTerminal[] calldata terminals) external override {
// Enforce permissions.
_requirePermissionAllowingOverrideFrom({
account: PROJECTS.ownerOf(projectId),
projectId: projectId,
permissionId: JBPermissionIds.SET_TERMINALS,
alsoGrantAccessIf: msg.sender == address(controllerOf[projectId])
});
// Keep a reference to the project's controller.
IERC165 controller = controllerOf[projectId];
// Get a reference to the flag indicating whether the project is allowed to set its terminals.
bool allowSetTerminals = !controller.supportsInterface(type(IJBDirectoryAccessControl).interfaceId)
|| IJBDirectoryAccessControl(address(controller)).setTerminalsAllowed(projectId);
// If the caller is not the project's controller, the project's ruleset must allow setting terminals.
if (msg.sender != address(controllerOf[projectId]) && !allowSetTerminals) {
revert JBDirectory_SetTerminalsNotAllowed();
}
// Set the stored terminals for the project.
_terminalsOf[projectId] = terminals;
// If there are any duplicates, revert.
if (terminals.length > 1) {
for (uint256 i; i < terminals.length; i++) {
for (uint256 j = i + 1; j < terminals.length; j++) {
if (terminals[i] == terminals[j]) revert JBDirectory_DuplicateTerminals(terminals[i]);
}
}
}
emit SetTerminals({projectId: projectId, terminals: terminals, caller: msg.sender});
}
//*********************************************************************//
// ------------------------ internal functions ----------------------- //
//*********************************************************************//
/// @notice If a terminal hasn't already been added to a project's list of terminals, add it.
/// @dev The project's ruleset must have `allowSetTerminals` set to `true`.
/// @param projectId The ID of the project to add the terminal to.
/// @param terminal The terminal to add.
function _addTerminalIfNeeded(uint256 projectId, IJBTerminal terminal) internal {
// Ensure that the terminal has not already been added.
if (isTerminalOf(projectId, terminal)) return;
// Keep a reference to the current controller.
IERC165 controller = controllerOf[projectId];
// Get a reference to a flag indicating whether the project is allowed to set its terminals.
bool allowSetTerminals = !controller.supportsInterface(type(IJBDirectoryAccessControl).interfaceId)
|| IJBDirectoryAccessControl(address(controller)).setTerminalsAllowed(projectId);
// The project's ruleset must allow setting terminals.
if (!allowSetTerminals) {
revert JBDirectory_SetTerminalsNotAllowed();
}
// Add the new terminal.
_terminalsOf[projectId].push(terminal);
emit AddTerminal({projectId: projectId, terminal: terminal, caller: msg.sender});
}
}// SPDX-License-Identifier: MIT
// slither-disable-next-line solc-version
pragma solidity ^0.8.0;
/// @notice Permission IDs for `JBPermissions`, used throughout the Bananapus ecosystem. See
/// [`JBPermissions`](https://github.com/Bananapus/nana-core/blob/main/src/JBPermissions.sol)
/// @dev `JBPermissions` allows one address to grant another address permission to call functions in Juicebox contracts
/// on their behalf. Each ID in `JBPermissionIds` grants access to a specific set of these functions.
library JBPermissionIds {
uint8 internal constant ROOT = 1; // All permissions across every contract. Very dangerous. BE CAREFUL!
/* Used by `nana-core`: https://github.com/Bananapus/nana-core */
uint8 internal constant QUEUE_RULESETS = 2; // Permission to call `JBController.queueRulesetsOf` and
// `JBController.launchRulesetsFor`.
uint8 internal constant CASH_OUT_TOKENS = 3; // Permission to call `JBMultiTerminal.cashOutTokensOf`.
uint8 internal constant SEND_PAYOUTS = 4; // Permission to call `JBMultiTerminal.sendPayoutsOf`.
uint8 internal constant MIGRATE_TERMINAL = 5; // Permission to call `JBMultiTerminal.migrateBalanceOf`.
uint8 internal constant SET_PROJECT_URI = 6; // Permission to call `JBController.setUriOf`.
uint8 internal constant DEPLOY_ERC20 = 7; // Permission to call `JBController.deployERC20For`.
uint8 internal constant SET_TOKEN = 8; // Permission to call `JBController.setTokenFor`.
uint8 internal constant MINT_TOKENS = 9; // Permission to call `JBController.mintTokensOf`.
uint8 internal constant BURN_TOKENS = 10; // Permission to call `JBController.burnTokensOf`.
uint8 internal constant CLAIM_TOKENS = 11; // Permission to call `JBController.claimTokensFor`.
uint8 internal constant TRANSFER_CREDITS = 12; // Permission to call `JBController.transferCreditsFrom`.
uint8 internal constant SET_CONTROLLER = 13; // Permission to call `JBDirectory.setControllerOf`.
uint8 internal constant SET_TERMINALS = 14; // Permission to call `JBDirectory.setTerminalsOf`.
// Be careful - `SET_TERMINALS` can be used to remove the primary terminal.
uint8 internal constant SET_PRIMARY_TERMINAL = 15; // Permission to call `JBDirectory.setPrimaryTerminalOf`.
uint8 internal constant USE_ALLOWANCE = 16; // Permission to call `JBMultiTerminal.useAllowanceOf`.
uint8 internal constant SET_SPLIT_GROUPS = 17; // Permission to call `JBController.setSplitGroupsOf`.
uint8 internal constant ADD_PRICE_FEED = 18; // Permission to call `JBPrices.addPriceFeedFor`.
uint8 internal constant ADD_ACCOUNTING_CONTEXTS = 19; // Permission to call
// `JBMultiTerminal.addAccountingContextsFor`.
/* Used by `nana-721-hook`: https://github.com/Bananapus/nana-721-hook */
uint8 internal constant ADJUST_721_TIERS = 20; // Permission to call `JB721TiersHook.adjustTiers`.
uint8 internal constant SET_721_METADATA = 21; // Permission to call `JB721TiersHook.setMetadata`.
uint8 internal constant MINT_721 = 22; // Permission to call `JB721TiersHook.mintFor`.
uint8 internal constant SET_721_DISCOUNT_PERCENT = 23; // Permission to call `JB721TiersHook.setDiscountPercentOf`.
/* Used by `nana-buyback-hook`: https://github.com/Bananapus/nana-buyback-hook */
uint8 internal constant SET_BUYBACK_TWAP = 24; // Permission to call `JBBuybackHook.setTwapWindowOf` and
// `JBBuybackHook.setTwapSlippageToleranceOf`.
uint8 internal constant SET_BUYBACK_POOL = 25; // Permission to call `JBBuybackHook.setPoolFor`.
/* Used by `nana-swap-terminal`: https://github.com/Bananapus/nana-swap-terminal */
uint8 internal constant ADD_SWAP_TERMINAL_POOL = 26; // Permission to call `JBSwapTerminal.addDefaultPool`.
uint8 internal constant ADD_SWAP_TERMINAL_TWAP_PARAMS = 27; // Permission to call
// `JBSwapTerminal.addTwapParamsFor`.
/* Used by `nana-suckers`: https://github.com/Bananapus/nana-suckers */
uint8 internal constant MAP_SUCKER_TOKEN = 28; // Permission to call `BPSucker.mapToken`.
uint8 internal constant DEPLOY_SUCKERS = 29; // Permission to call `BPSuckerRegistry.deploySuckersFor`.
uint8 internal constant SUCKER_SAFETY = 30; // Permission to call `BPSucker.enableEmergencyHatchFor` and
// `BPSucker.setDeprecation`.
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC-721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC-721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
* {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
import {IJBPermissioned} from "./../interfaces/IJBPermissioned.sol";
import {IJBPermissions} from "./../interfaces/IJBPermissions.sol";
/// @notice Modifiers to allow access to transactions based on which permissions the message's sender has.
abstract contract JBPermissioned is Context, IJBPermissioned {
//*********************************************************************//
// --------------------------- custom errors -------------------------- //
//*********************************************************************//
error JBPermissioned_Unauthorized(address account, address sender, uint256 projectId, uint256 permissionId);
//*********************************************************************//
// ---------------- public immutable stored properties --------------- //
//*********************************************************************//
/// @notice A contract storing permissions.
IJBPermissions public immutable override PERMISSIONS;
//*********************************************************************//
// -------------------------- constructor ---------------------------- //
//*********************************************************************//
/// @param permissions A contract storing permissions.
constructor(IJBPermissions permissions) {
PERMISSIONS = permissions;
}
//*********************************************************************//
// -------------------------- internal views ------------------------- //
//*********************************************************************//
/// @notice Require the message sender to be the account or have the relevant permission.
/// @param account The account to allow.
/// @param projectId The project ID to check the permission under.
/// @param permissionId The required permission ID. The operator must have this permission within the specified
/// project ID.
function _requirePermissionFrom(address account, uint256 projectId, uint256 permissionId) internal view {
address sender = _msgSender();
if (
sender != account
&& !PERMISSIONS.hasPermission({
operator: sender,
account: account,
projectId: projectId,
permissionId: permissionId,
includeRoot: true,
includeWildcardProjectId: true
})
) revert JBPermissioned_Unauthorized(account, sender, projectId, permissionId);
}
/// @notice If the 'alsoGrantAccessIf' condition is truthy, proceed. Otherwise, require the message sender to be the
/// account or
/// have the relevant permission.
/// @param account The account to allow.
/// @param projectId The project ID to check the permission under.
/// @param permissionId The required permission ID. The operator must have this permission within the specified
/// project ID.
/// @param alsoGrantAccessIf An override condition which will allow access regardless of permissions.
function _requirePermissionAllowingOverrideFrom(
address account,
uint256 projectId,
uint256 permissionId,
bool alsoGrantAccessIf
)
internal
view
{
if (alsoGrantAccessIf) return;
_requirePermissionFrom(account, projectId, permissionId);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {IJBProjects} from "./IJBProjects.sol";
import {IJBTerminal} from "./IJBTerminal.sol";
interface IJBDirectory {
event AddTerminal(uint256 indexed projectId, IJBTerminal indexed terminal, address caller);
event SetController(uint256 indexed projectId, IERC165 indexed controller, address caller);
event SetIsAllowedToSetFirstController(address indexed addr, bool indexed isAllowed, address caller);
event SetPrimaryTerminal(
uint256 indexed projectId, address indexed token, IJBTerminal indexed terminal, address caller
);
event SetTerminals(uint256 indexed projectId, IJBTerminal[] terminals, address caller);
function PROJECTS() external view returns (IJBProjects);
function controllerOf(uint256 projectId) external view returns (IERC165);
function isAllowedToSetFirstController(address account) external view returns (bool);
function isTerminalOf(uint256 projectId, IJBTerminal terminal) external view returns (bool);
function primaryTerminalOf(uint256 projectId, address token) external view returns (IJBTerminal);
function terminalsOf(uint256 projectId) external view returns (IJBTerminal[] memory);
function setControllerOf(uint256 projectId, IERC165 controller) external;
function setIsAllowedToSetFirstController(address account, bool flag) external;
function setPrimaryTerminalOf(uint256 projectId, address token, IJBTerminal terminal) external;
function setTerminalsOf(uint256 projectId, IJBTerminal[] calldata terminals) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IJBDirectoryAccessControl {
function setControllerAllowed(uint256 projectId) external view returns (bool);
function setTerminalsAllowed(uint256 projectId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IJBMigratable is IERC165 {
event Migrate(uint256 indexed projectId, IERC165 to, address caller);
function migrate(uint256 projectId, IERC165 to) external;
function beforeReceiveMigrationFrom(IERC165 from, uint256 projectId) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {JBAfterPayRecordedContext} from "./../structs/JBAfterPayRecordedContext.sol";
/// @notice Hook called after a terminal's `pay(...)` logic completes (if passed by the ruleset's data hook).
interface IJBPayHook is IERC165 {
/// @notice This function is called by the terminal's `pay(...)` function after the payment has been recorded in the
/// terminal store.
/// @dev Critical business logic should be protected by appropriate access control.
/// @param context The context passed in by the terminal, as a `JBAfterPayRecordedContext` struct.
function afterPayRecordedWith(JBAfterPayRecordedContext calldata context) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IJBPermissions} from "./IJBPermissions.sol";
interface IJBPermissioned {
function PERMISSIONS() external view returns (IJBPermissions);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {JBPermissionsData} from "./../structs/JBPermissionsData.sol";
interface IJBPermissions {
event OperatorPermissionsSet(
address indexed operator,
address indexed account,
uint256 indexed projectId,
uint8[] permissionIds,
uint256 packed,
address caller
);
function WILDCARD_PROJECT_ID() external view returns (uint256);
function permissionsOf(address operator, address account, uint256 projectId) external view returns (uint256);
function hasPermission(
address operator,
address account,
uint256 projectId,
uint256 permissionId,
bool includeRoot,
bool includeWildcardProjectId
)
external
view
returns (bool);
function hasPermissions(
address operator,
address account,
uint256 projectId,
uint256[] calldata permissionIds,
bool includeRoot,
bool includeWildcardProjectId
)
external
view
returns (bool);
function setPermissionsFor(address account, JBPermissionsData calldata permissionsData) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IJBTokenUriResolver} from "./IJBTokenUriResolver.sol";
interface IJBProjects is IERC721 {
event Create(uint256 indexed projectId, address indexed owner, address caller);
event SetTokenUriResolver(IJBTokenUriResolver indexed resolver, address caller);
function count() external view returns (uint256);
function tokenUriResolver() external view returns (IJBTokenUriResolver);
function createFor(address owner) external returns (uint256 projectId);
function setTokenUriResolver(IJBTokenUriResolver resolver) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {IJBPayHook} from "./IJBPayHook.sol";
import {JBAccountingContext} from "../structs/JBAccountingContext.sol";
import {JBAfterPayRecordedContext} from "../structs/JBAfterPayRecordedContext.sol";
/// @notice A terminal that accepts payments and can be migrated.
interface IJBTerminal is IERC165 {
event AddToBalance(
uint256 indexed projectId, uint256 amount, uint256 returnedFees, string memo, bytes metadata, address caller
);
event HookAfterRecordPay(
IJBPayHook indexed hook, JBAfterPayRecordedContext context, uint256 specificationAmount, address caller
);
event MigrateTerminal(
uint256 indexed projectId, address indexed token, IJBTerminal indexed to, uint256 amount, address caller
);
event Pay(
uint256 indexed rulesetId,
uint256 indexed rulesetCycleNumber,
uint256 indexed projectId,
address payer,
address beneficiary,
uint256 amount,
uint256 newlyIssuedTokenCount,
string memo,
bytes metadata,
address caller
);
event SetAccountingContext(uint256 indexed projectId, JBAccountingContext context, address caller);
function accountingContextForTokenOf(
uint256 projectId,
address token
)
external
view
returns (JBAccountingContext memory);
function accountingContextsOf(uint256 projectId) external view returns (JBAccountingContext[] memory);
function currentSurplusOf(
uint256 projectId,
JBAccountingContext[] memory accountingContexts,
uint256 decimals,
uint256 currency
)
external
view
returns (uint256);
function addAccountingContextsFor(uint256 projectId, JBAccountingContext[] calldata accountingContexts) external;
function addToBalanceOf(
uint256 projectId,
address token,
uint256 amount,
bool shouldReturnHeldFees,
string calldata memo,
bytes calldata metadata
)
external
payable;
function migrateBalanceOf(uint256 projectId, address token, IJBTerminal to) external returns (uint256 balance);
function pay(
uint256 projectId,
address token,
uint256 amount,
address beneficiary,
uint256 minReturnedTokens,
string calldata memo,
bytes calldata metadata
)
external
payable
returns (uint256 beneficiaryTokenCount);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IJBTokenUriResolver {
function getUri(uint256 projectId) external view returns (string memory tokenUri);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @custom:member token The address of the token that accounting is being done with.
/// @custom:member decimals The number of decimals expected in that token's fixed point accounting.
/// @custom:member currency The currency that the token is priced in terms of. By convention, this is
/// `uint32(uint160(tokenAddress))` for tokens, or a constant ID from e.g. `JBCurrencyIds` for other currencies.
struct JBAccountingContext {
address token;
uint8 decimals;
uint32 currency;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {JBTokenAmount} from "./JBTokenAmount.sol";
/// @custom:member payer The address the payment originated from.
/// @custom:member projectId The ID of the project being paid.
/// @custom:member rulesetId The ID of the ruleset the payment is being made during.
/// @custom:member amount The payment's token amount. Includes the token being paid, the value, the number of decimals
/// included, and the currency of the amount.
/// @custom:member forwardedAmount The token amount being forwarded to the pay hook. Includes the token
/// being paid, the value, the number of decimals included, and the currency of the amount.
/// @custom:member weight The current ruleset's weight (used to determine how many tokens should be minted).
/// @custom:member newlyIssuedTokenCount The number of project tokens minted for the beneficiary.
/// @custom:member beneficiary The address which receives any tokens this payment yields.
/// @custom:member hookMetadata Extra data specified by the data hook, which is sent to the pay hook.
/// @custom:member payerMetadata Extra data specified by the payer, which is sent to the pay hook.
struct JBAfterPayRecordedContext {
address payer;
uint256 projectId;
uint256 rulesetId;
JBTokenAmount amount;
JBTokenAmount forwardedAmount;
uint256 weight;
uint256 newlyIssuedTokenCount;
address beneficiary;
bytes hookMetadata;
bytes payerMetadata;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @custom:member operator The address that permissions are being given to.
/// @custom:member projectId The ID of the project the operator is being given permissions for. Operators only have
/// permissions under this project's scope. An ID of 0 is a wildcard, which gives an operator permissions across all
/// projects.
/// @custom:member permissionIds The IDs of the permissions being given. See the `JBPermissionIds` library.
struct JBPermissionsData {
address operator;
uint64 projectId;
uint8[] permissionIds;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @custom:member token The token the payment was made in.
/// @custom:member decimals The number of decimals included in the value fixed point number.
/// @custom:member currency The currency. By convention, this is `uint32(uint160(tokenAddress))` for tokens, or a
/// constant ID from e.g. `JBCurrencyIds` for other currencies.
/// @custom:member value The amount of tokens that was paid, as a fixed point number.
struct JBTokenAmount {
address token;
uint8 decimals;
uint32 currency;
uint256 value;
}{
"evmVersion": "paris",
"metadata": {
"appendCBOR": true,
"bytecodeHash": "ipfs",
"useLiteralContent": false
},
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": [
"@sphinx-labs/contracts/=lib/sphinx/packages/contracts/contracts/foundry/",
"@arbitrum/=node_modules/@arbitrum/",
"@bananapus/=node_modules/@bananapus/",
"@chainlink/=node_modules/@chainlink/",
"@eth-optimism/=node_modules/@eth-optimism/",
"@offchainlabs/=node_modules/@offchainlabs/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@prb/=node_modules/@prb/",
"@scroll-tech/=node_modules/@scroll-tech/",
"@uniswap/=node_modules/@uniswap/",
"@zksync/=node_modules/@zksync/",
"forge-std/=lib/forge-std/src/",
"hardhat/=node_modules/hardhat/",
"solmate/=node_modules/solmate/",
"sphinx/=lib/sphinx/packages/contracts/contracts/forge-std/src/"
],
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IJBPermissions","name":"permissions","type":"address"},{"internalType":"contract IJBProjects","name":"projects","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"contract IJBTerminal","name":"terminal","type":"address"}],"name":"JBDirectory_DuplicateTerminals","type":"error"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"JBDirectory_InvalidProjectIdInDirectory","type":"error"},{"inputs":[],"name":"JBDirectory_SetControllerNotAllowed","type":"error"},{"inputs":[],"name":"JBDirectory_SetTerminalsNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"contract IJBTerminal","name":"terminal","type":"address"}],"name":"JBDirectory_TokenNotAccepted","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"uint256","name":"permissionId","type":"uint256"}],"name":"JBPermissioned_Unauthorized","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":true,"internalType":"contract IJBTerminal","name":"terminal","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"AddTerminal","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":"projectId","type":"uint256"},{"indexed":true,"internalType":"contract IERC165","name":"controller","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"SetController","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"bool","name":"isAllowed","type":"bool"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"SetIsAllowedToSetFirstController","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"contract IJBTerminal","name":"terminal","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"SetPrimaryTerminal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"projectId","type":"uint256"},{"indexed":false,"internalType":"contract IJBTerminal[]","name":"terminals","type":"address[]"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"SetTerminals","type":"event"},{"inputs":[],"name":"PERMISSIONS","outputs":[{"internalType":"contract IJBPermissions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROJECTS","outputs":[{"internalType":"contract IJBProjects","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"}],"name":"controllerOf","outputs":[{"internalType":"contract IERC165","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isAllowedToSetFirstController","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"contract IJBTerminal","name":"terminal","type":"address"}],"name":"isTerminalOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"token","type":"address"}],"name":"primaryTerminalOf","outputs":[{"internalType":"contract IJBTerminal","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"contract IERC165","name":"controller","type":"address"}],"name":"setControllerOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"flag","type":"bool"}],"name":"setIsAllowedToSetFirstController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"contract IJBTerminal","name":"terminal","type":"address"}],"name":"setPrimaryTerminalOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"contract IJBTerminal[]","name":"terminals","type":"address[]"}],"name":"setTerminalsOf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectId","type":"uint256"}],"name":"terminalsOf","outputs":[{"internalType":"contract IJBTerminal[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162001926380380620019268339810160408190526200003491620000f4565b6001600160a01b03808416608052819081166200006b57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b62000076816200008b565b50506001600160a01b031660a0525062000148565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381168114620000f157600080fd5b50565b6000806000606084860312156200010a57600080fd5b83516200011781620000db565b60208501519093506200012a81620000db565b60408501519092506200013d81620000db565b809150509250925092565b60805160a05161178f620001976000396000818160f40152818161029001528181610541015281816105e00152818161066a0152610a9c01526000818161025401526110aa015261178f6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063862026501161008c578063c5664e2111610066578063c5664e21146101f9578063d17541531461021c578063f2fde38b1461023c578063f434c9141461024f57600080fd5b806386202650146101c25780638da5cb5b146101d5578063a1ed3175146101e657600080fd5b80636e49181f116100c85780636e49181f14610171578063714e7f3214610194578063715018a6146101a7578063821b9fd8146101af57600080fd5b8063293c4999146100ef5780635dd8f6aa1461013357806363d0850a1461015c575b600080fd5b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6101166101413660046113fc565b6001602052600090815260409020546001600160a01b031681565b61016f61016a36600461142a565b610276565b005b61018461017f36600461146c565b610444565b604051901515815260200161012a565b61016f6101a236600461146c565b61050b565b61016f610a6e565b61016f6101bd36600461149c565b610a82565b6101166101d036600461146c565b610dbd565b6000546001600160a01b0316610116565b61016f6101f4366004611529565b610f3e565b610184610207366004611557565b60026020526000908152604090205460ff1681565b61022f61022a3660046113fc565b610fa8565b60405161012a919061157b565b61016f61024a366004611557565b611014565b6101167f000000000000000000000000000000000000000000000000000000000000000081565b6040516331a9108f60e11b81526004810184905261030b907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156102df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030391906115c8565b84600f611052565b604051633a01714f60e01b8152600481018490526001600160a01b03838116602483015260009190831690633a01714f90604401606060405180830381865afa15801561035c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038091906115e5565b516001600160a01b0316036103c75760405163027bb87960e11b8152600481018490526001600160a01b038084166024830152821660448201526064015b60405180910390fd5b6103d18382611156565b60008381526003602090815260408083206001600160a01b038681168086529184529382902080546001600160a01b03191694861694851790559051338152909186917fc670a502bbb9f8a4315f95eca901a9f99b65f89a2eb5705a58050e5c00f9d672910160405180910390a4505050565b6000828152600460209081526040808320805482518185028101850190935280835284938301828280156104a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610483575b505083519394506000925050505b818110156104fd57846001600160a01b03168382815181106104d3576104d3611674565b60200260200101516001600160a01b0316036104f55760019350505050610505565b6001016104af565b506000925050505b92915050565b600082815260016020526040908190205490516331a9108f60e11b8152600481018490526001600160a01b03918216916105de917f000000000000000000000000000000000000000000000000000000000000000090911690636352211e90602401602060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ae91906115c8565b336000908152600260205260409020548590600d9060ff1680156105d957506001600160a01b038516155b6112f7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166306661abd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561063c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610660919061168a565b83111561070c57827f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166306661abd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ea919061168a565b6040516317140d0f60e31b8152600481019290925260248201526044016103be565b60006001600160a01b038216158061079557506040516301ffc9a760e01b81526001600160a01b038316906301ffc9a79061075290632877540760e01b906004016116a3565b602060405180830381865afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079391906116b8565b155b61080757604051632674968d60e21b8152600481018590526001600160a01b038316906399d25a3490602401602060405180830381865afa1580156107de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080291906116b8565b61080a565b60015b90508061082a5760405163cf211e7f60e01b815260040160405180910390fd5b6001600160a01b038216158015906108b157506040516301ffc9a760e01b81526001600160a01b038416906301ffc9a79061087090635825057160e11b906004016116a3565b602060405180830381865afa15801561088d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b191906116b8565b1561091957604051631e0231c360e31b81526001600160a01b0383811660048301526024820186905284169063f0118e1890604401600060405180830381600087803b15801561090057600080fd5b505af1158015610914573d6000803e3d6000fd5b505050505b60008481526001602090815260409182902080546001600160a01b0319166001600160a01b038716908117909155915133815286917f7f9a7dcb234c909a09de2f344661ad9e5b24067adb97c908647c2edcbb121c30910160405180910390a36001600160a01b03821615801590610a0057506040516301ffc9a760e01b81526001600160a01b038316906301ffc9a7906109bf90635825057160e11b906004016116a3565b602060405180830381865afa1580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0091906116b8565b15610a685760405163202dc27d60e11b8152600481018590526001600160a01b03848116602483015283169063405b84fa90604401600060405180830381600087803b158015610a4f57600080fd5b505af1158015610a63573d6000803e3d6000fd5b505050505b50505050565b610a76611307565b610a806000611334565b565b6040516331a9108f60e11b815260048101849052610b33907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0f91906115c8565b6000858152600160205260409020548590600e906001600160a01b031633146112f7565b6000838152600160205260408082205490516301ffc9a760e01b81526001600160a01b03909116919082906301ffc9a790610b7990632877540760e01b906004016116a3565b602060405180830381865afa158015610b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba91906116b8565b1580610c2a575060405163b1a50e3360e01b8152600481018690526001600160a01b0383169063b1a50e3390602401602060405180830381865afa158015610c06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2a91906116b8565b6000868152600160205260409020549091506001600160a01b03163314801590610c52575080155b15610c7057604051630fed236960e21b815260040160405180910390fd5b6000858152600460205260409020610c89908585611384565b506001831115610d7a5760005b83811015610d78576000610cab8260016116d5565b90505b84811015610d6f57858582818110610cc857610cc8611674565b9050602002016020810190610cdd9190611557565b6001600160a01b0316868684818110610cf857610cf8611674565b9050602002016020810190610d0d9190611557565b6001600160a01b031603610d6757858583818110610d2d57610d2d611674565b9050602002016020810190610d429190611557565b604051638a53d99f60e01b81526001600160a01b0390911660048201526024016103be565b600101610cae565b50600101610c96565b505b847fb648241d83df6540fc10f2acc641e4bf80a1e84e7ae2f1f6b0ad204b8fee635b858533604051610dae939291906116f6565b60405180910390a25050505050565b60008281526003602090815260408083206001600160a01b0380861685529252822054168015801590610df55750610df58482610444565b15610e01579050610505565b600084815260046020908152604080832080548251818502810185019093528083529192909190830182828015610e6157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e43575b505083519394506000925050505b81811015610f31576000838281518110610e8b57610e8b611674565b6020908102919091010151604051633a01714f60e01b8152600481018a90526001600160a01b038981166024830152919250600091831690633a01714f90604401606060405180830381865afa158015610ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d91906115e5565b516001600160a01b031614610f285794506105059350505050565b50600101610e6f565b5060009695505050505050565b610f46611307565b6001600160a01b038216600081815260026020908152604091829020805460ff191685151590811790915591513381529192917f11207664cc48b0fa81c8674795f1d8f642960f38d5d2d305ad813093bed85fab910160405180910390a35050565b60008181526004602090815260409182902080548351818402810184019094528084526060939283018282801561100857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610fea575b50505050509050919050565b61101c611307565b6001600160a01b03811661104657604051631e4fbdf760e01b8152600060048201526024016103be565b61104f81611334565b50565b336001600160a01b03841681148015906111175750604051631a45b42760e11b81526001600160a01b0382811660048301528581166024830152604482018590526064820184905260016084830181905260a48301527f0000000000000000000000000000000000000000000000000000000000000000169063348b684e9060c401602060405180830381865afa1580156110f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111591906116b8565b155b15610a6857604051631326f75560e11b81526001600160a01b0380861660048301528216602482015260448101849052606481018390526084016103be565b6111608282610444565b15611169575050565b6000828152600160205260408082205490516301ffc9a760e01b81526001600160a01b03909116919082906301ffc9a7906111af90632877540760e01b906004016116a3565b602060405180830381865afa1580156111cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f091906116b8565b1580611260575060405163b1a50e3360e01b8152600481018590526001600160a01b0383169063b1a50e3390602401602060405180830381865afa15801561123c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126091906116b8565b90508061128057604051630fed236960e21b815260040160405180910390fd5b600084815260046020908152604080832080546001810182559084529282902090920180546001600160a01b0319166001600160a01b038716908117909155915133815286917f409bccc07b7cf7807930526a24318212d614c59f2dde05a017a41efee144e7c8910160405180910390a350505050565b80610a6857610a68848484611052565b6000546001600160a01b03163314610a805760405163118cdaa760e01b81523360048201526024016103be565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280548282559060005260206000209081019282156113d7579160200282015b828111156113d75781546001600160a01b0319166001600160a01b038435161782556020909201916001909101906113a4565b506113e39291506113e7565b5090565b5b808211156113e357600081556001016113e8565b60006020828403121561140e57600080fd5b5035919050565b6001600160a01b038116811461104f57600080fd5b60008060006060848603121561143f57600080fd5b83359250602084013561145181611415565b9150604084013561146181611415565b809150509250925092565b6000806040838503121561147f57600080fd5b82359150602083013561149181611415565b809150509250929050565b6000806000604084860312156114b157600080fd5b83359250602084013567ffffffffffffffff808211156114d057600080fd5b818601915086601f8301126114e457600080fd5b8135818111156114f357600080fd5b8760208260051b850101111561150857600080fd5b6020830194508093505050509250925092565b801515811461104f57600080fd5b6000806040838503121561153c57600080fd5b823561154781611415565b915060208301356114918161151b565b60006020828403121561156957600080fd5b813561157481611415565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156115bc5783516001600160a01b031683529284019291840191600101611597565b50909695505050505050565b6000602082840312156115da57600080fd5b815161157481611415565b6000606082840312156115f757600080fd5b6040516060810181811067ffffffffffffffff8211171561162857634e487b7160e01b600052604160045260246000fd5b604052825161163681611415565b8152602083015160ff8116811461164c57600080fd5b6020820152604083015163ffffffff8116811461166857600080fd5b60408201529392505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561169c57600080fd5b5051919050565b6001600160e01b031991909116815260200190565b6000602082840312156116ca57600080fd5b81516115748161151b565b8082018082111561050557634e487b7160e01b600052601160045260246000fd5b6040808252810183905260008460608301825b8681101561173957823561171c81611415565b6001600160a01b0316825260209283019290910190600101611709565b506001600160a01b0394909416602093909301929092525090939250505056fea2646970667358221220e023368f049ac60d7a5275cb961c9de2bcc8f70c76610ee585527395a7c3930864736f6c6343000817003300000000000000000000000004fd6913d6c32d8c216e153a43c04b1857a7793d000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d400000000000000000000000080a8f7a4bd75b539ce26937016df607fdc9abeb5
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063862026501161008c578063c5664e2111610066578063c5664e21146101f9578063d17541531461021c578063f2fde38b1461023c578063f434c9141461024f57600080fd5b806386202650146101c25780638da5cb5b146101d5578063a1ed3175146101e657600080fd5b80636e49181f116100c85780636e49181f14610171578063714e7f3214610194578063715018a6146101a7578063821b9fd8146101af57600080fd5b8063293c4999146100ef5780635dd8f6aa1461013357806363d0850a1461015c575b600080fd5b6101167f000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d481565b6040516001600160a01b0390911681526020015b60405180910390f35b6101166101413660046113fc565b6001602052600090815260409020546001600160a01b031681565b61016f61016a36600461142a565b610276565b005b61018461017f36600461146c565b610444565b604051901515815260200161012a565b61016f6101a236600461146c565b61050b565b61016f610a6e565b61016f6101bd36600461149c565b610a82565b6101166101d036600461146c565b610dbd565b6000546001600160a01b0316610116565b61016f6101f4366004611529565b610f3e565b610184610207366004611557565b60026020526000908152604090205460ff1681565b61022f61022a3660046113fc565b610fa8565b60405161012a919061157b565b61016f61024a366004611557565b611014565b6101167f00000000000000000000000004fd6913d6c32d8c216e153a43c04b1857a7793d81565b6040516331a9108f60e11b81526004810184905261030b907f000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d46001600160a01b031690636352211e90602401602060405180830381865afa1580156102df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030391906115c8565b84600f611052565b604051633a01714f60e01b8152600481018490526001600160a01b03838116602483015260009190831690633a01714f90604401606060405180830381865afa15801561035c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038091906115e5565b516001600160a01b0316036103c75760405163027bb87960e11b8152600481018490526001600160a01b038084166024830152821660448201526064015b60405180910390fd5b6103d18382611156565b60008381526003602090815260408083206001600160a01b038681168086529184529382902080546001600160a01b03191694861694851790559051338152909186917fc670a502bbb9f8a4315f95eca901a9f99b65f89a2eb5705a58050e5c00f9d672910160405180910390a4505050565b6000828152600460209081526040808320805482518185028101850190935280835284938301828280156104a157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610483575b505083519394506000925050505b818110156104fd57846001600160a01b03168382815181106104d3576104d3611674565b60200260200101516001600160a01b0316036104f55760019350505050610505565b6001016104af565b506000925050505b92915050565b600082815260016020526040908190205490516331a9108f60e11b8152600481018490526001600160a01b03918216916105de917f000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d490911690636352211e90602401602060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ae91906115c8565b336000908152600260205260409020548590600d9060ff1680156105d957506001600160a01b038516155b6112f7565b7f000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d46001600160a01b03166306661abd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561063c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610660919061168a565b83111561070c57827f000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d46001600160a01b03166306661abd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ea919061168a565b6040516317140d0f60e31b8152600481019290925260248201526044016103be565b60006001600160a01b038216158061079557506040516301ffc9a760e01b81526001600160a01b038316906301ffc9a79061075290632877540760e01b906004016116a3565b602060405180830381865afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079391906116b8565b155b61080757604051632674968d60e21b8152600481018590526001600160a01b038316906399d25a3490602401602060405180830381865afa1580156107de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080291906116b8565b61080a565b60015b90508061082a5760405163cf211e7f60e01b815260040160405180910390fd5b6001600160a01b038216158015906108b157506040516301ffc9a760e01b81526001600160a01b038416906301ffc9a79061087090635825057160e11b906004016116a3565b602060405180830381865afa15801561088d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b191906116b8565b1561091957604051631e0231c360e31b81526001600160a01b0383811660048301526024820186905284169063f0118e1890604401600060405180830381600087803b15801561090057600080fd5b505af1158015610914573d6000803e3d6000fd5b505050505b60008481526001602090815260409182902080546001600160a01b0319166001600160a01b038716908117909155915133815286917f7f9a7dcb234c909a09de2f344661ad9e5b24067adb97c908647c2edcbb121c30910160405180910390a36001600160a01b03821615801590610a0057506040516301ffc9a760e01b81526001600160a01b038316906301ffc9a7906109bf90635825057160e11b906004016116a3565b602060405180830381865afa1580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0091906116b8565b15610a685760405163202dc27d60e11b8152600481018590526001600160a01b03848116602483015283169063405b84fa90604401600060405180830381600087803b158015610a4f57600080fd5b505af1158015610a63573d6000803e3d6000fd5b505050505b50505050565b610a76611307565b610a806000611334565b565b6040516331a9108f60e11b815260048101849052610b33907f000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d46001600160a01b031690636352211e90602401602060405180830381865afa158015610aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0f91906115c8565b6000858152600160205260409020548590600e906001600160a01b031633146112f7565b6000838152600160205260408082205490516301ffc9a760e01b81526001600160a01b03909116919082906301ffc9a790610b7990632877540760e01b906004016116a3565b602060405180830381865afa158015610b96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bba91906116b8565b1580610c2a575060405163b1a50e3360e01b8152600481018690526001600160a01b0383169063b1a50e3390602401602060405180830381865afa158015610c06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2a91906116b8565b6000868152600160205260409020549091506001600160a01b03163314801590610c52575080155b15610c7057604051630fed236960e21b815260040160405180910390fd5b6000858152600460205260409020610c89908585611384565b506001831115610d7a5760005b83811015610d78576000610cab8260016116d5565b90505b84811015610d6f57858582818110610cc857610cc8611674565b9050602002016020810190610cdd9190611557565b6001600160a01b0316868684818110610cf857610cf8611674565b9050602002016020810190610d0d9190611557565b6001600160a01b031603610d6757858583818110610d2d57610d2d611674565b9050602002016020810190610d429190611557565b604051638a53d99f60e01b81526001600160a01b0390911660048201526024016103be565b600101610cae565b50600101610c96565b505b847fb648241d83df6540fc10f2acc641e4bf80a1e84e7ae2f1f6b0ad204b8fee635b858533604051610dae939291906116f6565b60405180910390a25050505050565b60008281526003602090815260408083206001600160a01b0380861685529252822054168015801590610df55750610df58482610444565b15610e01579050610505565b600084815260046020908152604080832080548251818502810185019093528083529192909190830182828015610e6157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e43575b505083519394506000925050505b81811015610f31576000838281518110610e8b57610e8b611674565b6020908102919091010151604051633a01714f60e01b8152600481018a90526001600160a01b038981166024830152919250600091831690633a01714f90604401606060405180830381865afa158015610ee9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d91906115e5565b516001600160a01b031614610f285794506105059350505050565b50600101610e6f565b5060009695505050505050565b610f46611307565b6001600160a01b038216600081815260026020908152604091829020805460ff191685151590811790915591513381529192917f11207664cc48b0fa81c8674795f1d8f642960f38d5d2d305ad813093bed85fab910160405180910390a35050565b60008181526004602090815260409182902080548351818402810184019094528084526060939283018282801561100857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610fea575b50505050509050919050565b61101c611307565b6001600160a01b03811661104657604051631e4fbdf760e01b8152600060048201526024016103be565b61104f81611334565b50565b336001600160a01b03841681148015906111175750604051631a45b42760e11b81526001600160a01b0382811660048301528581166024830152604482018590526064820184905260016084830181905260a48301527f00000000000000000000000004fd6913d6c32d8c216e153a43c04b1857a7793d169063348b684e9060c401602060405180830381865afa1580156110f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111591906116b8565b155b15610a6857604051631326f75560e11b81526001600160a01b0380861660048301528216602482015260448101849052606481018390526084016103be565b6111608282610444565b15611169575050565b6000828152600160205260408082205490516301ffc9a760e01b81526001600160a01b03909116919082906301ffc9a7906111af90632877540760e01b906004016116a3565b602060405180830381865afa1580156111cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f091906116b8565b1580611260575060405163b1a50e3360e01b8152600481018590526001600160a01b0383169063b1a50e3390602401602060405180830381865afa15801561123c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126091906116b8565b90508061128057604051630fed236960e21b815260040160405180910390fd5b600084815260046020908152604080832080546001810182559084529282902090920180546001600160a01b0319166001600160a01b038716908117909155915133815286917f409bccc07b7cf7807930526a24318212d614c59f2dde05a017a41efee144e7c8910160405180910390a350505050565b80610a6857610a68848484611052565b6000546001600160a01b03163314610a805760405163118cdaa760e01b81523360048201526024016103be565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280548282559060005260206000209081019282156113d7579160200282015b828111156113d75781546001600160a01b0319166001600160a01b038435161782556020909201916001909101906113a4565b506113e39291506113e7565b5090565b5b808211156113e357600081556001016113e8565b60006020828403121561140e57600080fd5b5035919050565b6001600160a01b038116811461104f57600080fd5b60008060006060848603121561143f57600080fd5b83359250602084013561145181611415565b9150604084013561146181611415565b809150509250925092565b6000806040838503121561147f57600080fd5b82359150602083013561149181611415565b809150509250929050565b6000806000604084860312156114b157600080fd5b83359250602084013567ffffffffffffffff808211156114d057600080fd5b818601915086601f8301126114e457600080fd5b8135818111156114f357600080fd5b8760208260051b850101111561150857600080fd5b6020830194508093505050509250925092565b801515811461104f57600080fd5b6000806040838503121561153c57600080fd5b823561154781611415565b915060208301356114918161151b565b60006020828403121561156957600080fd5b813561157481611415565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156115bc5783516001600160a01b031683529284019291840191600101611597565b50909695505050505050565b6000602082840312156115da57600080fd5b815161157481611415565b6000606082840312156115f757600080fd5b6040516060810181811067ffffffffffffffff8211171561162857634e487b7160e01b600052604160045260246000fd5b604052825161163681611415565b8152602083015160ff8116811461164c57600080fd5b6020820152604083015163ffffffff8116811461166857600080fd5b60408201529392505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561169c57600080fd5b5051919050565b6001600160e01b031991909116815260200190565b6000602082840312156116ca57600080fd5b81516115748161151b565b8082018082111561050557634e487b7160e01b600052601160045260246000fd5b6040808252810183905260008460608301825b8681101561173957823561171c81611415565b6001600160a01b0316825260209283019290910190600101611709565b506001600160a01b0394909416602093909301929092525090939250505056fea2646970667358221220e023368f049ac60d7a5275cb961c9de2bcc8f70c76610ee585527395a7c3930864736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000004fd6913d6c32d8c216e153a43c04b1857a7793d000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d400000000000000000000000080a8f7a4bd75b539ce26937016df607fdc9abeb5
-----Decoded View---------------
Arg [0] : permissions (address): 0x04fD6913d6c32D8C216e153a43C04b1857a7793d
Arg [1] : projects (address): 0x885f707EFA18D2cb12f05a3a8eBA6B4B26c8c1D4
Arg [2] : owner (address): 0x80a8F7a4bD75b539CE26937016Df607fdC9ABeb5
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000004fd6913d6c32d8c216e153a43c04b1857a7793d
Arg [1] : 000000000000000000000000885f707efa18d2cb12f05a3a8eba6b4b26c8c1d4
Arg [2] : 00000000000000000000000080a8f7a4bd75b539ce26937016df607fdc9abeb5
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.