Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xBe92B49aEE993ADea3a002AdCDA189A2b7deC56c
Balance 0 ETH
Nonce 1
Code Size 2606 bytes
Last Active
Indexed Transactions 14 (24,216,57724,460,853)
Gas Used (indexed) 2,880,027
External Etherscan · Sourcify

Contract Bytecode

2606 bytes
0x608060405234801561001057600080fd5b506004361061009e5760003560e01c80638da5cb5b116100665780638da5cb5b146101a45780638f32d59b146101ac578063a42dce80146101c8578063c415b95c146101ee578063f2fde38b146101f65761009e565b80631e59c529146100a35780632b20e39714610156578063451c3d801461017a578063715018a6146101825780638d859f3e1461018a575b600080fd5b610154600480360360408110156100b957600080fd5b8101906020810181356401000000008111156100d457600080fd5b8201836020820111156100e657600080fd5b8035906020019184600183028401116401000000008311171561010857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b0316915061021c9050565b005b61015e610493565b604080516001600160a01b039092168252519081900360200190f35b61015e6104a2565b6101546104b1565b610192610554565b60408051918252519081900360200190f35b61015e610561565b6101b4610570565b604080519115158252519081900360200190f35b610154600480360360208110156101de57600080fd5b50356001600160a01b0316610594565b61015e6105f9565b6101546004803603602081101561020c57600080fd5b50356001600160a01b0316610608565b6001600160a01b03811661026d576040805162461bcd60e51b8152602060048201526013602482015272496e76616c69642062656e656669636961727960681b604482015290519081900360640190fd5b6102768261066a565b60025460408051631e59c52960e01b81526001600160a01b03848116602483015260048201928352855160448301528551931692631e59c5299286928692829160640190602086019080838360005b838110156102dd5781810151838201526020016102c5565b50505050905090810190601f16801561030a5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561032a57600080fd5b505af115801561033e573d6000803e3d6000fd5b5050600154600354604080516323b872dd60e01b81523360048201526001600160a01b03928316602482015268056bc75e2d63100000604482015290519190921693506323b872dd925060648083019260209291908290030181600087803b1580156103a957600080fd5b505af11580156103bd573d6000803e3d6000fd5b505050506040513d60208110156103d357600080fd5b50506040805168056bc75e2d63100000808252602082810184815286519484019490945285516001600160a01b0386169433947fb8c56202a5ae8b00edfcd57a54ec6c3fb8d2f6deb3067a7ba11408a7bd014a3e94938993919291606084019185019080838360005b8381101561045457818101518382015260200161043c565b50505050905090810190601f1680156104815780820380516001836020036101000a031916815260200191505b50935050505060405180910390a35050565b6002546001600160a01b031681565b6001546001600160a01b031681565b6104b9610570565b61050a576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b68056bc75e2d6310000081565b6000546001600160a01b031690565b600080546001600160a01b0316610585610765565b6001600160a01b031614905090565b61059c610570565b6105ed576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6105f681610769565b50565b6003546001600160a01b031681565b610610610570565b610661576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6105f681610818565b805181906002118015906106805750600f815111155b6106bb5760405162461bcd60e51b81526004018080602001828103825260468152602001806109b46046913960600191505060405180910390fd5b60005b8151811015610760576106ea8282815181106106d657fe5b01602001516001600160f81b0319166108b8565b8061071357506107138282815181106106ff57fe5b01602001516001600160f81b03191661091e565b610758576040805162461bcd60e51b815260206004820152601160248201527024b73b30b634b21021b430b930b1ba32b960791b604482015290519081900360640190fd5b6001016106be565b505050565b3390565b6001600160a01b0381166107bc576040805162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103332b29031b7b63632b1ba37b960591b604482015290519081900360640190fd5b6003546040516001600160a01b038084169216907f649c5e3d0ed183894196148e193af316452b0037e77d2ff0fef23b7dc722bed090600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811661085d5760405162461bcd60e51b815260040180806020018281038252602681526020018061098e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000604160f81b6001600160f81b03198316108015906108e65750602d60f91b6001600160f81b0319831611155b806109185750606160f81b6001600160f81b03198316108015906109185750603d60f91b6001600160f81b0319831611155b92915050565b6000600360fc1b6001600160f81b0319831610801590610918575050603960f81b6001600160f81b031991909116111590565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906109855750808214155b94935050505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734e616d652073686f756c642062652067726561746572207468616e206f7220657175616c20746f203220616e64206c657373207468616e206f7220657175616c20746f203135a265627a7a7231582040e3e513f6a2216a170736f442334495c6419fe857b0fea3d982341523c18bd464736f6c634300050f0032

Verified Source Code Full Match

Compiler: v0.5.15+commit.6a57276f EVM: istanbul Optimization: Yes (200 runs)
DCLControllerV2.sol 116 lines
pragma solidity ^0.5.15;

import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "openzeppelin-solidity/contracts/utils/Address.sol";

import "../interfaces/IENSRegistry.sol";
import "../interfaces/IDCLRegistrar.sol";
import "../interfaces/IERC20Token.sol";

contract DCLControllerV2 is Ownable {
    using Address for address;

    // Price of each name
    uint256 constant public PRICE = 100 ether;

    // Accepted ERC20 token
    IERC20Token public acceptedToken;
    // DCL Registrar
    IDCLRegistrar public registrar;
    // Fee Collector
    address public feeCollector;

    // Emitted when a name is bought
    event NameBought(address indexed _caller, address indexed _beneficiary, uint256 _price, string _name);

    // Emitted when the fee collector is changed
    event FeeCollectorChanged(address indexed _oldFeeCollector, address indexed _newFeeCollector);

    /**
	 * @dev Constructor of the contract
     * This contract does not support ERC20 tokens that do not revert on an invalid transfer.
     * @param _acceptedToken - address of the accepted ERC20 token
     * @param _registrar - address of the DCL registrar contract
     * @param _feeCollector - address of the fee collector
     * @param _owner - address of the contract owner
	 */
    constructor(IERC20Token _acceptedToken, IDCLRegistrar _registrar, address _feeCollector, address _owner) public {
        require(address(_acceptedToken).isContract(), "Accepted token should be a contract");
        require(address(_registrar).isContract(), "Registrar should be a contract");

        // Accepted token
        acceptedToken = _acceptedToken;
        // DCL registrar
        registrar = _registrar;

        _setFeeCollector(_feeCollector);

        _transferOwnership(_owner);
    }

    /**
	 * @dev Register a name
     * This function transfers the PRICE from the sender to the fee collector without checking the return value of the transferFrom function.
     * This means that only tokens that revert when the transfer fails due to insufficient balance or insufficient approve should be used.
     * If the token does not revert on an invalid transfer, the register will succeed and a name will be minted without being paid for.
     * @param _name - name to be registered
	 * @param _beneficiary - owner of the name
	 */
    function register(string memory _name, address _beneficiary) public {
        // Check for valid beneficiary
        require(_beneficiary != address(0), "Invalid beneficiary");

        // Check if the name is valid
        _requireNameValid(_name);

        // Register the name
        registrar.register(_name, _beneficiary);
        // Transfer PRICE to the fee collector
        acceptedToken.transferFrom(msg.sender, feeCollector, PRICE);
        // Log
        emit NameBought(msg.sender, _beneficiary, PRICE, _name);
    }

    /**
     * @notice Set the fee collector
     * @dev Only the owner can change the fee collector
     * @param _feeCollector - the address of the new collector
     */
    function setFeeCollector(address _feeCollector) external onlyOwner {
        _setFeeCollector(_feeCollector);
    }

    /**
    * @dev Validate a name
    * @notice that only a-z is allowed
    * @param _name - string for the name
    */
    function _requireNameValid(string memory _name) internal pure {
        bytes memory tempName = bytes(_name);
        require(
            tempName.length >= 2 && tempName.length <= 15,
            "Name should be greater than or equal to 2 and less than or equal to 15"
        );
        for(uint256 i = 0; i < tempName.length; i++) {
            require(_isLetter(tempName[i]) || _isNumber(tempName[i]), "Invalid Character");
        }
    }

    function _isLetter(bytes1 _char) internal pure returns (bool) {
        return (_char >= 0x41 && _char <= 0x5A) || (_char >= 0x61 && _char <= 0x7A);
    }

    function _isNumber(bytes1 _char) internal pure returns (bool) {
        return (_char >= 0x30 && _char <= 0x39);
    }

    function _setFeeCollector(address _feeCollector) internal {
        require(_feeCollector != address(0), "Invalid fee collector");
        
        emit FeeCollectorChanged(feeCollector, _feeCollector);

        feeCollector = _feeCollector;
    }

}
IERC20Token.sol 8 lines
pragma solidity ^0.5.15;

contract IERC20Token {
    function balanceOf(address from) public view returns (uint256);
    function transferFrom(address from, address to, uint tokens) public returns (bool);
    function allowance(address owner, address spender) public view returns (uint256);
    function burn(uint256 amount) public;
}
IENSRegistry.sol 14 lines
pragma solidity ^0.5.15;

/**
 * @title EnsRegistry
 * @dev Extract of the interface for ENS Registry
*/
contract IENSRegistry {
    function setOwner(bytes32 node, address owner) public;
    function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public;
    function setResolver(bytes32 node, address resolver) public;
    function owner(bytes32 node) public view returns (address);
    function resolver(bytes32 node) public view returns (address);
}
IDCLRegistrar.sol 36 lines
pragma solidity ^0.5.15;

contract IDCLRegistrar {
    /**
	 * @dev Allows to create a subdomain (e.g. "nacho.dcl.eth"), set its resolver, owner and target address
	 * @param _subdomain - subdomain  (e.g. "nacho")
	 * @param _beneficiary - address that will become owner of this new subdomain
	 */
    function register(string calldata _subdomain, address _beneficiary) external;

     /**
	 * @dev Re-claim the ownership of a subdomain (e.g. "nacho").
     * @notice After a subdomain is transferred by this contract, the owner in the ENS registry contract
     * is still the old owner. Therefore, the owner should call `reclaim` to update the owner of the subdomain.
	 * @param _tokenId - erc721 token id which represents the node (subdomain).
     * @param _owner - new owner.
     */
    function reclaim(uint256 _tokenId, address _owner) external;

    /**
     * @dev Transfer a name to a new owner.
     * @param _from - current owner of the node.
     * @param _to - new owner of the node.
     * @param _id - node id.
     */
    function transferFrom(address _from, address _to, uint256 _id) public;

    /**
	 * @dev Check whether a name is available to be registered or not
	 * @param _labelhash - hash of the name to check
     * @return whether the name is available or not
     */
    function available(bytes32 _labelhash) public view returns (bool);

}
Context.sol 27 lines
pragma solidity ^0.5.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}
Address.sol 68 lines
pragma solidity ^0.5.5;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * IMPORTANT: It is unsafe to assume that an address for which this
     * function returns false is an externally-owned account (EOA) and not a
     * contract.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-call-value
        (bool success, ) = recipient.call.value(amount)("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}
Ownable.sol 76 lines
pragma solidity ^0.5.0;

import "../GSN/Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        _owner = _msgSender();
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

Read Contract

PRICE 0x8d859f3e → uint256
acceptedToken 0x451c3d80 → address
feeCollector 0xc415b95c → address
isOwner 0x8f32d59b → bool
owner 0x8da5cb5b → address
registrar 0x2b20e397 → address

Write Contract 4 functions

These functions modify contract state and require a wallet transaction to execute.

register 0x1e59c529
string _name
address _beneficiary
renounceOwnership 0x715018a6
No parameters
setFeeCollector 0xa42dce80
address _feeCollector
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

CSV View All 14 Transactions →
|
Hash Method Block Age From/To Value Txn Fee Type
0x3889e401...c08184 0x1e59c529 24,460,853 IN 0xd82d005E...e8aF 0 ETH 0.000071604500 ETH EIP-1559
0x465b19f5...7c46c8 0x1e59c529 24,323,522 IN 0x5854Cce9...C495 0 ETH 0.000581445243 ETH EIP-1559
0x0b6c8ca4...6f9996 0x1e59c529 24,323,507 IN 0x5854Cce9...C495 0 ETH 0.000580109797 ETH EIP-1559
0x1a84169f...0fc691 0x1e59c529 24,323,497 IN 0x5854Cce9...C495 0 ETH 0.000593162834 ETH EIP-1559
0x52fb63ee...75ade5 0x1e59c529 24,313,420 IN 0xb4725672...631d 0 ETH 0.000615966566 ETH EIP-1559
0xf4e09fed...875e7d 0x1e59c529 24,292,495 IN 0x4F406803...7C3A 0 ETH 0.000024081577 ETH EIP-1559
0x52a04d9f...4e47b3 0x1e59c529 24,281,959 IN 0xd82d005E...e8aF 0 ETH 0.000032876632 ETH EIP-1559
0xc062c4cb...0028db 0x1e59c529 24,251,549 IN 0x29fb0D1B...70B4 0 ETH 0.000576834848 ETH EIP-1559
0x61fe03f3...a73342 0x1e59c529 24,248,927 IN 0x3e2F8218...F68d 0 ETH 0.000614853200 ETH EIP-1559
0xec7eb11b...345063 0x1e59c529 24,216,577 IN 0x7971EfB2...3b3F 0 ETH 0.000569344734 ETH EIP-1559