ETH Price: $2,002.66 (+0.68%)

Contract

0x5A784fE7cf88edadeE2eb2dB33EA90653300Cc46
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Start Bounty134433652021-10-18 18:20:421622 days ago1634581242IN
0x5A784fE7...53300Cc46
0 ETH0.02718742101.4339004
Start Bounty134210562021-10-15 6:34:441625 days ago1634279684IN
0x5A784fE7...53300Cc46
0 ETH0.03068451116.29970266
Start Bounty134196822021-10-15 1:14:571626 days ago1634260497IN
0x5A784fE7...53300Cc46
0 ETH0.02729558103.60311012

Latest 4 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
-134433652021-10-18 18:20:421622 days ago1634581242
0x5A784fE7...53300Cc46
 Contract Creation0 ETH
-134210562021-10-15 6:34:441625 days ago1634279684
0x5A784fE7...53300Cc46
 Contract Creation0 ETH
-134196822021-10-15 1:14:571626 days ago1634260497
0x5A784fE7...53300Cc46
 Contract Creation0 ETH
-134196592021-10-15 1:10:381626 days ago1634260238
0x5A784fE7...53300Cc46
 Contract Creation0 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BountyFactory

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

import {Bounty} from "./Bounty.sol";
import {IERC721VaultFactory} from "./external/interfaces/IERC721VaultFactory.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";

contract BountyFactory is ReentrancyGuard {
    event BountyDeployed(
        address indexed addressDeployed,
        address indexed creator,
        address nftContract,
        uint256 nftTokenID,
        string name,
        string symbol,
        uint256 contributionCap,
        bool indexed isPrivate
    );

    address public immutable logic;

    constructor(
        address _gov,
        IERC721VaultFactory _tokenVaultFactory,
        IERC721 _logicNftContract,
        uint256 _logicTokenID
    ) {
        Bounty _bounty = new Bounty(_gov, _tokenVaultFactory);
        // initialize as expired bounty
        _bounty.initialize(
            _logicNftContract,
            _logicTokenID,
            "BOUNTY",
            "BOUNTY",
            0, // contribution cap
            0 // duration (expired right away)
        );
        logic = address(_bounty);
    }

    function startBounty(
        IERC721 _nftContract,
        uint256 _nftTokenID,
        string memory _name,
        string memory _symbol,
        uint256 _contributionCap,
        uint256 _duration,
        bool _isPrivate
    ) external nonReentrant returns (address bountyAddress) {
        bountyAddress = Clones.clone(logic);
        Bounty(bountyAddress).initialize(
            _nftContract,
            _nftTokenID,
            _name,
            _symbol,
            _contributionCap,
            _duration
        );
        emit BountyDeployed(
            bountyAddress,
            msg.sender,
            address(_nftContract),
            _nftTokenID,
            _name,
            _symbol,
            _contributionCap,
            _isPrivate
        );
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/utils/ERC721HolderUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "./external/interfaces/IERC721VaultFactory.sol";
import "./external/interfaces/ITokenVault.sol";

interface IBounty {
    function redeemBounty(
        IBountyRedeemer redeemer,
        uint256 amount,
        bytes calldata data
    ) external;
}

interface IBountyRedeemer {
    function onRedeemBounty(address initiator, bytes calldata data)
        external
        payable
        returns (bytes32);
}

// @notice Bounty isn't upgradeable, but because it is deploys as a
// static proxy, needs to extend upgradeable contracts.
contract Bounty is
    ReentrancyGuardUpgradeable,
    ERC721HolderUpgradeable,
    IBounty
{
    using Counters for Counters.Counter;

    enum BountyStatus {
        ACTIVE,
        ACQUIRED,
        EXPIRED
    }

    struct Contribution {
        uint256 priorTotalContributed;
        uint256 amount;
    }

    // tokens are minted at a rate of 1 ETH : 1000 tokens
    uint16 internal constant TOKEN_SCALE = 1000;
    uint8 internal constant RESALE_MULTIPLIER = 2;

    // immutable (across clones)
    address public immutable gov;
    IERC721VaultFactory public immutable tokenVaultFactory;

    // immutable (at clone level)
    IERC721 public nftContract;
    uint256 public nftTokenID;
    string public name;
    string public symbol;
    uint256 public contributionCap;
    uint256 public expiryTimestamp;

    // mutables
    mapping(address => Contribution[]) public contributions;
    mapping(address => uint256) public totalContributedByAddress;
    mapping(address => bool) public claimed;
    uint256 public totalContributed;
    uint256 public totalSpent;
    ITokenVault public tokenVault;
    Counters.Counter public contributors;

    event Contributed(address indexed contributor, uint256 amount);

    event Acquired(uint256 amount);

    event Claimed(
        address indexed contributor,
        uint256 tokenAmount,
        uint256 ethAmount
    );

    modifier onlyGov() {
        require(msg.sender == gov, "Bounty:: only callable by gov");
        _;
    }

    constructor(address _gov, IERC721VaultFactory _tokenVaultFactory) {
        gov = _gov;
        tokenVaultFactory = _tokenVaultFactory;
    }

    function initialize(
        IERC721 _nftContract,
        uint256 _nftTokenID,
        string memory _name,
        string memory _symbol,
        uint256 _contributionCap,
        uint256 _duration
    ) external initializer {
        __ReentrancyGuard_init();
        __ERC721Holder_init();

        nftContract = _nftContract;
        nftTokenID = _nftTokenID;
        name = _name;
        symbol = _symbol;
        contributionCap = _contributionCap;
        expiryTimestamp = block.timestamp + _duration;

        require(
            IERC721(nftContract).ownerOf(nftTokenID) != address(0),
            "Bounty::initialize: Token does not exist"
        );
    }

    // @notice contribute (via msg.value) to active bounty as long as the contribution cap has not been reached
    function contribute() external payable nonReentrant {
        require(
            status() == BountyStatus.ACTIVE,
            "Bounty::contribute: bounty not active"
        );
        address _contributor = msg.sender;
        uint256 _amount = msg.value;
        require(_amount > 0, "Bounty::contribute: must contribute more than 0");
        require(
            contributionCap == 0 || totalContributed < contributionCap,
            "Bounty::contribute: at max contributions"
        );

        if (contributions[_contributor].length == 0) {
            contributors.increment();
        }

        Contribution memory _contribution = Contribution({
            amount: _amount,
            priorTotalContributed: totalContributed
        });
        contributions[_contributor].push(_contribution);
        totalContributedByAddress[_contributor] =
            totalContributedByAddress[_contributor] +
            _amount;
        totalContributed = totalContributed + _amount;
        emit Contributed(_contributor, _amount);
    }

    // @notice uses the redeemer to swap `_amount` ETH for the NFT
    // @param _redeemer The callback to acquire the NFT
    // @param _amount The amount of the bounty to redeem. Must be <= MIN(totalContributed, contributionCap)
    // @param _data Arbitrary calldata for the callback
    function redeemBounty(
        IBountyRedeemer _redeemer,
        uint256 _amount,
        bytes calldata _data
    ) external override nonReentrant {
        require(
            status() == BountyStatus.ACTIVE,
            "Bounty::redeemBounty: bounty isn't active"
        );
        require(totalSpent == 0, "Bounty::redeemBounty: already acquired");
        require(_amount > 0, "Bounty::redeemBounty: cannot redeem for free");
        require(
            _amount <= totalContributed && _amount <= contributionCap,
            "Bounty::redeemBounty: not enough funds"
        );
        totalSpent = _amount;
        require(
            _redeemer.onRedeemBounty{value: _amount}(msg.sender, _data) ==
                keccak256("IBountyRedeemer.onRedeemBounty"),
            "Bounty::redeemBounty: callback failed"
        );
        require(
            IERC721(nftContract).ownerOf(nftTokenID) == address(this),
            "Bounty::redeemBounty: NFT not delivered"
        );
        emit Acquired(_amount);
    }

    // @notice Kicks off fractionalization once the NFT is acquired
    // @dev Also triggered by the first claim()
    function fractionalize() external nonReentrant {
        require(
            status() == BountyStatus.ACQUIRED,
            "Bounty::fractionalize: NFT not yet acquired"
        );
        _fractionalizeNFTIfNeeded();
    }

    // @notice Claims any tokens or eth for `_contributor` from active or expired bounties
    // @dev msg.sender does not necessarily match `_contributor`
    // @dev O(N) where N = number of contributions by `_contributor`
    // @param _contributor The address of the contributor to claim tokens for
    function claim(address _contributor) external nonReentrant {
        BountyStatus _status = status();
        require(
            _status != BountyStatus.ACTIVE,
            "Bounty::claim: bounty still active"
        );
        require(
            totalContributedByAddress[_contributor] != 0,
            "Bounty::claim: not a contributor"
        );
        require(
            !claimed[_contributor],
            "Bounty::claim: bounty already claimed"
        );
        claimed[_contributor] = true;

        if (_status == BountyStatus.ACQUIRED) {
            _fractionalizeNFTIfNeeded();
        }

        (uint256 _tokenAmount, uint256 _ethAmount) = claimAmounts(_contributor);

        if (_ethAmount > 0) {
            _transferETH(_contributor, _ethAmount);
        }
        if (_tokenAmount > 0) {
            _transferTokens(_contributor, _tokenAmount);
        }
        emit Claimed(_contributor, _tokenAmount, _ethAmount);
    }

    // @notice (GOV ONLY) emergency: withdraw stuck ETH
    function emergencyWithdrawETH(uint256 _value) external onlyGov {
        _transferETH(gov, _value);
    }

    // @notice (GOV ONLY) emergency: execute arbitrary calls from contract
    function emergencyCall(address _contract, bytes memory _calldata)
        external
        onlyGov
        returns (bool _success, bytes memory _returnData)
    {
        (_success, _returnData) = _contract.call(_calldata);
        require(_success, string(_returnData));
    }

    // @notice (GOV ONLY) emergency: immediately expires bounty
    function emergencyExpire() external onlyGov {
        expiryTimestamp = block.timestamp;
    }

    // @notice The amount of tokens and ETH that can or have been claimed by `_contributor`
    // @dev Check `claimed(address)` to see if already claimed
    // @param _contributor The address of the contributor to compute amounts for.
    function claimAmounts(address _contributor)
        public
        view
        returns (uint256 _tokenAmount, uint256 _ethAmount)
    {
        require(
            status() != BountyStatus.ACTIVE,
            "Bounty::claimAmounts: bounty still active"
        );
        if (totalSpent > 0) {
            uint256 _ethUsed = ethUsedForAcquisition(_contributor);
            if (_ethUsed > 0) {
                _tokenAmount = valueToTokens(_ethUsed);
            }
            _ethAmount = totalContributedByAddress[_contributor] - _ethUsed;
        } else {
            _ethAmount = totalContributedByAddress[_contributor];
        }
    }

    // @notice The amount of the contributor's ETH used to acquire the NFT
    // @notice Tokens owed will be proportional to eth used.
    // @notice ETH contributed = ETH used in acq + ETH left to be claimed
    // @param _contributor The address of the contributor to compute eth usd
    function ethUsedForAcquisition(address _contributor)
        public
        view
        returns (uint256 _total)
    {
        require(
            totalSpent > 0,
            "Bounty::ethUsedForAcquisition: NFT not acquired yet"
        );
        // load from storage once and reuse
        uint256 _totalSpent = totalSpent;
        Contribution[] memory _contributions = contributions[_contributor];
        for (uint256 _i = 0; _i < _contributions.length; _i++) {
            Contribution memory _contribution = _contributions[_i];
            if (
                _contribution.priorTotalContributed + _contribution.amount <=
                _totalSpent
            ) {
                _total = _total + _contribution.amount;
            } else if (_contribution.priorTotalContributed < _totalSpent) {
                uint256 _amountUsed = _totalSpent -
                    _contribution.priorTotalContributed;
                _total = _total + _amountUsed;
                break;
            } else {
                break;
            }
        }
    }

    // @notice Computes the status of the bounty
    // Valid state transitions:
    // EXPIRED
    // ACTIVE -> EXPIRED
    // ACTIVE -> ACQUIRED
    function status() public view returns (BountyStatus) {
        if (totalSpent > 0) {
            return BountyStatus.ACQUIRED;
        } else if (block.timestamp >= expiryTimestamp) {
            return BountyStatus.EXPIRED;
        } else {
            return BountyStatus.ACTIVE;
        }
    }

    // @dev Helper function for translating ETH contributions into token amounts
    function valueToTokens(uint256 _value)
        public
        pure
        returns (uint256 _tokens)
    {
        _tokens = _value * TOKEN_SCALE;
    }

    function _transferETH(address _to, uint256 _value) internal {
        // guard against rounding errors
        uint256 _balance = address(this).balance;
        if (_value > _balance) {
            _value = _balance;
        }
        payable(_to).transfer(_value);
    }

    function _transferTokens(address _to, uint256 _value) internal {
        // guard against rounding errors
        uint256 _balance = tokenVault.balanceOf(address(this));
        if (_value > _balance) {
            _value = _balance;
        }
        tokenVault.transfer(_to, _value);
    }

    function _fractionalizeNFTIfNeeded() internal {
        if (address(tokenVault) != address(0)) {
            return;
        }
        IERC721(nftContract).approve(address(tokenVaultFactory), nftTokenID);
        uint256 _vaultNumber = tokenVaultFactory.mint(
            name,
            symbol,
            address(nftContract),
            nftTokenID,
            valueToTokens(totalSpent),
            totalSpent * RESALE_MULTIPLIER,
            0 // fees
        );
        tokenVault = ITokenVault(tokenVaultFactory.vaults(_vaultNumber));
        tokenVault.updateCurator(address(0));
    }
}

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

interface IERC721VaultFactory {
    /// @notice the mapping of vault number to vault address
    function vaults(uint256) external returns (address);

    /// @notice the function to mint a new vault
    /// @param _name the desired name of the vault
    /// @param _symbol the desired sumbol of the vault
    /// @param _token the ERC721 token address fo the NFT
    /// @param _id the uint256 ID of the token
    /// @param _listPrice the initial price of the NFT
    /// @return the ID of the vault
    function mint(
        string memory _name,
        string memory _symbol,
        address _token,
        uint256 _id,
        uint256 _supply,
        uint256 _listPrice,
        uint256 _fee
    ) external returns (uint256);
}

File 4 of 13 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 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`, checking first that contract recipients
     * are aware of the ERC721 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 be 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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * 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 Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @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 caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @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);

    /**
     * @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;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 *
 * _Available since v3.4._
 */
library Clones {
    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create(0, ptr, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create2(0, ptr, 0x37, salt)
        }
        require(instance != address(0), "ERC1167: create2 failed");
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
            mstore(add(ptr, 0x38), shl(0x60, deployer))
            mstore(add(ptr, 0x4c), salt)
            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
            predicted := keccak256(add(ptr, 0x37), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(address implementation, bytes32 salt)
        internal
        view
        returns (address predicted)
    {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721ReceiverUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";

/**
 * @dev Implementation of the {IERC721Receiver} interface.
 *
 * Accepts all token transfers.
 * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
 */
contract ERC721HolderUpgradeable is Initializable, IERC721ReceiverUpgradeable {
    function __ERC721Holder_init() internal initializer {
        __ERC721Holder_init_unchained();
    }

    function __ERC721Holder_init_unchained() internal initializer {
    }
    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     *
     * Always returns `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address,
        address,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }
    uint256[50] private __gap;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuardUpgradeable is Initializable {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    function __ReentrancyGuard_init() internal initializer {
        __ReentrancyGuard_init_unchained();
    }

    function __ReentrancyGuard_init_unchained() internal initializer {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
    uint256[49] private __gap;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

interface ITokenVault {
    /// @notice allow curator to update the curator address
    /// @param _curator the new curator
    function updateCurator(address _curator) external;

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount)
        external
        returns (bool);

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) external view returns (uint256);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * 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[EIP 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);
}

File 12 of 13 : IERC721ReceiverUpgradeable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721ReceiverUpgradeable {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 13 of 13 : Initializable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_gov","type":"address"},{"internalType":"contract IERC721VaultFactory","name":"_tokenVaultFactory","type":"address"},{"internalType":"contract IERC721","name":"_logicNftContract","type":"address"},{"internalType":"uint256","name":"_logicTokenID","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addressDeployed","type":"address"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"address","name":"nftContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"nftTokenID","type":"uint256"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"contributionCap","type":"uint256"},{"indexed":true,"internalType":"bool","name":"isPrivate","type":"bool"}],"name":"BountyDeployed","type":"event"},{"inputs":[],"name":"logic","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"_nftContract","type":"address"},{"internalType":"uint256","name":"_nftTokenID","type":"uint256"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_contributionCap","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"bool","name":"_isPrivate","type":"bool"}],"name":"startBounty","outputs":[{"internalType":"address","name":"bountyAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"}]

60a060405234801561001057600080fd5b50604051612f9f380380612f9f83398101604081905261002f9161014f565b60016000819055506000848460405161004790610142565b6001600160a01b03928316815291166020820152604001604051809103906000f08015801561007a573d6000803e3d6000fd5b5060405163e8d81ae560e01b81526001600160a01b0385811660048301526024820185905260c06044830152600660c4830181905265424f554e545960d01b60e48401819052610100606485015261010484019190915261012483015260006084830181905260a48301529192509082169063e8d81ae59061014401600060405180830381600087803b15801561011057600080fd5b505af1158015610124573d6000803e3d6000fd5b5050505060601b6001600160601b031916608052506101b992505050565b61287d8061072283390190565b60008060008060808587031215610164578384fd5b845161016f816101a1565b6020860151909450610180816101a1565b6040860151909350610191816101a1565b6060959095015193969295505050565b6001600160a01b03811681146101b657600080fd5b50565b60805160601c6105466101dc60003960008181606f015260f501526105466000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80634fba6e5d1461003b578063d7dfa0dd1461006a575b600080fd5b61004e610049366004610345565b610091565b6040516001600160a01b03909116815260200160405180910390f35b61004e7f000000000000000000000000000000000000000000000000000000000000000081565b6000600260005414156100eb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000556101197f0000000000000000000000000000000000000000000000000000000000000000610203565b6040517fe8d81ae50000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063e8d81ae59061016b908b908b908b908b908b908b90600401610491565b600060405180830381600087803b15801561018557600080fd5b505af1158015610199573d6000803e3d6000fd5b50505050811515336001600160a01b0316826001600160a01b03167f2eaa563602a478ea4d156f82ad059aa0dfed6de1b5693ba6f8a42ef886fea4278b8b8b8b8b6040516101eb959493929190610444565b60405180910390a46001600055979650505050505050565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f09150506001600160a01b0381166102b95760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c65640000000000000000000060448201526064016100e2565b919050565b600082601f8301126102ce578081fd5b813567ffffffffffffffff808211156102e9576102e96104e1565b604051601f8301601f19908116603f01168101908282118183101715610311576103116104e1565b81604052838152866020858801011115610329578485fd5b8360208701602083013792830160200193909352509392505050565b600080600080600080600060e0888a03121561035f578283fd5b87356001600160a01b0381168114610375578384fd5b965060208801359550604088013567ffffffffffffffff80821115610398578485fd5b6103a48b838c016102be565b965060608a01359150808211156103b9578485fd5b506103c68a828b016102be565b9450506080880135925060a0880135915060c088013580151581146103e9578182fd5b8091505092959891949750929550565b60008151808452815b8181101561041e57602081850181015186830182015201610402565b8181111561042f5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038616815284602082015260a06040820152600061046c60a08301866103f9565b828103606084015261047e81866103f9565b9150508260808301529695505050505050565b6001600160a01b038716815285602082015260c0604082015260006104b960c08301876103f9565b82810360608401526104cb81876103f9565b6080840195909552505060a00152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea2646970667358221220eff7c0a9459ea6dbf50253632b0d431d53ec93482e7b2e283663e0df40c20ace64736f6c6343000804003360c06040523480156200001157600080fd5b506040516200287d3803806200287d833981016040819052620000349162000053565b6001600160601b0319606092831b8116608052911b1660a052620000aa565b6000806040838503121562000066578182fd5b8251620000738162000091565b6020840151909250620000868162000091565b809150509250929050565b6001600160a01b0381168114620000a757600080fd5b50565b60805160601c60a05160601c6127766200010760003960008181610219015281816119c501528181611a350152611b4101526000818161026501528181610987015281816109f90152818161103401526110b601526127766000f3fe6080604052600436106101b75760003560e01c806395d89b41116100ec578063d56d229d1161008a578063ded7127d11610064578063ded7127d14610543578063e8d81ae514610570578063ecbb618414610590578063fb346eab146105b057600080fd5b8063d56d229d14610506578063d7bb99ba14610526578063d8625c5f1461052e57600080fd5b8063ade6e2aa116100c6578063ade6e2aa1461046d578063b1de7ca314610483578063c4bf022014610498578063c884ef83146104c657600080fd5b806395d89b41146104225780639744b8dc14610437578063ace1b44d1461045757600080fd5b8063550b521c116101595780636d4d226e116101335780636d4d226e146103b55780636e7e3b2b146103d5578063944890d6146103ec57806395816a161461040c57600080fd5b8063550b521c146103405780635bc789d9146103755780636b792c4b1461039557600080fd5b806312d43a511161019557806312d43a5114610253578063150b7a02146102875780631e83409a146102fc578063200d2ed21461031e57600080fd5b8063023f4147146101bc57806306fdde03146101e55780630b20302314610207575b600080fd5b3480156101c857600080fd5b506101d2606e5481565b6040519081526020015b60405180910390f35b3480156101f157600080fd5b506101fa6105c6565b6040516101dc91906125c3565b34801561021357600080fd5b5061023b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101dc565b34801561025f57600080fd5b5061023b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561029357600080fd5b506102cb6102a236600461220d565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101dc565b34801561030857600080fd5b5061031c6103173660046121ce565b610654565b005b34801561032a57600080fd5b5061033361091a565b6040516101dc919061259b565b34801561034c57600080fd5b5061036061035b3660046122c5565b610940565b604080519283526020830191909152016101dc565b34801561038157600080fd5b5060705461023b906001600160a01b031681565b3480156103a157600080fd5b5061031c6103b036600461243b565b61097c565b3480156103c157600080fd5b506103606103d03660046121ce565b610a21565b3480156103e157600080fd5b506071546101d29081565b3480156103f857600080fd5b5061031c610407366004612328565b610b32565b34801561041857600080fd5b506101d260695481565b34801561042e57600080fd5b506101fa611008565b34801561044357600080fd5b506101d261045236600461243b565b611015565b34801561046357600080fd5b506101d260665481565b34801561047957600080fd5b506101d2606a5481565b34801561048f57600080fd5b5061031c611029565b3480156104a457600080fd5b506104b86104b3366004612277565b6110a7565b6040516101dc929190612578565b3480156104d257600080fd5b506104f66104e13660046121ce565b606d6020526000908152604090205460ff1681565b60405190151581526020016101dc565b34801561051257600080fd5b5060655461023b906001600160a01b031681565b61031c6111aa565b34801561053a57600080fd5b5061031c611498565b34801561054f57600080fd5b506101d261055e3660046121ce565b606c6020526000908152604090205481565b34801561057c57600080fd5b5061031c61058b3660046123ac565b61159a565b34801561059c57600080fd5b506101d26105ab3660046121ce565b6117c8565b3480156105bc57600080fd5b506101d2606f5481565b606780546105d3906126a9565b80601f01602080910402602001604051908101604052809291908181526020018280546105ff906126a9565b801561064c5780601f106106215761010080835404028352916020019161064c565b820191906000526020600020905b81548152906001019060200180831161062f57829003601f168201915b505050505081565b600260015414156106ac5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260015560006106bb61091a565b905060008160028111156106df57634e487b7160e01b600052602160045260246000fd5b14156107535760405162461bcd60e51b815260206004820152602260248201527f426f756e74793a3a636c61696d3a20626f756e7479207374696c6c206163746960448201527f766500000000000000000000000000000000000000000000000000000000000060648201526084016106a3565b6001600160a01b0382166000908152606c60205260409020546107b85760405162461bcd60e51b815260206004820181905260248201527f426f756e74793a3a636c61696d3a206e6f74206120636f6e7472696275746f7260448201526064016106a3565b6001600160a01b0382166000908152606d602052604090205460ff16156108475760405162461bcd60e51b815260206004820152602560248201527f426f756e74793a3a636c61696d3a20626f756e747920616c726561647920636c60448201527f61696d656400000000000000000000000000000000000000000000000000000060648201526084016106a3565b6001600160a01b0382166000908152606d60205260409020805460ff1916600190811790915581600281111561088d57634e487b7160e01b600052602160045260246000fd5b141561089b5761089b61197c565b6000806108a784610a21565b909250905080156108bc576108bc8482611c5c565b81156108cc576108cc8483611ca5565b60408051838152602081018390526001600160a01b038616917f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a910160405180910390a25050600180555050565b606f546000901561092b5750600190565b606a54421061093a5750600290565b50600090565b606b602052816000526040600020818154811061095c57600080fd5b600091825260209091206002909102018054600190910154909250905082565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109f45760405162461bcd60e51b815260206004820152601d60248201527f426f756e74793a3a206f6e6c792063616c6c61626c6520627920676f7600000060448201526064016106a3565b610a1e7f000000000000000000000000000000000000000000000000000000000000000082611c5c565b50565b60008080610a2d61091a565b6002811115610a4c57634e487b7160e01b600052602160045260246000fd5b1415610ac05760405162461bcd60e51b815260206004820152602960248201527f426f756e74793a3a636c61696d416d6f756e74733a20626f756e74792073746960448201527f6c6c20616374697665000000000000000000000000000000000000000000000060648201526084016106a3565b606f5415610b13576000610ad3846117c8565b90508015610ae757610ae481611015565b92505b6001600160a01b0384166000908152606c6020526040902054610b0b908290612666565b915050915091565b506001600160a01b0382166000908152606c6020526040902054915091565b60026001541415610b855760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106a3565b60026001556000610b9461091a565b6002811115610bb357634e487b7160e01b600052602160045260246000fd5b14610c265760405162461bcd60e51b815260206004820152602960248201527f426f756e74793a3a72656465656d426f756e74793a20626f756e74792069736e60448201527f277420616374697665000000000000000000000000000000000000000000000060648201526084016106a3565b606f5415610c9c5760405162461bcd60e51b815260206004820152602660248201527f426f756e74793a3a72656465656d426f756e74793a20616c726561647920616360448201527f717569726564000000000000000000000000000000000000000000000000000060648201526084016106a3565b60008311610d125760405162461bcd60e51b815260206004820152602c60248201527f426f756e74793a3a72656465656d426f756e74793a2063616e6e6f742072656460448201527f65656d20666f722066726565000000000000000000000000000000000000000060648201526084016106a3565b606e548311158015610d2657506069548311155b610d985760405162461bcd60e51b815260206004820152602660248201527f426f756e74793a3a72656465656d426f756e74793a206e6f7420656e6f75676860448201527f2066756e6473000000000000000000000000000000000000000000000000000060648201526084016106a3565b606f8390556040517f0122f3ae0000000000000000000000000000000000000000000000000000000081527fff5a4f39beb7278e7ec3966df924a21fbea2926668bafa5ef7e648192758cf21906001600160a01b03861690630122f3ae908690610e0a90339088908890600401612539565b6020604051808303818588803b158015610e2357600080fd5b505af1158015610e37573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610e5c9190612310565b14610ecf5760405162461bcd60e51b815260206004820152602560248201527f426f756e74793a3a72656465656d426f756e74793a2063616c6c6261636b206660448201527f61696c656400000000000000000000000000000000000000000000000000000060648201526084016106a3565b6065546066546040516331a9108f60e11b8152600481019190915230916001600160a01b031690636352211e9060240160206040518083038186803b158015610f1757600080fd5b505afa158015610f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f4f91906121f1565b6001600160a01b031614610fcb5760405162461bcd60e51b815260206004820152602760248201527f426f756e74793a3a72656465656d426f756e74793a204e4654206e6f7420646560448201527f6c6976657265640000000000000000000000000000000000000000000000000060648201526084016106a3565b6040518381527f6d71a7963fc48a9b74e4978a00425896809beef0d90ee51a1b5f3b25c76e3e8c9060200160405180910390a15050600180555050565b606880546105d3906126a9565b60006110236103e883612647565b92915050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146110a15760405162461bcd60e51b815260206004820152601d60248201527f426f756e74793a3a206f6e6c792063616c6c61626c6520627920676f7600000060448201526064016106a3565b42606a55565b60006060336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111235760405162461bcd60e51b815260206004820152601d60248201527f426f756e74793a3a206f6e6c792063616c6c61626c6520627920676f7600000060448201526064016106a3565b836001600160a01b03168360405161113b919061251d565b6000604051808303816000865af19150503d8060008114611178576040519150601f19603f3d011682016040523d82523d6000602084013e61117d565b606091505b50909250905080826111a25760405162461bcd60e51b81526004016106a391906125c3565b509250929050565b600260015414156111fd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106a3565b6002600155600061120c61091a565b600281111561122b57634e487b7160e01b600052602160045260246000fd5b1461129e5760405162461bcd60e51b815260206004820152602560248201527f426f756e74793a3a636f6e747269627574653a20626f756e7479206e6f74206160448201527f637469766500000000000000000000000000000000000000000000000000000060648201526084016106a3565b3334806113135760405162461bcd60e51b815260206004820152602f60248201527f426f756e74793a3a636f6e747269627574653a206d75737420636f6e7472696260448201527f757465206d6f7265207468616e2030000000000000000000000000000000000060648201526084016106a3565b60695415806113255750606954606e54105b6113975760405162461bcd60e51b815260206004820152602860248201527f426f756e74793a3a636f6e747269627574653a206174206d617820636f6e747260448201527f69627574696f6e7300000000000000000000000000000000000000000000000060648201526084016106a3565b6001600160a01b0382166000908152606b60205260409020546113c2576113c2607180546001019055565b604080518082018252606e54815260208082018481526001600160a01b0386166000818152606b8452858120805460018181018355918352858320875160029092020190815593519301929092558152606c909152919091205461142790839061262f565b6001600160a01b0384166000908152606c6020526040902055606e5461144e90839061262f565b606e556040518281526001600160a01b038416907f62722348256371b5147820d6cad90c40fd2da1ccee18c3ed52c0bca5a61dbbab9060200160405180910390a250506001805550565b600260015414156114eb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106a3565b600260019081556114fa61091a565b600281111561151957634e487b7160e01b600052602160045260246000fd5b1461158c5760405162461bcd60e51b815260206004820152602b60248201527f426f756e74793a3a6672616374696f6e616c697a653a204e4654206e6f74207960448201527f657420616371756972656400000000000000000000000000000000000000000060648201526084016106a3565b61159461197c565b60018055565b600054610100900460ff16806115b3575060005460ff16155b6116165760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a3565b600054610100900460ff16158015611638576000805461ffff19166101011790555b611640611de7565b611648611ea1565b6065805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038916179055606686905584516116889060679060208801906120ae565b50835161169c9060689060208701906120ae565b5060698390556116ac824261262f565b606a556065546066546040516331a9108f60e11b815260048101919091526000916001600160a01b031690636352211e9060240160206040518083038186803b1580156116f857600080fd5b505afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173091906121f1565b6001600160a01b031614156117ad5760405162461bcd60e51b815260206004820152602860248201527f426f756e74793a3a696e697469616c697a653a20546f6b656e20646f6573206e60448201527f6f7420657869737400000000000000000000000000000000000000000000000060648201526084016106a3565b80156117bf576000805461ff00191690555b50505050505050565b600080606f54116118415760405162461bcd60e51b815260206004820152603360248201527f426f756e74793a3a65746855736564466f724163717569736974696f6e3a204e60448201527f4654206e6f74206163717569726564207965740000000000000000000000000060648201526084016106a3565b606f546001600160a01b0383166000908152606b6020908152604080832080548251818502810185019093528083529192909190849084015b828210156118c05783829060005260206000209060020201604051806040016040529081600082015481526020016001820154815250508152602001906001019061187a565b50505050905060005b81518110156119745760008282815181106118f457634e487b7160e01b600052603260045260246000fd5b602002602001015190508381602001518260000151611913919061262f565b1161192e576020810151611927908661262f565b9450611961565b805184111561195b5780516000906119469086612666565b9050611952818761262f565b95505050611974565b50611974565b508061196c816126e4565b9150506118c9565b505050919050565b6070546001600160a01b03161561198f57565b6065546066546040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482019290925291169063095ea7b390604401600060405180830381600087803b158015611a1957600080fd5b505af1158015611a2d573d6000803e3d6000fd5b5050505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bdc0111060676068606560009054906101000a90046001600160a01b0316606654611a8a606f54611015565b606f54611a9990600290612647565b60006040518863ffffffff1660e01b8152600401611abd97969594939291906125d6565b602060405180830381600087803b158015611ad757600080fd5b505af1158015611aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0f9190612310565b6040517f8c64ea4a000000000000000000000000000000000000000000000000000000008152600481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638c64ea4a90602401602060405180830381600087803b158015611b8d57600080fd5b505af1158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc591906121f1565b6070805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039290921691821790556040517f0c6a62dd00000000000000000000000000000000000000000000000000000000815260006004820152630c6a62dd90602401600060405180830381600087803b158015611c4157600080fd5b505af1158015611c55573d6000803e3d6000fd5b5050505050565b4780821115611c69578091505b6040516001600160a01b0384169083156108fc029084906000818181858888f19350505050158015611c9f573d6000803e3d6000fd5b50505050565b6070546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015611d0257600080fd5b505afa158015611d16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3a9190612310565b905080821115611d48578091505b6070546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152602482018590529091169063a9059cbb90604401602060405180830381600087803b158015611daf57600080fd5b505af1158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9f91906122f0565b600054610100900460ff1680611e00575060005460ff16155b611e635760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a3565b600054610100900460ff16158015611e85576000805461ffff19166101011790555b611e8d611f47565b8015610a1e576000805461ff001916905550565b600054610100900460ff1680611eba575060005460ff16155b611f1d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a3565b600054610100900460ff16158015611f3f576000805461ffff19166101011790555b611e8d611ffd565b600054610100900460ff1680611f60575060005460ff16155b611fc35760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a3565b600054610100900460ff16158015611fe5576000805461ffff19166101011790555b600180558015610a1e576000805461ff001916905550565b600054610100900460ff1680612016575060005460ff16155b6120795760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a3565b600054610100900460ff16158015611e8d576000805461ffff19166101011790558015610a1e576000805461ff001916905550565b8280546120ba906126a9565b90600052602060002090601f0160209004810192826120dc5760008555612122565b82601f106120f557805160ff1916838001178555612122565b82800160010185558215612122579182015b82811115612122578251825591602001919060010190612107565b5061212e929150612132565b5090565b5b8082111561212e5760008155600101612133565b600082601f830112612157578081fd5b813567ffffffffffffffff8082111561217257612172612715565b604051601f8301601f19908116603f0116810190828211818310171561219a5761219a612715565b816040528381528660208588010111156121b2578485fd5b8360208701602083013792830160200193909352509392505050565b6000602082840312156121df578081fd5b81356121ea8161272b565b9392505050565b600060208284031215612202578081fd5b81516121ea8161272b565b60008060008060808587031215612222578283fd5b843561222d8161272b565b9350602085013561223d8161272b565b925060408501359150606085013567ffffffffffffffff81111561225f578182fd5b61226b87828801612147565b91505092959194509250565b60008060408385031215612289578182fd5b82356122948161272b565b9150602083013567ffffffffffffffff8111156122af578182fd5b6122bb85828601612147565b9150509250929050565b600080604083850312156122d7578182fd5b82356122e28161272b565b946020939093013593505050565b600060208284031215612301578081fd5b815180151581146121ea578182fd5b600060208284031215612321578081fd5b5051919050565b6000806000806060858703121561233d578384fd5b84356123488161272b565b935060208501359250604085013567ffffffffffffffff8082111561236b578384fd5b818701915087601f83011261237e578384fd5b81358181111561238c578485fd5b88602082850101111561239d578485fd5b95989497505060200194505050565b60008060008060008060c087890312156123c4578182fd5b86356123cf8161272b565b955060208701359450604087013567ffffffffffffffff808211156123f2578384fd5b6123fe8a838b01612147565b95506060890135915080821115612413578384fd5b5061242089828a01612147565b9350506080870135915060a087013590509295509295509295565b60006020828403121561244c578081fd5b5035919050565b6000815180845261246b81602086016020860161267d565b601f01601f19169290920160200192915050565b8054600090600181811c908083168061249957607f831692505b60208084108214156124b957634e487b7160e01b86526022600452602486fd5b838852602088018280156124d457600181146124e557612510565b60ff19871682528282019750612510565b60008981526020902060005b8781101561250a578154848201529086019084016124f1565b83019850505b5050505050505092915050565b6000825161252f81846020870161267d565b9190910192915050565b6001600160a01b038416815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b82151581526040602082015260006125936040830184612453565b949350505050565b60208101600383106125bd57634e487b7160e01b600052602160045260246000fd5b91905290565b6020815260006121ea6020830184612453565b60e0815260006125e960e083018a61247f565b82810360208401526125fb818a61247f565b6001600160a01b0398909816604084015250506060810194909452608084019290925260a083015260c09091015292915050565b60008219821115612642576126426126ff565b500190565b6000816000190483118215151615612661576126616126ff565b500290565b600082821015612678576126786126ff565b500390565b60005b83811015612698578181015183820152602001612680565b83811115611c9f5750506000910152565b600181811c908216806126bd57607f821691505b602082108114156126de57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156126f8576126f86126ff565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610a1e57600080fdfea2646970667358221220924b1a851af8210ea9a0385d64bd434a844e763b8049f98960d2c4b8cd6f463964736f6c6343000804003300000000000000000000000041005bf80f28dd6c587a7b3df450e8010c134b9f00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc63000000000000000000000000059edd72cd353df5106d2b9cc5ab83a52287ac3a0000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100365760003560e01c80634fba6e5d1461003b578063d7dfa0dd1461006a575b600080fd5b61004e610049366004610345565b610091565b6040516001600160a01b03909116815260200160405180910390f35b61004e7f000000000000000000000000f11a7d743a928859b06b273e6f37b56652178ef981565b6000600260005414156100eb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000556101197f000000000000000000000000f11a7d743a928859b06b273e6f37b56652178ef9610203565b6040517fe8d81ae50000000000000000000000000000000000000000000000000000000081529091506001600160a01b0382169063e8d81ae59061016b908b908b908b908b908b908b90600401610491565b600060405180830381600087803b15801561018557600080fd5b505af1158015610199573d6000803e3d6000fd5b50505050811515336001600160a01b0316826001600160a01b03167f2eaa563602a478ea4d156f82ad059aa0dfed6de1b5693ba6f8a42ef886fea4278b8b8b8b8b6040516101eb959493929190610444565b60405180910390a46001600055979650505050505050565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f09150506001600160a01b0381166102b95760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c65640000000000000000000060448201526064016100e2565b919050565b600082601f8301126102ce578081fd5b813567ffffffffffffffff808211156102e9576102e96104e1565b604051601f8301601f19908116603f01168101908282118183101715610311576103116104e1565b81604052838152866020858801011115610329578485fd5b8360208701602083013792830160200193909352509392505050565b600080600080600080600060e0888a03121561035f578283fd5b87356001600160a01b0381168114610375578384fd5b965060208801359550604088013567ffffffffffffffff80821115610398578485fd5b6103a48b838c016102be565b965060608a01359150808211156103b9578485fd5b506103c68a828b016102be565b9450506080880135925060a0880135915060c088013580151581146103e9578182fd5b8091505092959891949750929550565b60008151808452815b8181101561041e57602081850181015186830182015201610402565b8181111561042f5782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038616815284602082015260a06040820152600061046c60a08301866103f9565b828103606084015261047e81866103f9565b9150508260808301529695505050505050565b6001600160a01b038716815285602082015260c0604082015260006104b960c08301876103f9565b82810360608401526104cb81876103f9565b6080840195909552505060a00152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea2646970667358221220eff7c0a9459ea6dbf50253632b0d431d53ec93482e7b2e283663e0df40c20ace64736f6c63430008040033

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

00000000000000000000000041005bf80f28dd6c587a7b3df450e8010c134b9f00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc63000000000000000000000000059edd72cd353df5106d2b9cc5ab83a52287ac3a0000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _gov (address): 0x41005BF80F28Dd6C587A7B3Df450E8010c134B9F
Arg [1] : _tokenVaultFactory (address): 0x85Aa7f78BdB2DE8F3e0c0010d99AD5853fFcfC63
Arg [2] : _logicNftContract (address): 0x059EDD72Cd353dF5106D2B9cC5ab83a52287aC3a
Arg [3] : _logicTokenID (uint256): 0

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000041005bf80f28dd6c587a7b3df450e8010c134b9f
Arg [1] : 00000000000000000000000085aa7f78bdb2de8f3e0c0010d99ad5853ffcfc63
Arg [2] : 000000000000000000000000059edd72cd353df5106d2b9cc5ab83a52287ac3a
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.