ETH Price: $3,331.28 (-3.95%)
Gas: 6 Gwei

Contract

0x85e6cAE882E521BdA19Fd86A242BE29d7BaC4e85
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Create Crowdfund...153773682022-08-20 11:30:16704 days ago1660995016IN
0x85e6cAE8...d7BaC4e85
0 ETH0.004804745.05877329
Create Crowdfund...153654002022-08-18 13:59:52706 days ago1660831192IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0143639913.46690126
Create Crowdfund...153491082022-08-16 0:11:37708 days ago1660608697IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0203597513.27128919
Create Crowdfund...153396712022-08-14 12:07:59710 days ago1660478879IN
0x85e6cAE8...d7BaC4e85
0 ETH0.006636376.33988792
Create Crowdfund...153218882022-08-11 16:59:36713 days ago1660237176IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0204948824.59794271
Create Crowdfund...152988102022-08-08 1:53:14716 days ago1659923594IN
0x85e6cAE8...d7BaC4e85
0 ETH0.006861126.43204124
Create Crowdfund...152212272022-07-27 0:08:25728 days ago1658880505IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0072177310.07955252
Create Crowdfund...151969622022-07-23 5:09:18732 days ago1658552958IN
0x85e6cAE8...d7BaC4e85
0 ETH0.005258717.34427069
Create Crowdfund...151962232022-07-23 2:22:29732 days ago1658542949IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0074506710.40276126
Create Crowdfund...151835982022-07-21 3:39:53734 days ago1658374793IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0117248912.34494979
Create Crowdfund...151551662022-07-16 17:54:07739 days ago1657994047IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0214439929.939338
Create Crowdfund...151338172022-07-13 10:41:59742 days ago1657708919IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0129926118.14476401
Create Crowdfund...151271062022-07-12 9:50:06743 days ago1657619406IN
0x85e6cAE8...d7BaC4e85
0 ETH0.017010117.9096558
Create Crowdfund...150928332022-07-07 2:48:34748 days ago1657162114IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0170345518.3213521
Create Crowdfund...150674502022-07-03 4:36:48752 days ago1656823008IN
0x85e6cAE8...d7BaC4e85
0 ETH0.007536219.04913198
Create Crowdfund...150567192022-07-01 12:54:39754 days ago1656680079IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0244674524.58586198
Create Crowdfund...150458592022-06-29 16:24:55756 days ago1656519895IN
0x85e6cAE8...d7BaC4e85
0 ETH0.035857650.07591327
Transfer150458082022-06-29 16:10:29756 days ago1656519029IN
0x85e6cAE8...d7BaC4e85
0.05709371 ETH0.0012786660.75880656
Create Crowdfund...150312542022-06-26 22:39:20758 days ago1656283160IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0281732939.34065124
Create Crowdfund...150027422022-06-21 14:31:12764 days ago1655821872IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0562074952.6935237
Create Crowdfund...149889622022-06-19 4:52:52766 days ago1655614372IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0115538312.16437861
Create Crowdfund...149816312022-06-17 22:33:12767 days ago1655505192IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0219323526.33229921
Create Crowdfund...149812982022-06-17 21:04:37768 days ago1655499877IN
0x85e6cAE8...d7BaC4e85
0 ETH0.026468131.7788935
Create Crowdfund...149479472022-06-12 3:31:34773 days ago1655004694IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0353085337.17764484
Create Crowdfund...149388822022-06-10 14:18:09775 days ago1654870689IN
0x85e6cAE8...d7BaC4e85
0 ETH0.0443856753.28777441
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
153773682022-08-20 11:30:16704 days ago1660995016
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
153654002022-08-18 13:59:52706 days ago1660831192
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
153491082022-08-16 0:11:37708 days ago1660608697
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
153396712022-08-14 12:07:59710 days ago1660478879
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
153218882022-08-11 16:59:36713 days ago1660237176
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
152988102022-08-08 1:53:14716 days ago1659923594
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
152212272022-07-27 0:08:25728 days ago1658880505
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
151969622022-07-23 5:09:18732 days ago1658552958
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
151962232022-07-23 2:22:29732 days ago1658542949
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
151835982022-07-21 3:39:53734 days ago1658374793
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
151551662022-07-16 17:54:07739 days ago1657994047
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
151338172022-07-13 10:41:59742 days ago1657708919
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
151271062022-07-12 9:50:06743 days ago1657619406
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
150928332022-07-07 2:48:34748 days ago1657162114
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
150674502022-07-03 4:36:48752 days ago1656823008
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
150567192022-07-01 12:54:39754 days ago1656680079
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
150458592022-06-29 16:24:55756 days ago1656519895
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
150312542022-06-26 22:39:20758 days ago1656283160
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
150027422022-06-21 14:31:12764 days ago1655821872
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
149889622022-06-19 4:52:52766 days ago1655614372
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
149816312022-06-17 22:33:12767 days ago1655505192
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
149812982022-06-17 21:04:37768 days ago1655499877
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
149479472022-06-12 3:31:34773 days ago1655004694
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
149388822022-06-10 14:18:09775 days ago1654870689
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
149303592022-06-09 3:12:39776 days ago1654744359
0x85e6cAE8...d7BaC4e85
 Contract Creation0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CrowdfundWithEditionsFactory

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion
File 1 of 13 : CrowdfundWithEditionsFactory.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

import {CrowdfundWithEditionsProxy} from "./CrowdfundWithEditionsProxy.sol";
import {CrowdfundWithEditionsLogic} from "./CrowdfundWithEditionsLogic.sol";
import {ICrowdfundWithEditions} from "./interface/ICrowdfundWithEditions.sol";
import {ITributaryRegistry} from "../../../interface/ITributaryRegistry.sol";
import {Governable} from "../../../lib/Governable.sol";

/**
 * @title CrowdfundWithEditionsFactory
 * @author MirrorXYZ
 */
contract CrowdfundWithEditionsFactory is Governable {
    //======== Structs ========

    struct Parameters {
        address payable fundingRecipient;
        uint256 fundingCap;
        uint256 operatorPercent;
        uint256 feePercentage;
    }

    //======== Events ========

    event CrowdfundDeployed(
        address crowdfundProxy,
        string name,
        string symbol,
        address operator
    );

    event Upgraded(address indexed implementation);

    //======== Configuration storage =========

    /*
        Updatable via governance
    */

    address public logic;
    address payable public editions;
    address public tributaryRegistry;
    address public treasuryConfig;
    uint256 public minFeePercentage = 250;

    //======== Runtime mutable storage =========

    // Gets set within the block, and then deleted.
    Parameters public parameters;

    //======== Constructor =========

    constructor(
        address owner_,
        address logic_,
        address payable editions_,
        address tributaryRegistry_,
        address treasuryConfig_
    ) Governable(owner_) {
        logic = logic_;
        editions = editions_;
        tributaryRegistry = tributaryRegistry_;
        treasuryConfig = treasuryConfig_;
    }

    //======== Configuration =========

    function setMinimumFeePercentage(uint256 newMinFeePercentage)
        public
        onlyGovernance
    {
        minFeePercentage = newMinFeePercentage;
    }

    function setEditions(address payable newEditions) public onlyGovernance {
        editions = newEditions;
    }

    function setLogic(address newLogic) public onlyGovernance {
        logic = newLogic;
    }

    function setTreasuryConfig(address newTreasuryConfig)
        public
        onlyGovernance
    {
        treasuryConfig = newTreasuryConfig;
    }

    function setTributaryRegistry(address newTributaryRegistry)
        public
        onlyGovernance
    {
        tributaryRegistry = newTributaryRegistry;
    }

    //======== Deploy function =========
    struct TributaryConfig {
        address tributary;
        uint256 feePercentage;
    }

    function createCrowdfundWithEdition(
        ICrowdfundWithEditions.EditionTier[] calldata tiers,
        TributaryConfig calldata tributaryConfig,
        string calldata name_,
        string calldata symbol_,
        address payable operator_,
        address payable fundingRecipient_,
        uint256 fundingCap_,
        uint256 operatorPercent_
    ) external returns (address crowdfundProxy) {
        require(
            tributaryConfig.feePercentage >= minFeePercentage,
            "fee is too low"
        );

        parameters = Parameters({
            fundingRecipient: fundingRecipient_,
            fundingCap: fundingCap_,
            operatorPercent: operatorPercent_,
            feePercentage: tributaryConfig.feePercentage
        });

        crowdfundProxy = address(
            new CrowdfundWithEditionsProxy{
                salt: keccak256(abi.encode(symbol_, operator_))
            }(treasuryConfig, operator_, name_, symbol_)
        );

        delete parameters;

        emit CrowdfundDeployed(crowdfundProxy, name_, symbol_, operator_);

        ITributaryRegistry(tributaryRegistry).registerTributary(
            crowdfundProxy,
            tributaryConfig.tributary
        );

        ICrowdfundWithEditions(editions).createEditions(
            tiers,
            payable(crowdfundProxy),
            crowdfundProxy
        );
    }
}

File 2 of 13 : CrowdfundWithEditionsProxy.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

import {CrowdfundWithEditionsStorage} from "./CrowdfundWithEditionsStorage.sol";
import {ERC20Storage} from "../../../external/ERC20Storage.sol";
import {IERC20Events} from "../../../external/interface/IERC20.sol";

interface ICrowdfundWithEditionsFactory {
    function mediaAddress() external returns (address);

    function logic() external returns (address);

    function editions() external returns (address);

    // ERC20 data.
    function parameters()
        external
        returns (
            address payable fundingRecipient,
            uint256 fundingCap,
            uint256 operatorPercent,
            uint256 feePercentage
        );
}

/**
 * @title CrowdfundWithEditionsProxy
 * @author MirrorXYZ
 */
contract CrowdfundWithEditionsProxy is
    CrowdfundWithEditionsStorage,
    ERC20Storage,
    IERC20Events
{
    event Upgraded(address indexed implementation);

    /**
     * @dev Storage slot with the address of the current implementation.
     * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
     * validated in the constructor.
     */
    bytes32 internal constant _IMPLEMENTATION_SLOT =
        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    constructor(
        address treasuryConfig_,
        address payable operator_,
        string memory name_,
        string memory symbol_
    ) ERC20Storage(name_, symbol_) {
        address logic = ICrowdfundWithEditionsFactory(msg.sender).logic();

        assembly {
            sstore(_IMPLEMENTATION_SLOT, logic)
        }

        emit Upgraded(logic);

        editions = ICrowdfundWithEditionsFactory(msg.sender).editions();
        // Crowdfund-specific data.
        (
            fundingRecipient,
            fundingCap,
            operatorPercent,
            feePercentage
        ) = ICrowdfundWithEditionsFactory(msg.sender).parameters();

        operator = operator_;
        treasuryConfig = treasuryConfig_;
        // Initialize mutable storage.
        status = Status.FUNDING;
    }

    /// @notice Get current logic
    function logic() external view returns (address logic_) {
        assembly {
            logic_ := sload(_IMPLEMENTATION_SLOT)
        }
    }

    fallback() external payable {
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize())
            let result := delegatecall(
                gas(),
                sload(_IMPLEMENTATION_SLOT),
                ptr,
                calldatasize(),
                0,
                0
            )
            let size := returndatasize()
            returndatacopy(ptr, 0, size)

            switch result
            case 0 {
                revert(ptr, size)
            }
            default {
                return(ptr, size)
            }
        }
    }

    receive() external payable {}
}

File 3 of 13 : CrowdfundWithEditionsLogic.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

import {CrowdfundWithEditionsStorage} from "./CrowdfundWithEditionsStorage.sol";
import {ERC20} from "../../../external/ERC20.sol";
import {ICrowdfundWithEditions} from "./interface/ICrowdfundWithEditions.sol";
import {ITreasuryConfig} from "../../../interface/ITreasuryConfig.sol";

/**
 * @title CrowdfundWithEditionsLogic
 * @author MirrorXYZ
 *
 * Crowdfund the creation of NFTs by issuing ERC20 tokens that
 * can be redeemed for the underlying value of the NFT once sold.
 */
contract CrowdfundWithEditionsLogic is CrowdfundWithEditionsStorage, ERC20 {
    // ============ Events ============

    event ReceivedERC721(uint256 tokenId, address sender);
    event Contribution(address contributor, uint256 amount);
    event ContributionForEdition(
        address contributor,
        uint256 amount,
        uint256 editionId,
        uint256 tokenId
    );

    event FundingClosed(uint256 amountRaised, uint256 creatorAllocation);
    event BidAccepted(uint256 amount);
    event Redeemed(address contributor, uint256 amount);
    event Withdrawal(uint256 amount, uint256 fee);

    // ============ Modifiers ============

    /**
     * @dev Modifier to check whether the `msg.sender` is the operator.
     * If it is, it will run the function. Otherwise, it will revert.
     */
    modifier onlyOperator() {
        require(msg.sender == operator);
        _;
    }

    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(reentrancy_status != REENTRANCY_ENTERED, "Reentrant call");

        // Any calls to nonReentrant after this point will fail
        reentrancy_status = REENTRANCY_ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        reentrancy_status = REENTRANCY_NOT_ENTERED;
    }

    // ============ Crowdfunding Methods ============

    /**
     * @notice Mints tokens for the sender propotional to the
     *  amount of ETH sent in the transaction.
     * @dev Emits the Contribution event.
     */
    function contribute(
        address payable backer,
        uint256 editionId,
        uint256 amount
    ) external payable nonReentrant {
        _contribute(backer, editionId, amount);
    }

    /**
     * @notice Burns the sender's tokens and redeems underlying ETH.
     * @dev Emits the Redeemed event.
     */
    function redeem(uint256 tokenAmount) external nonReentrant {
        // Prevent backers from accidently redeeming when balance is 0.
        require(
            address(this).balance > 0,
            "Crowdfund: No ETH available to redeem"
        );
        // Check
        require(
            balanceOf[msg.sender] >= tokenAmount,
            "Crowdfund: Insufficient balance"
        );
        require(status == Status.TRADING, "Crowdfund: Funding must be trading");
        // Effect
        uint256 redeemable = redeemableFromTokens(tokenAmount);
        _burn(msg.sender, tokenAmount);
        // Safe version of transfer.
        sendValue(payable(msg.sender), redeemable);
        emit Redeemed(msg.sender, redeemable);
    }

    /**
     * @notice Returns the amount of ETH that is redeemable for tokenAmount.
     */
    function redeemableFromTokens(uint256 tokenAmount)
        public
        view
        returns (uint256)
    {
        return (tokenAmount * address(this).balance) / totalSupply;
    }

    function valueToTokens(uint256 value) public pure returns (uint256 tokens) {
        tokens = value * TOKEN_SCALE;
    }

    function tokensToValue(uint256 tokenAmount)
        internal
        pure
        returns (uint256 value)
    {
        value = tokenAmount / TOKEN_SCALE;
    }

    // ============ Operator Methods ============

    /**
     * @notice Transfers all funds to operator, and mints tokens for the operator.
     *  Updates status to TRADING.
     * @dev Emits the FundingClosed event.
     */
    function closeFunding() external onlyOperator nonReentrant {
        require(status == Status.FUNDING, "Crowdfund: Funding must be open");
        // Close funding status, move to tradable.
        status = Status.TRADING;
        // Mint the operator a percent of the total supply.
        uint256 operatorTokens = (operatorPercent * totalSupply) /
            (100 - operatorPercent);
        _mint(operator, operatorTokens);
        // Announce that funding has been closed.
        emit FundingClosed(address(this).balance, operatorTokens);

        _withdraw();
    }

    /**
     * @notice Operator can change the funding recipient.
     */
    function changeFundingRecipient(address payable newFundingRecipient)
        public
        onlyOperator
    {
        fundingRecipient = newFundingRecipient;
    }

    function withdraw() public {
        _withdraw();
    }

    function computeFee(uint256 amount, uint256 feePercentage_)
        public
        pure
        returns (uint256 fee)
    {
        fee = (feePercentage_ * amount) / (100 * 100);
    }

    // ============ Utility Methods ============

    function sendValue(address payable recipient, uint256 amount) internal {
        require(
            address(this).balance >= amount,
            "Address: insufficient balance"
        );

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{value: amount}("");
        require(
            success,
            "Address: unable to send value, recipient may have reverted"
        );
    }

    // ============ Edition Methods ============

    function buyEdition(
        uint256 amount,
        uint256 editionId,
        address recipient
    ) internal returns (uint256) {
        // Check that the sender is paying the correct amount.
        require(
            amount >= ICrowdfundWithEditions(editions).editionPrice(editionId),
            "Unable purchase edition with available amount"
        );
        // We don't need to transfer the value to the NFT contract here,
        // since that contract trusts this one to check before minting.
        // I.E. this contract has minting privileges.
        return
            ICrowdfundWithEditions(editions).buyEdition(editionId, recipient);
    }

    // ============ Internal Methods  ============
    function _contribute(
        address payable backer,
        uint256 editionId,
        uint256 amount
    ) private {
        require(status == Status.FUNDING, "Crowdfund: Funding must be open");
        require(amount == msg.value, "Crowdfund: Amount is not value sent");
        // This first case is the happy path, so we will keep it efficient.
        // The balance, which includes the current contribution, is less than or equal to cap.
        if (address(this).balance <= fundingCap) {
            // Mint equity for the contributor.
            _mint(backer, valueToTokens(amount));

            // Editions start at 1, so a "0" edition means the user wants to contribute without
            // purchasing a token.
            if (editionId > 0) {
                emit ContributionForEdition(
                    backer,
                    amount,
                    editionId,
                    buyEdition(amount, editionId, backer)
                );
            } else {
                emit Contribution(backer, amount);
            }
        } else {
            // Compute the balance of the crowdfund before the contribution was made.
            uint256 startAmount = address(this).balance - amount;
            // If that amount was already greater than the funding cap, then we should revert immediately.
            require(
                startAmount < fundingCap,
                "Crowdfund: Funding cap already reached"
            );
            // Otherwise, the contribution helped us reach the funding cap. We should
            // take what we can until the funding cap is reached, and refund the rest.
            uint256 eligibleAmount = fundingCap - startAmount;
            // Otherwise, we process the contribution as if it were the minimal amount.
            _mint(backer, valueToTokens(eligibleAmount));

            if (editionId > 0) {
                emit ContributionForEdition(
                    backer,
                    eligibleAmount,
                    editionId,
                    // Attempt to purchase edition with eligible amount.
                    buyEdition(eligibleAmount, editionId, backer)
                );
            } else {
                emit Contribution(backer, eligibleAmount);
            }
            // Refund the sender with their contribution (e.g. 2.5 minus the diff - e.g. 1.5 = 1 ETH)
            sendValue(backer, amount - eligibleAmount);
        }
    }

    function _withdraw() internal {
        uint256 fee = feePercentage;

        emit Withdrawal(
            address(this).balance,
            computeFee(address(this).balance, fee)
        );

        // Transfer the fee to the treasury.
        sendValue(
            ITreasuryConfig(treasuryConfig).treasury(),
            computeFee(address(this).balance, fee)
        );
        // Transfer available balance to the fundingRecipient.
        sendValue(fundingRecipient, address(this).balance);
    }
}

File 4 of 13 : ICrowdfundWithEditions.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

interface ICrowdfundWithEditions {
    struct Edition {
        // The maximum number of tokens that can be sold.
        uint256 quantity;
        // The price at which each token will be sold, in ETH.
        uint256 price;
        // The account that will receive sales revenue.
        address payable fundingRecipient;
        // The number of tokens sold so far.
        uint256 numSold;
        bytes32 contentHash;
    }

    struct EditionTier {
        // The maximum number of tokens that can be sold.
        uint256 quantity;
        // The price at which each token will be sold, in ETH.
        uint256 price;
        bytes32 contentHash;
    }

    function buyEdition(uint256 editionId, address recipient)
        external
        payable
        returns (uint256 tokenId);

    function editionPrice(uint256 editionId) external view returns (uint256);

    function createEditions(
        EditionTier[] memory tier,
        // The account that should receive the revenue.
        address payable fundingRecipient,
        address minter
    ) external;

    function contractURI() external view returns (string memory);
}

File 5 of 13 : ITributaryRegistry.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

interface ITributaryRegistry {
    function addRegistrar(address registrar) external;

    function removeRegistrar(address registrar) external;

    function addSingletonProducer(address producer) external;

    function removeSingletonProducer(address producer) external;

    function registerTributary(address producer, address tributary) external;

    function producerToTributary(address producer)
        external
        returns (address tributary);

    function singletonProducer(address producer) external returns (bool);

    function changeTributary(address producer, address newTributary) external;
}

File 6 of 13 : Governable.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

import {Ownable} from "../lib/Ownable.sol";
import {IGovernable} from "../lib/interface/IGovernable.sol";

contract Governable is Ownable, IGovernable {
    // ============ Mutable Storage ============

    // Mirror governance contract.
    address public override governor;

    // ============ Modifiers ============

    modifier onlyGovernance() {
        require(isOwner() || isGovernor(), "caller is not governance");
        _;
    }

    modifier onlyGovernor() {
        require(isGovernor(), "caller is not governor");
        _;
    }

    // ============ Constructor ============

    constructor(address owner_) Ownable(owner_) {}

    // ============ Administration ============

    function changeGovernor(address governor_) public override onlyGovernance {
        governor = governor_;
    }

    // ============ Utility Functions ============

    function isGovernor() public view override returns (bool) {
        return msg.sender == governor;
    }
}

File 7 of 13 : CrowdfundWithEditionsStorage.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

/**
 * @title CrowdfundWithEditionsStorage
 * @author MirrorXYZ
 */
contract CrowdfundWithEditionsStorage {
    /**
     * @notice The two states that this contract can exist in.
     * "FUNDING" allows contributors to add funds.
     */
    enum Status {
        FUNDING,
        TRADING
    }

    // ============ Constants ============

    /// @notice The factor by which ETH contributions will multiply into crowdfund tokens.
    uint16 internal constant TOKEN_SCALE = 1000;

    // ============ Reentrancy ============

    /// @notice Reentrancy constants.
    uint256 internal constant REENTRANCY_NOT_ENTERED = 1;
    uint256 internal constant REENTRANCY_ENTERED = 2;

    /// @notice Current reentrancy status -- used by the modifier.
    uint256 internal reentrancy_status;

    /// @notice The operator has a special role to change contract status.
    address payable public operator;

    /// @notice Receives the funds when calling withdraw. Operator can configure.
    address payable public fundingRecipient;

    /// @notice Treasury configuration.
    address public treasuryConfig;

    /// @notice We add a hard cap to prevent raising more funds than deemed reasonable.
    uint256 public fundingCap;

    /// @notice Fee percentage that the crowdfund pays to the treasury.
    uint256 public feePercentage;

    /// @notice The operator takes some equity in the tokens, represented by this percent.
    uint256 public operatorPercent;

    // ============ Mutable Storage ============

    /// @notice Represents the current state of the campaign.
    Status public status;

    // ============ Tiered Campaigns ============

    /// @notice Address of the editions contract to purchase from.
    address public editions;
}

File 8 of 13 : ERC20Storage.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

/**
 * @title ERC20Storage
 * @author MirrorXYZ
 */
contract ERC20Storage {
    /// @notice EIP-20 token name for this token
    string public name;

    /// @notice EIP-20 token symbol for this token
    string public symbol;

    /// @notice EIP-20 total number of tokens in circulation
    uint256 public totalSupply;

    /// @notice Initialize total supply to zero.
    constructor(string memory name_, string memory symbol_) {
        name = name_;
        symbol = symbol_;
        totalSupply = 0;
    }
}

File 9 of 13 : IERC20.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

interface IERC20 {
    /// @notice EIP-20 token name for this token
    function name() external returns (string calldata);

    /// @notice EIP-20 token symbol for this token
    function symbol() external returns (string calldata);

    /// @notice EIP-20 token decimals for this token
    function decimals() external returns (uint8);

    /// @notice EIP-20 total number of tokens in circulation
    function totalSupply() external returns (uint256);

    /// @notice EIP-20 official record of token balances for each account
    function balanceOf(address account) external returns (uint256);

    /// @notice EIP-20 allowance amounts on behalf of others
    function allowance(address owner, address spender)
        external
        returns (uint256);

    /// @notice EIP-20 approves _spender_ to transfer up to _value_ multiple times
    function approve(address spender, uint256 value) external returns (bool);

    /// @notice EIP-20 transfer _value_ to _to_ from _msg.sender_
    function transfer(address to, uint256 value) external returns (bool);

    /// @notice EIP-20 transfer _value_ to _to_ from _from_
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

interface IERC20Events {
    /// @notice EIP-20 Mint event
    event Mint(address indexed to, uint256 amount);

    /// @notice EIP-20 approval event
    event Approval(
        address indexed from,
        address indexed spender,
        uint256 value
    );

    /// @notice EIP-20 transfer event
    event Transfer(address indexed from, address indexed to, uint256 value);
}

File 10 of 13 : ERC20.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

// import {ERC20Storage} from "./ERC20Storage.sol";
import {IERC20, IERC20Events} from "./interface/IERC20.sol";

/**
 * @title ERC20 Implementation.
 * @author MirrorXYZ
 */
contract ERC20 is IERC20, IERC20Events {
    // ============ ERC20 Attributes ============
    /// @notice EIP-20 token name for this token
    string public override name;

    /// @notice EIP-20 token symbol for this token
    string public override symbol;

    /// @notice EIP-20 token decimals for this token
    uint8 public constant override decimals = 18;

    // ============ Mutable ERC20 Storage ============
    /// @notice EIP-20 total number of tokens in circulation
    uint256 public override totalSupply;

    /// @notice EIP-20 official record of token balances for each account
    mapping(address => uint256) public override balanceOf;

    /// @notice EIP-20 allowance amounts on behalf of others
    mapping(address => mapping(address => uint256)) public override allowance;

    /**
     * @notice Initialize and assign total supply when using
     * proxy pattern. Only callable during contract deployment.
     * @param totalSupply_ is the initial token supply
     * @param to_ is the address that will hold the initial token supply
     */
    function initialize(uint256 totalSupply_, address to_) external {
        // Ensure that this function is only callable during contract construction.
        assembly {
            if extcodesize(address()) {
                revert(0, 0)
            }
        }

        totalSupply = totalSupply_;
        balanceOf[to_] = totalSupply_;
        emit Transfer(address(0), to_, totalSupply_);
    }

    // ============ ERC20 Spec ============

    /**
     * @dev Function to increase allowance of tokens.
     * @param spender The address that will receive an allowance increase.
     * @param value The amount of tokens to increase allowance.
     */
    function approve(address spender, uint256 value)
        external
        override
        returns (bool)
    {
        _approve(msg.sender, spender, value);
        return true;
    }

    /**
     * @dev Function to transfer tokens.
     * @param to The address that will receive the tokens.
     * @param value The amount of tokens to transfer.
     */
    function transfer(address to, uint256 value)
        external
        override
        returns (bool)
    {
        _transfer(msg.sender, to, value);
        return true;
    }

    /**
     * @dev Function to transfer an accounts tokens. Sender of txn must be approved.
     * @param from The address that will transfer tokens.
     * @param to The address that will receive the tokens.
     * @param value The amount of tokens to transfer.
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external override returns (bool) {
        require(
            allowance[from][msg.sender] >= value,
            "transfer amount exceeds spender allowance"
        );

        allowance[from][msg.sender] = allowance[from][msg.sender] - value;
        _transfer(from, to, value);
        return true;
    }

    // ============ Private Utils ============

    function _mint(address to, uint256 value) internal {
        totalSupply = totalSupply + value;
        balanceOf[to] = balanceOf[to] + value;
        emit Transfer(address(0), to, value);
    }

    function _burn(address from, uint256 value) internal {
        balanceOf[from] = balanceOf[from] - value;
        totalSupply = totalSupply - value;
        emit Transfer(from, address(0), value);
    }

    function _approve(
        address owner,
        address spender,
        uint256 value
    ) internal {
        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    function _transfer(
        address from,
        address to,
        uint256 value
    ) internal {
        require(balanceOf[from] >= value, "transfer amount exceeds balance");

        balanceOf[from] = balanceOf[from] - value;
        balanceOf[to] = balanceOf[to] + value;

        emit Transfer(from, to, value);
    }
}

File 11 of 13 : ITreasuryConfig.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

interface ITreasuryConfig {
    function treasury() external returns (address payable);

    function distributionModel() external returns (address);
}

File 12 of 13 : Ownable.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

contract Ownable {
    address public owner;
    address private nextOwner;

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    // modifiers

    modifier onlyOwner() {
        require(isOwner(), "caller is not the owner.");
        _;
    }

    modifier onlyNextOwner() {
        require(isNextOwner(), "current owner must set caller as next owner.");
        _;
    }

    /**
     * @dev Initialize contract by setting transaction submitter as initial owner.
     */
    constructor(address owner_) {
        owner = owner_;
        emit OwnershipTransferred(address(0), owner);
    }

    /**
     * @dev Initiate ownership transfer by setting nextOwner.
     */
    function transferOwnership(address nextOwner_) external onlyOwner {
        require(nextOwner_ != address(0), "Next owner is the zero address.");

        nextOwner = nextOwner_;
    }

    /**
     * @dev Cancel ownership transfer by deleting nextOwner.
     */
    function cancelOwnershipTransfer() external onlyOwner {
        delete nextOwner;
    }

    /**
     * @dev Accepts ownership transfer by setting owner.
     */
    function acceptOwnership() external onlyNextOwner {
        delete nextOwner;

        owner = msg.sender;

        emit OwnershipTransferred(owner, msg.sender);
    }

    /**
     * @dev Renounce ownership by setting owner to zero address.
     */
    function renounceOwnership() external onlyOwner {
        owner = address(0);

        emit OwnershipTransferred(owner, address(0));
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == owner;
    }

    /**
     * @dev Returns true if the caller is the next owner.
     */
    function isNextOwner() public view returns (bool) {
        return msg.sender == nextOwner;
    }
}

File 13 of 13 : IGovernable.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;

interface IGovernable {
    function changeGovernor(address governor_) external;

    function isGovernor() external view returns (bool);

    function governor() external view returns (address);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 2000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"logic_","type":"address"},{"internalType":"address payable","name":"editions_","type":"address"},{"internalType":"address","name":"tributaryRegistry_","type":"address"},{"internalType":"address","name":"treasuryConfig_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"crowdfundProxy","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"CrowdfundDeployed","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":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governor_","type":"address"}],"name":"changeGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bytes32","name":"contentHash","type":"bytes32"}],"internalType":"struct ICrowdfundWithEditions.EditionTier[]","name":"tiers","type":"tuple[]"},{"components":[{"internalType":"address","name":"tributary","type":"address"},{"internalType":"uint256","name":"feePercentage","type":"uint256"}],"internalType":"struct CrowdfundWithEditionsFactory.TributaryConfig","name":"tributaryConfig","type":"tuple"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address payable","name":"operator_","type":"address"},{"internalType":"address payable","name":"fundingRecipient_","type":"address"},{"internalType":"uint256","name":"fundingCap_","type":"uint256"},{"internalType":"uint256","name":"operatorPercent_","type":"uint256"}],"name":"createCrowdfundWithEdition","outputs":[{"internalType":"address","name":"crowdfundProxy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"editions","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isGovernor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isNextOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"logic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minFeePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"parameters","outputs":[{"internalType":"address payable","name":"fundingRecipient","type":"address"},{"internalType":"uint256","name":"fundingCap","type":"uint256"},{"internalType":"uint256","name":"operatorPercent","type":"uint256"},{"internalType":"uint256","name":"feePercentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newEditions","type":"address"}],"name":"setEditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newLogic","type":"address"}],"name":"setLogic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinFeePercentage","type":"uint256"}],"name":"setMinimumFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasuryConfig","type":"address"}],"name":"setTreasuryConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTributaryRegistry","type":"address"}],"name":"setTributaryRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nextOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryConfig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tributaryRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405260fa6007553480156200001657600080fd5b5060405162001c3a38038062001c3a8339810160408190526200003991620000da565b600080546001600160a01b0319166001600160a01b038716908117825560405187928392917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35050600380546001600160a01b039586166001600160a01b03199182161790915560048054948616948216949094179093556005805492851692841692909217909155600680549190931691161790555062000173565b600080600080600060a08688031215620000f357600080fd5b855162000100816200015a565b602087015190955062000113816200015a565b604087015190945062000126816200015a565b606087015190935062000139816200015a565b60808701519092506200014c816200015a565b809150509295509295909350565b6001600160a01b03811681146200017057600080fd5b50565b611ab780620001836000396000f3fe60806040523480156200001157600080fd5b5060043610620001a15760003560e01c8063c7af335211620000e9578063e011bf8e1162000097578063f1fe1663116200006e578063f1fe1663146200037a578063f2fde38b1462000391578063ff39e71014620003a857600080fd5b8063e011bf8e1462000338578063e4c0aaf4146200034f578063ed459df2146200036657600080fd5b8063d321de7311620000cc578063d321de7314620002f9578063d6811b6f1462000310578063d7dfa0dd146200032457600080fd5b8063c7af335214620002d1578063cfd7b0df14620002e557600080fd5b806379ba509711620001535780638da5cb5b116200012a5780638da5cb5b14620002895780638f32d59b146200029d578063b8ddbcb314620002bd57600080fd5b806379ba5097146200021d57806383892879146200022757806389035730146200023e57600080fd5b80632a0b17ee11620001885780632a0b17ee14620001e3578063715018a614620001fc57806371857000146200020657600080fd5b80630c340a2414620001a657806323452b9c14620001d7575b600080fd5b600254620001ba906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001e1620003bf565b005b620001ed60075481565b604051908152602001620001ce565b620001e162000431565b620001e16200021736600462000d53565b620004c9565b620001e16200055d565b620001ba6200023836600462000d7a565b62000627565b600854600954600a54600b546200025e936001600160a01b031692919084565b604080516001600160a01b0390951685526020850193909352918301526060820152608001620001ce565b600054620001ba906001600160a01b031681565b6000546001600160a01b031633145b6040519015158152602001620001ce565b600454620001ba906001600160a01b031681565b6002546001600160a01b03163314620002ac565b600654620001ba906001600160a01b031681565b620001e16200030a36600462000d53565b620008e9565b600554620001ba906001600160a01b031681565b600354620001ba906001600160a01b031681565b620001e16200034936600462000d53565b6200097d565b620001e16200036036600462000d53565b62000a11565b6001546001600160a01b03163314620002ac565b620001e16200038b36600462000d53565b62000aa5565b620001e1620003a236600462000d53565b62000b39565b620001e1620003b936600462000e6c565b62000c0f565b6000546001600160a01b031633146200041f5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064015b60405180910390fd5b600180546001600160a01b0319169055565b6000546001600160a01b031633146200048d5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e0000000000000000604482015260640162000416565b600080546001600160a01b031916815560405181907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3565b6000546001600160a01b0316331480620004ed57506002546001600160a01b031633145b6200053b5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314620005df5760405162461bcd60e51b815260206004820152602c60248201527f63757272656e74206f776e6572206d757374207365742063616c6c657220617360448201527f206e657874206f776e65722e0000000000000000000000000000000000000000606482015260840162000416565b600180546001600160a01b0319908116909155600080543392168217815560405182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3565b60006007548a602001351015620006815760405162461bcd60e51b815260206004820152600e60248201527f66656520697320746f6f206c6f77000000000000000000000000000000000000604482015260640162000416565b604080516080810182526001600160a01b03861680825260208083018790528284018690528d8101356060909301839052600880546001600160a01b0319169092179091556009869055600a859055600b919091559051620006ea918991899189910162000fe1565b60405160208183030381529060405280519060200120600660009054906101000a90046001600160a01b0316868b8b8b8b604051620007299062000c86565b6200073a9695949392919062000ecf565b8190604051809103906000f59050801580156200075b573d6000803e3d6000fd5b50600880546001600160a01b031916905560006009819055600a819055600b556040519091507f5133bb164b64ffa4461bc0c782a5c0e71cdc9d6c6ef5aa9af84f7fd2cd966d8e90620007ba9083908c908c908c908c908c9062000f20565b60405180910390a16005546001600160a01b0316633d2a6f7782620007e360208e018e62000d53565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03928316600482015291166024820152604401600060405180830381600087803b1580156200084457600080fd5b505af115801562000859573d6000803e3d6000fd5b50505050600460009054906101000a90046001600160a01b03166001600160a01b03166309fc162a8d8d84856040518563ffffffff1660e01b8152600401620008a6949392919062000f72565b600060405180830381600087803b158015620008c157600080fd5b505af1158015620008d6573d6000803e3d6000fd5b505050509b9a5050505050505050505050565b6000546001600160a01b03163314806200090d57506002546001600160a01b031633145b6200095b5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331480620009a157506002546001600160a01b031633145b620009ef5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633148062000a3557506002546001600160a01b031633145b62000a835760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633148062000ac957506002546001600160a01b031633145b62000b175760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331462000b955760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e0000000000000000604482015260640162000416565b6001600160a01b03811662000bed5760405162461bcd60e51b815260206004820152601f60248201527f4e657874206f776e657220697320746865207a65726f20616464726573732e00604482015260640162000416565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633148062000c3357506002546001600160a01b031633145b62000c815760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600755565b610a58806200102a83390190565b803562000ca18162001010565b919050565b60008083601f84011262000cb957600080fd5b50813567ffffffffffffffff81111562000cd257600080fd5b60208301915083602060608302850101111562000cee57600080fd5b9250929050565b60008083601f84011262000d0857600080fd5b50813567ffffffffffffffff81111562000d2157600080fd5b60208301915083602082850101111562000cee57600080fd5b60006040828403121562000d4d57600080fd5b50919050565b60006020828403121562000d6657600080fd5b813562000d738162001010565b9392505050565b60008060008060008060008060008060006101208c8e03121562000d9d57600080fd5b67ffffffffffffffff808d35111562000db557600080fd5b62000dc48e8e358f0162000ca6565b909c509a5062000dd88e60208f0162000d3a565b99508060608e0135111562000dec57600080fd5b62000dfe8e60608f01358f0162000cf5565b909950975060808d013581101562000e1557600080fd5b5062000e288d60808e01358e0162000cf5565b909650945062000e3b60a08d0162000c94565b935062000e4b60c08d0162000c94565b925060e08c013591506101008c013590509295989b509295989b9093969950565b60006020828403121562000e7f57600080fd5b5035919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60006001600160a01b0380891683528088166020840152506080604083015262000efe60808301868862000e86565b828103606084015262000f1381858762000e86565b9998505050505050505050565b60006001600160a01b0380891683526080602084015262000f4660808401888a62000e86565b838103604085015262000f5b81878962000e86565b925050808416606084015250979650505050505050565b60608082528181018590526000908660808401835b8881101562000fb957823582526020808401359083015260408084013590830152918301919083019060010162000f87565b506001600160a01b039687166020860152949095166040909301929092525090949350505050565b60408152600062000ff760408301858762000e86565b90506001600160a01b0383166020830152949350505050565b6001600160a01b03811681146200102657600080fd5b5056fe60806040523480156200001157600080fd5b5060405162000a5838038062000a58833981016040819052620000349162000477565b8151829082906200004d906008906020850190620002b1565b50805162000063906009906020840190620002b1565b506000600a8190555050506000336001600160a01b031663d7dfa0dd6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015620000ac57600080fd5b505af1158015620000c1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e791906200040e565b9050807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55806001600160a01b03167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a2336001600160a01b031663b8ddbcb36040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156200017e57600080fd5b505af115801562000193573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b991906200040e565b600760016101000a8154816001600160a01b0302191690836001600160a01b03160217905550336001600160a01b031663890357306040518163ffffffff1660e01b8152600401608060405180830381600087803b1580156200021b57600080fd5b505af115801562000230573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000256919062000435565b600555600655600455600280546001600160a01b03199081166001600160a01b0393841617909155600180548216968316969096179095556003805490951695169490941790925550506007805460ff191690555062000578565b828054620002bf906200050c565b90600052602060002090601f016020900481019282620002e357600085556200032e565b82601f10620002fe57805160ff19168380011785556200032e565b828001600101855582156200032e579182015b828111156200032e57825182559160200191906001019062000311565b506200033c92915062000340565b5090565b5b808211156200033c576000815560010162000341565b600082601f8301126200036957600080fd5b81516001600160401b038082111562000386576200038662000549565b604051601f8301601f19908116603f01168101908282118183101715620003b157620003b162000549565b81604052838152602092508683858801011115620003ce57600080fd5b600091505b83821015620003f25785820183015181830184015290820190620003d3565b83821115620004045760008385830101525b9695505050505050565b6000602082840312156200042157600080fd5b81516200042e816200055f565b9392505050565b600080600080608085870312156200044c57600080fd5b845162000459816200055f565b60208601516040870151606090970151919890975090945092505050565b600080600080608085870312156200048e57600080fd5b84516200049b816200055f565b6020860151909450620004ae816200055f565b60408601519093506001600160401b0380821115620004cc57600080fd5b620004da8883890162000357565b93506060870151915080821115620004f157600080fd5b50620005008782880162000357565b91505092959194509250565b600181811c908216806200052157607f821691505b602082108114156200054357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200057557600080fd5b50565b6104d080620005886000396000f3fe6080604052600436106100cb5760003560e01c806395d89b4111610074578063cfd7b0df1161004e578063cfd7b0df14610280578063d7dfa0dd146102ad578063e3b2594f146102e1576100d2565b806395d89b4114610223578063a001ecdd14610238578063b8ddbcb31461024e576100d2565b8063200d2ed2116100a5578063200d2ed2146101b9578063570ca735146101e05780637b4044a01461020d576100d2565b806306fdde031461011857806318160ddd146101435780631bb534ba14610167576100d2565b366100d257005b604051366000823760008036837f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d806000843e818015610114578184f35b8184fd5b34801561012457600080fd5b5061012d6102f7565b60405161013a91906103d3565b60405180910390f35b34801561014f57600080fd5b50610159600a5481565b60405190815260200161013a565b34801561017357600080fd5b506002546101949073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013a565b3480156101c557600080fd5b506007546101d39060ff1681565b60405161013a9190610392565b3480156101ec57600080fd5b506001546101949073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021957600080fd5b5061015960065481565b34801561022f57600080fd5b5061012d610385565b34801561024457600080fd5b5061015960055481565b34801561025a57600080fd5b5060075461019490610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561028c57600080fd5b506003546101949073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b957600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54610194565b3480156102ed57600080fd5b5061015960045481565b6008805461030490610446565b80601f016020809104026020016040519081016040528092919081815260200182805461033090610446565b801561037d5780601f106103525761010080835404028352916020019161037d565b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505081565b6009805461030490610446565b60208101600283106103cd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b600060208083528351808285015260005b81811015610400578581018301518582016040015282016103e4565b81811115610412576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c9082168061045a57607f821691505b60208210811415610494577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b5091905056fea264697066735822122075e2c11b94fd8bff7467563877afbbd5b54be285e957310575d63f73b2551baf64736f6c63430008060033a2646970667358221220863b10cd7107d16db86edc4e6ee9f540c6abdabfd909fd484d11007c876bcd0a64736f6c634300080600330000000000000000000000002330ee705ffd040bb0cba8cb7734dfe00e7c4b570000000000000000000000000e41862deeca185f784b96a0bc44de21f0436306000000000000000000000000834ebe76d6e0331fe86071963cad42c98199fc7c0000000000000000000000001171b858777120a59a6cc8148edda8982f187cd800000000000000000000000021a93be569666527dae0fdbfbe7715299dec1202

Deployed Bytecode

0x60806040523480156200001157600080fd5b5060043610620001a15760003560e01c8063c7af335211620000e9578063e011bf8e1162000097578063f1fe1663116200006e578063f1fe1663146200037a578063f2fde38b1462000391578063ff39e71014620003a857600080fd5b8063e011bf8e1462000338578063e4c0aaf4146200034f578063ed459df2146200036657600080fd5b8063d321de7311620000cc578063d321de7314620002f9578063d6811b6f1462000310578063d7dfa0dd146200032457600080fd5b8063c7af335214620002d1578063cfd7b0df14620002e557600080fd5b806379ba509711620001535780638da5cb5b116200012a5780638da5cb5b14620002895780638f32d59b146200029d578063b8ddbcb314620002bd57600080fd5b806379ba5097146200021d57806383892879146200022757806389035730146200023e57600080fd5b80632a0b17ee11620001885780632a0b17ee14620001e3578063715018a614620001fc57806371857000146200020657600080fd5b80630c340a2414620001a657806323452b9c14620001d7575b600080fd5b600254620001ba906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b620001e1620003bf565b005b620001ed60075481565b604051908152602001620001ce565b620001e162000431565b620001e16200021736600462000d53565b620004c9565b620001e16200055d565b620001ba6200023836600462000d7a565b62000627565b600854600954600a54600b546200025e936001600160a01b031692919084565b604080516001600160a01b0390951685526020850193909352918301526060820152608001620001ce565b600054620001ba906001600160a01b031681565b6000546001600160a01b031633145b6040519015158152602001620001ce565b600454620001ba906001600160a01b031681565b6002546001600160a01b03163314620002ac565b600654620001ba906001600160a01b031681565b620001e16200030a36600462000d53565b620008e9565b600554620001ba906001600160a01b031681565b600354620001ba906001600160a01b031681565b620001e16200034936600462000d53565b6200097d565b620001e16200036036600462000d53565b62000a11565b6001546001600160a01b03163314620002ac565b620001e16200038b36600462000d53565b62000aa5565b620001e1620003a236600462000d53565b62000b39565b620001e1620003b936600462000e6c565b62000c0f565b6000546001600160a01b031633146200041f5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064015b60405180910390fd5b600180546001600160a01b0319169055565b6000546001600160a01b031633146200048d5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e0000000000000000604482015260640162000416565b600080546001600160a01b031916815560405181907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3565b6000546001600160a01b0316331480620004ed57506002546001600160a01b031633145b6200053b5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b03163314620005df5760405162461bcd60e51b815260206004820152602c60248201527f63757272656e74206f776e6572206d757374207365742063616c6c657220617360448201527f206e657874206f776e65722e0000000000000000000000000000000000000000606482015260840162000416565b600180546001600160a01b0319908116909155600080543392168217815560405182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3565b60006007548a602001351015620006815760405162461bcd60e51b815260206004820152600e60248201527f66656520697320746f6f206c6f77000000000000000000000000000000000000604482015260640162000416565b604080516080810182526001600160a01b03861680825260208083018790528284018690528d8101356060909301839052600880546001600160a01b0319169092179091556009869055600a859055600b919091559051620006ea918991899189910162000fe1565b60405160208183030381529060405280519060200120600660009054906101000a90046001600160a01b0316868b8b8b8b604051620007299062000c86565b6200073a9695949392919062000ecf565b8190604051809103906000f59050801580156200075b573d6000803e3d6000fd5b50600880546001600160a01b031916905560006009819055600a819055600b556040519091507f5133bb164b64ffa4461bc0c782a5c0e71cdc9d6c6ef5aa9af84f7fd2cd966d8e90620007ba9083908c908c908c908c908c9062000f20565b60405180910390a16005546001600160a01b0316633d2a6f7782620007e360208e018e62000d53565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03928316600482015291166024820152604401600060405180830381600087803b1580156200084457600080fd5b505af115801562000859573d6000803e3d6000fd5b50505050600460009054906101000a90046001600160a01b03166001600160a01b03166309fc162a8d8d84856040518563ffffffff1660e01b8152600401620008a6949392919062000f72565b600060405180830381600087803b158015620008c157600080fd5b505af1158015620008d6573d6000803e3d6000fd5b505050509b9a5050505050505050505050565b6000546001600160a01b03163314806200090d57506002546001600160a01b031633145b6200095b5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331480620009a157506002546001600160a01b031633145b620009ef5760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633148062000a3557506002546001600160a01b031633145b62000a835760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633148062000ac957506002546001600160a01b031633145b62000b175760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331462000b955760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420746865206f776e65722e0000000000000000604482015260640162000416565b6001600160a01b03811662000bed5760405162461bcd60e51b815260206004820152601f60248201527f4e657874206f776e657220697320746865207a65726f20616464726573732e00604482015260640162000416565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633148062000c3357506002546001600160a01b031633145b62000c815760405162461bcd60e51b815260206004820152601860248201527f63616c6c6572206973206e6f7420676f7665726e616e63650000000000000000604482015260640162000416565b600755565b610a58806200102a83390190565b803562000ca18162001010565b919050565b60008083601f84011262000cb957600080fd5b50813567ffffffffffffffff81111562000cd257600080fd5b60208301915083602060608302850101111562000cee57600080fd5b9250929050565b60008083601f84011262000d0857600080fd5b50813567ffffffffffffffff81111562000d2157600080fd5b60208301915083602082850101111562000cee57600080fd5b60006040828403121562000d4d57600080fd5b50919050565b60006020828403121562000d6657600080fd5b813562000d738162001010565b9392505050565b60008060008060008060008060008060006101208c8e03121562000d9d57600080fd5b67ffffffffffffffff808d35111562000db557600080fd5b62000dc48e8e358f0162000ca6565b909c509a5062000dd88e60208f0162000d3a565b99508060608e0135111562000dec57600080fd5b62000dfe8e60608f01358f0162000cf5565b909950975060808d013581101562000e1557600080fd5b5062000e288d60808e01358e0162000cf5565b909650945062000e3b60a08d0162000c94565b935062000e4b60c08d0162000c94565b925060e08c013591506101008c013590509295989b509295989b9093969950565b60006020828403121562000e7f57600080fd5b5035919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60006001600160a01b0380891683528088166020840152506080604083015262000efe60808301868862000e86565b828103606084015262000f1381858762000e86565b9998505050505050505050565b60006001600160a01b0380891683526080602084015262000f4660808401888a62000e86565b838103604085015262000f5b81878962000e86565b925050808416606084015250979650505050505050565b60608082528181018590526000908660808401835b8881101562000fb957823582526020808401359083015260408084013590830152918301919083019060010162000f87565b506001600160a01b039687166020860152949095166040909301929092525090949350505050565b60408152600062000ff760408301858762000e86565b90506001600160a01b0383166020830152949350505050565b6001600160a01b03811681146200102657600080fd5b5056fe60806040523480156200001157600080fd5b5060405162000a5838038062000a58833981016040819052620000349162000477565b8151829082906200004d906008906020850190620002b1565b50805162000063906009906020840190620002b1565b506000600a8190555050506000336001600160a01b031663d7dfa0dd6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015620000ac57600080fd5b505af1158015620000c1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e791906200040e565b9050807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55806001600160a01b03167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a2336001600160a01b031663b8ddbcb36040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156200017e57600080fd5b505af115801562000193573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b991906200040e565b600760016101000a8154816001600160a01b0302191690836001600160a01b03160217905550336001600160a01b031663890357306040518163ffffffff1660e01b8152600401608060405180830381600087803b1580156200021b57600080fd5b505af115801562000230573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000256919062000435565b600555600655600455600280546001600160a01b03199081166001600160a01b0393841617909155600180548216968316969096179095556003805490951695169490941790925550506007805460ff191690555062000578565b828054620002bf906200050c565b90600052602060002090601f016020900481019282620002e357600085556200032e565b82601f10620002fe57805160ff19168380011785556200032e565b828001600101855582156200032e579182015b828111156200032e57825182559160200191906001019062000311565b506200033c92915062000340565b5090565b5b808211156200033c576000815560010162000341565b600082601f8301126200036957600080fd5b81516001600160401b038082111562000386576200038662000549565b604051601f8301601f19908116603f01168101908282118183101715620003b157620003b162000549565b81604052838152602092508683858801011115620003ce57600080fd5b600091505b83821015620003f25785820183015181830184015290820190620003d3565b83821115620004045760008385830101525b9695505050505050565b6000602082840312156200042157600080fd5b81516200042e816200055f565b9392505050565b600080600080608085870312156200044c57600080fd5b845162000459816200055f565b60208601516040870151606090970151919890975090945092505050565b600080600080608085870312156200048e57600080fd5b84516200049b816200055f565b6020860151909450620004ae816200055f565b60408601519093506001600160401b0380821115620004cc57600080fd5b620004da8883890162000357565b93506060870151915080821115620004f157600080fd5b50620005008782880162000357565b91505092959194509250565b600181811c908216806200052157607f821691505b602082108114156200054357634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200057557600080fd5b50565b6104d080620005886000396000f3fe6080604052600436106100cb5760003560e01c806395d89b4111610074578063cfd7b0df1161004e578063cfd7b0df14610280578063d7dfa0dd146102ad578063e3b2594f146102e1576100d2565b806395d89b4114610223578063a001ecdd14610238578063b8ddbcb31461024e576100d2565b8063200d2ed2116100a5578063200d2ed2146101b9578063570ca735146101e05780637b4044a01461020d576100d2565b806306fdde031461011857806318160ddd146101435780631bb534ba14610167576100d2565b366100d257005b604051366000823760008036837f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d806000843e818015610114578184f35b8184fd5b34801561012457600080fd5b5061012d6102f7565b60405161013a91906103d3565b60405180910390f35b34801561014f57600080fd5b50610159600a5481565b60405190815260200161013a565b34801561017357600080fd5b506002546101949073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013a565b3480156101c557600080fd5b506007546101d39060ff1681565b60405161013a9190610392565b3480156101ec57600080fd5b506001546101949073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021957600080fd5b5061015960065481565b34801561022f57600080fd5b5061012d610385565b34801561024457600080fd5b5061015960055481565b34801561025a57600080fd5b5060075461019490610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561028c57600080fd5b506003546101949073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b957600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54610194565b3480156102ed57600080fd5b5061015960045481565b6008805461030490610446565b80601f016020809104026020016040519081016040528092919081815260200182805461033090610446565b801561037d5780601f106103525761010080835404028352916020019161037d565b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505081565b6009805461030490610446565b60208101600283106103cd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b600060208083528351808285015260005b81811015610400578581018301518582016040015282016103e4565b81811115610412576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c9082168061045a57607f821691505b60208210811415610494577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b5091905056fea264697066735822122075e2c11b94fd8bff7467563877afbbd5b54be285e957310575d63f73b2551baf64736f6c63430008060033a2646970667358221220863b10cd7107d16db86edc4e6ee9f540c6abdabfd909fd484d11007c876bcd0a64736f6c63430008060033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000002330ee705ffd040bb0cba8cb7734dfe00e7c4b570000000000000000000000000e41862deeca185f784b96a0bc44de21f0436306000000000000000000000000834ebe76d6e0331fe86071963cad42c98199fc7c0000000000000000000000001171b858777120a59a6cc8148edda8982f187cd800000000000000000000000021a93be569666527dae0fdbfbe7715299dec1202

-----Decoded View---------------
Arg [0] : owner_ (address): 0x2330ee705fFD040bB0cbA8CB7734Dfe00E7C4b57
Arg [1] : logic_ (address): 0x0e41862dEECA185F784B96A0bc44DE21F0436306
Arg [2] : editions_ (address): 0x834Ebe76D6e0331fe86071963caD42c98199fC7c
Arg [3] : tributaryRegistry_ (address): 0x1171B858777120a59a6cc8148eDda8982F187Cd8
Arg [4] : treasuryConfig_ (address): 0x21A93bE569666527dAe0FDBFbe7715299dEC1202

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000002330ee705ffd040bb0cba8cb7734dfe00e7c4b57
Arg [1] : 0000000000000000000000000e41862deeca185f784b96a0bc44de21f0436306
Arg [2] : 000000000000000000000000834ebe76d6e0331fe86071963cad42c98199fc7c
Arg [3] : 0000000000000000000000001171b858777120a59a6cc8148edda8982f187cd8
Arg [4] : 00000000000000000000000021a93be569666527dae0fdbfbe7715299dec1202


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.