ETH Price: $2,685.05 (-1.80%)

Contract

0x501AcE132cDE599bb39A2Bf90c717a9C57c66aa4
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Migrate170199372023-04-10 19:46:47504 days ago1681156007IN
0x501AcE13...C57c66aa4
0 ETH0.0008010925.96568475
Migrate170199142023-04-10 19:42:11504 days ago1681155731IN
0x501AcE13...C57c66aa4
0 ETH0.0009693931.42076289
Migrate170199082023-04-10 19:40:59504 days ago1681155659IN
0x501AcE13...C57c66aa4
0 ETH0.0011571137.50525885
Set Paused170193502023-04-10 17:46:23504 days ago1681148783IN
0x501AcE13...C57c66aa4
0 ETH0.0013585627.72702935
Migrate170129062023-04-09 19:51:23505 days ago1681069883IN
0x501AcE13...C57c66aa4
0 ETH0.0028539729.9162321
Migrate170103572023-04-09 11:10:23505 days ago1681038623IN
0x501AcE13...C57c66aa4
0 ETH0.0021094422.09888388
Migrate170032382023-04-08 10:57:59506 days ago1680951479IN
0x501AcE13...C57c66aa4
0 ETH0.0019305520.03190348
Migrate169845972023-04-05 19:22:11509 days ago1680722531IN
0x501AcE13...C57c66aa4
0 ETH0.0032067233.27788825
Migrate169670912023-04-03 7:41:35511 days ago1680507695IN
0x501AcE13...C57c66aa4
0 ETH0.0019263820.18743344
Migrate169669542023-04-03 7:13:47512 days ago1680506027IN
0x501AcE13...C57c66aa4
0 ETH0.0019775820.51815874
Migrate169651292023-04-03 1:03:35512 days ago1680483815IN
0x501AcE13...C57c66aa4
0 ETH0.0017059517.87709922
Migrate169624862023-04-02 16:07:47512 days ago1680451667IN
0x501AcE13...C57c66aa4
0 ETH0.0023265224.13856807
Migrate169435892023-03-31 0:22:11515 days ago1680222131IN
0x501AcE13...C57c66aa4
0 ETH0.002629727.56532376
Migrate169429362023-03-30 22:09:35515 days ago1680214175IN
0x501AcE13...C57c66aa4
0 ETH0.0032956634.54035952
Migrate169330442023-03-29 12:47:23516 days ago1680094043IN
0x501AcE13...C57c66aa4
0 ETH0.002990831.32817132
Migrate169201102023-03-27 17:08:47518 days ago1679936927IN
0x501AcE13...C57c66aa4
0 ETH0.0045393247.09620748
Migrate169190852023-03-27 13:42:35518 days ago1679924555IN
0x501AcE13...C57c66aa4
0 ETH0.0033248334.49646564
Migrate169175222023-03-27 8:26:11518 days ago1679905571IN
0x501AcE13...C57c66aa4
0 ETH0.0020238121
Migrate169102472023-03-26 7:54:59519 days ago1679817299IN
0x501AcE13...C57c66aa4
0 ETH0.0014522315.22149567
Migrate169101182023-03-26 7:28:47519 days ago1679815727IN
0x501AcE13...C57c66aa4
0 ETH0.0013289813.79041739
Migrate169092742023-03-26 4:38:11520 days ago1679805491IN
0x501AcE13...C57c66aa4
0 ETH0.0012747313.22859306
Migrate169044872023-03-25 12:29:47520 days ago1679747387IN
0x501AcE13...C57c66aa4
0 ETH0.0019912720.8639482
Migrate169040992023-03-25 11:11:47520 days ago1679742707IN
0x501AcE13...C57c66aa4
0 ETH0.0016945517.58533088
Migrate169010132023-03-25 0:47:35521 days ago1679705255IN
0x501AcE13...C57c66aa4
0 ETH0.0016379816.99502629
Migrate169003372023-03-24 22:30:59521 days ago1679697059IN
0x501AcE13...C57c66aa4
0 ETH0.0022155822.99518041
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
168710632023-03-20 19:47:59525 days ago1679341679  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Migration

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 800 runs

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

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "./utils/Governable.sol";
import "./interfaces/ISGT.sol";

contract Migration is Governable, ReentrancyGuard {
    // state variables
    bool public paused;
    address immutable public token;
    bytes32 immutable public merkleRoot;
    mapping(address => bool) private _migrated;

    // modifiers
    modifier whileUnpaused() {
        require(!paused, "contract paused");
        _;
    }

    // events
    event PauseSet(bool paused);
    event Migrated(address account, uint256 value);

    constructor(address _token, bytes32 _merkleRoot, address _governance) Governable(_governance) {
        require(_token != address(0), "zero address token");
        token = _token;
        merkleRoot = _merkleRoot;
    }

    function migrate(address _account, uint256 _amount, bytes32[] memory _proof) external whileUnpaused nonReentrant {
        // check
        require(!_migrated[_account], "already migrated");
        require(_account != address(0x0), "zero address account");
        require(_amount != 0, "zero amount to migrate");

        // verify proof
        require(verify(_account, _amount, _proof), "invalid account");

        // migrate
        _migrated[_account] = true;
        ISGT(token).mint(_account, _amount);

        // emit
        emit Migrated(_account, _amount);
    }

    function migrated(address _account) public view returns (bool) {
        return _migrated[_account];
    }

    function verify(address _account, uint256 _amount, bytes32[] memory _proof) public view returns (bool) {
        return MerkleProof.verify(_proof, merkleRoot, createNode(_account, _amount));
    }

    function createNode(address _account, uint256 _amount) public pure returns (bytes32) {
        return keccak256(bytes.concat(keccak256(abi.encode(_account, _amount))));
    }

    function setPaused(bool _paused) external onlyGovernance {
        paused = _paused;
        emit PauseSet(_paused);
    }

}

File 2 of 8 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

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 making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

File 3 of 8 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

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

import "./../interfaces/utils/IGovernable.sol";

/**
 * @title Governable
 * @author solace.fi
 * @notice Enforces access control for important functions to [**governor**](/docs/protocol/governance).
 *
 * Many contracts contain functionality that should only be accessible to a privileged user. The most common access control pattern is [OpenZeppelin's `Ownable`](https://docs.openzeppelin.com/contracts/4.x/access-control#ownership-and-ownable). We instead use `Governable` with a few key differences:
   * - Transferring the governance role is a two step process. The current governance must [`setPendingGovernance(pendingGovernance_)`](#setpendinggovernance) then the new governance must [`acceptGovernance()`](#acceptgovernance). This is to safeguard against accidentally setting ownership to the wrong address and locking yourself out of your contract.
 * - `governance` is a constructor argument instead of `msg.sender`. This is especially useful when deploying contracts via a [`SingletonFactory`](./../interfaces/utils/ISingletonFactory).
 * - We use `lockGovernance()` instead of `renounceOwnership()`. `renounceOwnership()` is a prerequisite for the reinitialization bug because it sets `owner = address(0x0)`. We also use the `governanceIsLocked()` flag.
 */
contract Governable is IGovernable {

    /***************************************
    GLOBAL VARIABLES
    ***************************************/

    // Governor.
    address private _governance;

    // governance to take over.
    address private _pendingGovernance;

    bool private _locked;

    /**
     * @notice Constructs the governable contract.
     * @param governance_ The address of the [governor](/docs/protocol/governance).
     */
    constructor(address governance_) {
        require(governance_ != address(0x0), "zero address governance");
        _governance = governance_;
        _pendingGovernance = address(0x0);
        _locked = false;
    }

    /***************************************
    MODIFIERS
    ***************************************/

    // can only be called by governor
    // can only be called while unlocked
    modifier onlyGovernance() {
        require(!_locked, "governance locked");
        require(msg.sender == _governance, "!governance");
        _;
    }

    // can only be called by pending governor
    // can only be called while unlocked
    modifier onlyPendingGovernance() {
        require(!_locked, "governance locked");
        require(msg.sender == _pendingGovernance, "!pending governance");
        _;
    }

    /***************************************
    VIEW FUNCTIONS
    ***************************************/

    /// @notice Address of the current governor.
    function governance() public view override returns (address) {
        return _governance;
    }

    /// @notice Address of the governor to take over.
    function pendingGovernance() external view override returns (address) {
        return _pendingGovernance;
    }

    /// @notice Returns true if governance is locked.
    function governanceIsLocked() external view override returns (bool) {
        return _locked;
    }

    /***************************************
    MUTATOR FUNCTIONS
    ***************************************/

    /**
     * @notice Initiates transfer of the governance role to a new governor.
     * Transfer is not complete until the new governor accepts the role.
     * Can only be called by the current [**governor**](/docs/protocol/governance).
     * @param pendingGovernance_ The new governor.
     */
    function setPendingGovernance(address pendingGovernance_) external override onlyGovernance {
        _pendingGovernance = pendingGovernance_;
        emit GovernancePending(pendingGovernance_);
    }

    /**
     * @notice Accepts the governance role.
     * Can only be called by the pending governor.
     */
    function acceptGovernance() external override onlyPendingGovernance {
        // sanity check against transferring governance to the zero address
        // if someone figures out how to sign transactions from the zero address
        // consider the entirety of ethereum to be rekt
        require(_pendingGovernance != address(0x0), "zero governance");
        address oldGovernance = _governance;
        _governance = _pendingGovernance;
        _pendingGovernance = address(0x0);
        emit GovernanceTransferred(oldGovernance, _governance);
    }

    /**
     * @notice Permanently locks this contract's governance role and any of its functions that require the role.
     * This action cannot be reversed.
     * Before you call it, ask yourself:
     *   - Is the contract self-sustaining?
     *   - Is there a chance you will need governance privileges in the future?
     * Can only be called by the current [**governor**](/docs/protocol/governance).
     */
    function lockGovernance() external override onlyGovernance {
        _locked = true;
        // intentionally not using address(0x0), see re-initialization exploit
        _governance = address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF);
        _pendingGovernance = address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF);
        emit GovernanceTransferred(msg.sender, address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF));
        emit GovernanceLocked();
    }
}

File 5 of 8 : ISGT.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.6;

import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

/**
 * @title Solace Governance Token (SGT)
 * @author solace.fi
 * @notice The native governance token of the Solace Coverage Protocol.
 */
interface ISGT is IERC20Metadata {

    /***************************************
    EVENTS
    ***************************************/

    /// @notice Emitted when a minter is added.
    event MinterAdded(address indexed minter);
    /// @notice Emitted when a minter is removed.
    event MinterRemoved(address indexed minter);

    /***************************************
    MINT FUNCTIONS
    ***************************************/

    /**
     * @notice Returns true if `account` is authorized to mint [**SOLACE**](../SOLACE).
     * @param account Account to query.
     * @return status True if `account` can mint, false otherwise.
     */
    function isMinter(address account) external view returns (bool status);

    /**
     * @notice Returns true minter count.
     * @return count The number of minters.
     */
    function numOfMinters() external view returns (uint256 count);

    /**
     * @notice Returns minters.
     * @return minterAdddresses The minter addresses.
     */
    function minters() external view returns (address[] memory minterAdddresses);

    /**
     * @notice Mints new [**SOLACE**](../SOLACE) to the receiver account.
     * Can only be called by authorized minters.
     * @param account The receiver of new tokens.
     * @param amount The number of new tokens.
     */
    function mint(address account, uint256 amount) external;

    /**
     * @notice Burns [**SOLACE**](../SOLACE) from msg.sender.
     * @param amount Amount to burn.
     */
    function burn(uint256 amount) external;

    /**
     * @notice Adds a new minter.
     * Can only be called by the current [**governor**](/docs/protocol/governance).
     * @param minter The new minter.
     */
    function addMinter(address minter) external;

    /**
     * @notice Removes a minter.
     * Can only be called by the current [**governor**](/docs/protocol/governance).
     * @param minter The minter to remove.
     */
    function removeMinter(address minter) external;
}

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

/**
 * @title IGovernable
 * @author solace.fi
 * @notice Enforces access control for important functions to [**governor**](/docs/protocol/governance).
 *
 * Many contracts contain functionality that should only be accessible to a privileged user. The most common access control pattern is [OpenZeppelin's `Ownable`](https://docs.openzeppelin.com/contracts/4.x/access-control#ownership-and-ownable). We instead use `Governable` with a few key differences:
 * - Transferring the governance role is a two step process. The current governance must [`setPendingGovernance(pendingGovernance_)`](#setpendinggovernance) then the new governance must [`acceptGovernance()`](#acceptgovernance). This is to safeguard against accidentally setting ownership to the wrong address and locking yourself out of your contract.
 * - `governance` is a constructor argument instead of `msg.sender`. This is especially useful when deploying contracts via a [`SingletonFactory`](./ISingletonFactory).
 * - We use `lockGovernance()` instead of `renounceOwnership()`. `renounceOwnership()` is a prerequisite for the reinitialization bug because it sets `owner = address(0x0)`. We also use the `governanceIsLocked()` flag.
 */
interface IGovernable {

    /***************************************
    EVENTS
    ***************************************/

    /// @notice Emitted when pending Governance is set.
    event GovernancePending(address pendingGovernance);
    /// @notice Emitted when Governance is set.
    event GovernanceTransferred(address oldGovernance, address newGovernance);
    /// @notice Emitted when Governance is locked.
    event GovernanceLocked();

    /***************************************
    VIEW FUNCTIONS
    ***************************************/

    /// @notice Address of the current governor.
    function governance() external view returns (address);

    /// @notice Address of the governor to take over.
    function pendingGovernance() external view returns (address);

    /// @notice Returns true if governance is locked.
    function governanceIsLocked() external view returns (bool);

    /***************************************
    MUTATORS
    ***************************************/

    /**
     * @notice Initiates transfer of the governance role to a new governor.
     * Transfer is not complete until the new governor accepts the role.
     * Can only be called by the current [**governor**](/docs/protocol/governance).
     * @param pendingGovernance_ The new governor.
     */
    function setPendingGovernance(address pendingGovernance_) external;

    /**
     * @notice Accepts the governance role.
     * Can only be called by the new governor.
     */
    function acceptGovernance() external;

    /**
     * @notice Permanently locks this contract's governance role and any of its functions that require the role.
     * This action cannot be reversed.
     * Before you call it, ask yourself:
     *   - Is the contract self-sustaining?
     *   - Is there a chance you will need governance privileges in the future?
     * Can only be called by the current [**governor**](/docs/protocol/governance).
     */
    function lockGovernance() external;
}

File 7 of 8 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 8 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"address","name":"_governance","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"GovernanceLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingGovernance","type":"address"}],"name":"GovernancePending","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldGovernance","type":"address"},{"indexed":false,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Migrated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"PauseSet","type":"event"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"createNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceIsLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"migrated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingGovernance_","type":"address"}],"name":"setPendingGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60c060405234801561001057600080fd5b50604051610f19380380610f1983398101604081905261002f91610135565b806001600160a01b03811661008b5760405162461bcd60e51b815260206004820152601760248201527f7a65726f206164647265737320676f7665726e616e636500000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03928316179055600180546001600160a81b031916815560025583166100fd5760405162461bcd60e51b81526020600482015260126024820152713d32b9379030b2323932b9b9903a37b5b2b760711b6044820152606401610082565b5060609190911b6001600160601b03191660805260a052610171565b80516001600160a01b038116811461013057600080fd5b919050565b60008060006060848603121561014a57600080fd5b61015384610119565b92506020840151915061016860408501610119565b90509250925092565b60805160601c60a051610d726101a76000396000818161014701526105f201526000818161028101526109e60152610d726000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80635c975abb1161008c578063abbf4b1711610066578063abbf4b1714610250578063d1959f4814610258578063f39c38a01461026b578063fc0c546a1461027c57600080fd5b80635c975abb146101c85780636710837b146101d55780638be0861e1461023d57600080fd5b8063238efcbc116100c8578063238efcbc1461013a5780632eb4a7ab146101425780634ba0a5ee146101775780635aa6e675146101a357600080fd5b80630abb6035146100ef57806316c38b3c146101045780631c93022114610117575b600080fd5b6101026100fd366004610b9f565b6102a3565b005b610102610112366004610cc5565b6103a0565b600154600160a01b900460ff165b60405190151581526020015b60405180910390f35b610102610477565b6101697f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610131565b610125610185366004610b9f565b6001600160a01b031660009081526004602052604090205460ff1690565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610131565b6003546101259060ff1681565b6101696101e3366004610bba565b604080516001600160a01b038416602082015290810182905260009060600160408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905092915050565b61012561024b366004610be4565b6105ea565b61010261067d565b610102610266366004610be4565b6107e4565b6001546001600160a01b03166101b0565b6101b07f000000000000000000000000000000000000000000000000000000000000000081565b600154600160a01b900460ff16156102f65760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064015b60405180910390fd5b6000546001600160a01b0316331461033e5760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016102ed565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd61ed858909d3cb796547804c47dc1550d27455f8a0037b6b487e46212392396906020015b60405180910390a150565b600154600160a01b900460ff16156103ee5760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064016102ed565b6000546001600160a01b031633146104365760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016102ed565b6003805460ff19168215159081179091556040519081527f878ac8a2ca79520471f8f3c8494fa802c03ce3bf034252aad7f22318984fdbdb90602001610395565b600154600160a01b900460ff16156104c55760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064016102ed565b6001546001600160a01b0316331461051f5760405162461bcd60e51b815260206004820152601360248201527f2170656e64696e6720676f7665726e616e63650000000000000000000000000060448201526064016102ed565b6001546001600160a01b03166105775760405162461bcd60e51b815260206004820152600f60248201527f7a65726f20676f7665726e616e6365000000000000000000000000000000000060448201526064016102ed565b60008054600180546001600160a01b0380821673ffffffffffffffffffffffffffffffffffffffff19808616821790965594909116909155604080519190921680825260208201939093527f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce809101610395565b6000610675827f00000000000000000000000000000000000000000000000000000000000000006106708787604080516001600160a01b038416602082015290810182905260009060600160408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905092915050565b610a96565b949350505050565b600154600160a01b900460ff16156106cb5760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064016102ed565b6000546001600160a01b031633146107135760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016102ed565b60018054600080546001600160a01b0373ffffffffffffffffffffffffffffffffffffffff1990911681179091557fffffffffffffffffffffff0000000000000000000000000000000000000000009091167401ffffffffffffffffffffffffffffffffffffffff179091556040805133815260208101929092527f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce80910160405180910390a16040517fd572292b9e5d684b0719ae2d0e210513b477e303c975ed1c63b6fcac1607672790600090a1565b60035460ff16156108375760405162461bcd60e51b815260206004820152600f60248201527f636f6e747261637420706175736564000000000000000000000000000000000060448201526064016102ed565b61083f610aac565b6001600160a01b03831660009081526004602052604090205460ff16156108a85760405162461bcd60e51b815260206004820152601060248201527f616c7265616479206d696772617465640000000000000000000000000000000060448201526064016102ed565b6001600160a01b0383166108fe5760405162461bcd60e51b815260206004820152601460248201527f7a65726f2061646472657373206163636f756e7400000000000000000000000060448201526064016102ed565b8161094b5760405162461bcd60e51b815260206004820152601660248201527f7a65726f20616d6f756e7420746f206d6967726174650000000000000000000060448201526064016102ed565b6109568383836105ea565b6109a25760405162461bcd60e51b815260206004820152600f60248201527f696e76616c6964206163636f756e74000000000000000000000000000000000060448201526064016102ed565b6001600160a01b03838116600081815260046020819052604091829020805460ff1916600117905590516340c10f1960e01b815290810191909152602481018490527f0000000000000000000000000000000000000000000000000000000000000000909116906340c10f1990604401600060405180830381600087803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b5050604080516001600160a01b0387168152602081018690527f8b80bd19aea7b735bc6d75db8d6adbe18b28c30d62b3555245eb67b2340caedc935001905060405180910390a1610a916001600255565b505050565b600082610aa38584610b04565b14949350505050565b600280541415610afe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102ed565b60028055565b600081815b8451811015610b4957610b3582868381518110610b2857610b28610d10565b6020026020010151610b51565b915080610b4181610ce7565b915050610b09565b509392505050565b6000818310610b6d576000828152602084905260409020610b7c565b60008381526020839052604090205b9392505050565b80356001600160a01b0381168114610b9a57600080fd5b919050565b600060208284031215610bb157600080fd5b610b7c82610b83565b60008060408385031215610bcd57600080fd5b610bd683610b83565b946020939093013593505050565b600080600060608486031215610bf957600080fd5b610c0284610b83565b92506020808501359250604085013567ffffffffffffffff80821115610c2757600080fd5b818701915087601f830112610c3b57600080fd5b813581811115610c4d57610c4d610d26565b8060051b604051601f19603f83011681018181108582111715610c7257610c72610d26565b604052828152858101935084860182860187018c1015610c9157600080fd5b600095505b83861015610cb4578035855260019590950194938601938601610c96565b508096505050505050509250925092565b600060208284031215610cd757600080fd5b81358015158114610b7c57600080fd5b6000600019821415610d0957634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122037bb13f02a9bd87d1ccd27e6b90fe9c5787fa4942185eb6a4fa1119b18268e3664736f6c63430008060033000000000000000000000000501ace1cae9d535511fe78332741b21cdddb3b26e0f11c58e7ea42768979ddf2fb7b83c0660df2794c6fbb3b122d882162156d33000000000000000000000000501ace0e8d16b92236763e2ded7ae3bc2dffa276

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80635c975abb1161008c578063abbf4b1711610066578063abbf4b1714610250578063d1959f4814610258578063f39c38a01461026b578063fc0c546a1461027c57600080fd5b80635c975abb146101c85780636710837b146101d55780638be0861e1461023d57600080fd5b8063238efcbc116100c8578063238efcbc1461013a5780632eb4a7ab146101425780634ba0a5ee146101775780635aa6e675146101a357600080fd5b80630abb6035146100ef57806316c38b3c146101045780631c93022114610117575b600080fd5b6101026100fd366004610b9f565b6102a3565b005b610102610112366004610cc5565b6103a0565b600154600160a01b900460ff165b60405190151581526020015b60405180910390f35b610102610477565b6101697fe0f11c58e7ea42768979ddf2fb7b83c0660df2794c6fbb3b122d882162156d3381565b604051908152602001610131565b610125610185366004610b9f565b6001600160a01b031660009081526004602052604090205460ff1690565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610131565b6003546101259060ff1681565b6101696101e3366004610bba565b604080516001600160a01b038416602082015290810182905260009060600160408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905092915050565b61012561024b366004610be4565b6105ea565b61010261067d565b610102610266366004610be4565b6107e4565b6001546001600160a01b03166101b0565b6101b07f000000000000000000000000501ace1cae9d535511fe78332741b21cdddb3b2681565b600154600160a01b900460ff16156102f65760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064015b60405180910390fd5b6000546001600160a01b0316331461033e5760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016102ed565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd61ed858909d3cb796547804c47dc1550d27455f8a0037b6b487e46212392396906020015b60405180910390a150565b600154600160a01b900460ff16156103ee5760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064016102ed565b6000546001600160a01b031633146104365760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016102ed565b6003805460ff19168215159081179091556040519081527f878ac8a2ca79520471f8f3c8494fa802c03ce3bf034252aad7f22318984fdbdb90602001610395565b600154600160a01b900460ff16156104c55760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064016102ed565b6001546001600160a01b0316331461051f5760405162461bcd60e51b815260206004820152601360248201527f2170656e64696e6720676f7665726e616e63650000000000000000000000000060448201526064016102ed565b6001546001600160a01b03166105775760405162461bcd60e51b815260206004820152600f60248201527f7a65726f20676f7665726e616e6365000000000000000000000000000000000060448201526064016102ed565b60008054600180546001600160a01b0380821673ffffffffffffffffffffffffffffffffffffffff19808616821790965594909116909155604080519190921680825260208201939093527f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce809101610395565b6000610675827fe0f11c58e7ea42768979ddf2fb7b83c0660df2794c6fbb3b122d882162156d336106708787604080516001600160a01b038416602082015290810182905260009060600160408051601f198184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905092915050565b610a96565b949350505050565b600154600160a01b900460ff16156106cb5760405162461bcd60e51b815260206004820152601160248201527019dbdd995c9b985b98d9481b1bd8dad959607a1b60448201526064016102ed565b6000546001600160a01b031633146107135760405162461bcd60e51b815260206004820152600b60248201526a21676f7665726e616e636560a81b60448201526064016102ed565b60018054600080546001600160a01b0373ffffffffffffffffffffffffffffffffffffffff1990911681179091557fffffffffffffffffffffff0000000000000000000000000000000000000000009091167401ffffffffffffffffffffffffffffffffffffffff179091556040805133815260208101929092527f5f56bee8cffbe9a78652a74a60705edede02af10b0bbb888ca44b79a0d42ce80910160405180910390a16040517fd572292b9e5d684b0719ae2d0e210513b477e303c975ed1c63b6fcac1607672790600090a1565b60035460ff16156108375760405162461bcd60e51b815260206004820152600f60248201527f636f6e747261637420706175736564000000000000000000000000000000000060448201526064016102ed565b61083f610aac565b6001600160a01b03831660009081526004602052604090205460ff16156108a85760405162461bcd60e51b815260206004820152601060248201527f616c7265616479206d696772617465640000000000000000000000000000000060448201526064016102ed565b6001600160a01b0383166108fe5760405162461bcd60e51b815260206004820152601460248201527f7a65726f2061646472657373206163636f756e7400000000000000000000000060448201526064016102ed565b8161094b5760405162461bcd60e51b815260206004820152601660248201527f7a65726f20616d6f756e7420746f206d6967726174650000000000000000000060448201526064016102ed565b6109568383836105ea565b6109a25760405162461bcd60e51b815260206004820152600f60248201527f696e76616c6964206163636f756e74000000000000000000000000000000000060448201526064016102ed565b6001600160a01b03838116600081815260046020819052604091829020805460ff1916600117905590516340c10f1960e01b815290810191909152602481018490527f000000000000000000000000501ace1cae9d535511fe78332741b21cdddb3b26909116906340c10f1990604401600060405180830381600087803b158015610a2c57600080fd5b505af1158015610a40573d6000803e3d6000fd5b5050604080516001600160a01b0387168152602081018690527f8b80bd19aea7b735bc6d75db8d6adbe18b28c30d62b3555245eb67b2340caedc935001905060405180910390a1610a916001600255565b505050565b600082610aa38584610b04565b14949350505050565b600280541415610afe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016102ed565b60028055565b600081815b8451811015610b4957610b3582868381518110610b2857610b28610d10565b6020026020010151610b51565b915080610b4181610ce7565b915050610b09565b509392505050565b6000818310610b6d576000828152602084905260409020610b7c565b60008381526020839052604090205b9392505050565b80356001600160a01b0381168114610b9a57600080fd5b919050565b600060208284031215610bb157600080fd5b610b7c82610b83565b60008060408385031215610bcd57600080fd5b610bd683610b83565b946020939093013593505050565b600080600060608486031215610bf957600080fd5b610c0284610b83565b92506020808501359250604085013567ffffffffffffffff80821115610c2757600080fd5b818701915087601f830112610c3b57600080fd5b813581811115610c4d57610c4d610d26565b8060051b604051601f19603f83011681018181108582111715610c7257610c72610d26565b604052828152858101935084860182860187018c1015610c9157600080fd5b600095505b83861015610cb4578035855260019590950194938601938601610c96565b508096505050505050509250925092565b600060208284031215610cd757600080fd5b81358015158114610b7c57600080fd5b6000600019821415610d0957634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122037bb13f02a9bd87d1ccd27e6b90fe9c5787fa4942185eb6a4fa1119b18268e3664736f6c63430008060033

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

000000000000000000000000501ace1cae9d535511fe78332741b21cdddb3b26e0f11c58e7ea42768979ddf2fb7b83c0660df2794c6fbb3b122d882162156d33000000000000000000000000501ace0e8d16b92236763e2ded7ae3bc2dffa276

-----Decoded View---------------
Arg [0] : _token (address): 0x501ace1Cae9d535511fE78332741b21Cdddb3b26
Arg [1] : _merkleRoot (bytes32): 0xe0f11c58e7ea42768979ddf2fb7b83c0660df2794c6fbb3b122d882162156d33
Arg [2] : _governance (address): 0x501AcE0e8D16B92236763E2dEd7aE3bc2DFfA276

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000501ace1cae9d535511fe78332741b21cdddb3b26
Arg [1] : e0f11c58e7ea42768979ddf2fb7b83c0660df2794c6fbb3b122d882162156d33
Arg [2] : 000000000000000000000000501ace0e8d16b92236763e2ded7ae3bc2dffa276


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.