ETH Price: $2,612.07 (+0.04%)

Contract

0x61b3C5BFBF53Eb93a8AA27Ce6a11dfD4aa9AB7dc
 

Overview

ETH Balance

0.00002003900000052 ETH

Eth Value

$0.05 (@ $2,612.07/ETH)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer144189422022-03-19 20:06:36943 days ago1647720396IN
0x61b3C5BF...4aa9AB7dc
0.05001 ETH0.0033650526.77306653
Transfer144189252022-03-19 20:02:21943 days ago1647720141IN
0x61b3C5BF...4aa9AB7dc
0.00201001 ETH0.0041038124.77807718
Transfer144187652022-03-19 19:26:56943 days ago1647718016IN
0x61b3C5BF...4aa9AB7dc
500 wei0.0031231930.78402411
Transfer144184422022-03-19 18:15:08943 days ago1647713708IN
0x61b3C5BF...4aa9AB7dc
0.00000001 ETH0.0025886424.10758211

Latest 5 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
144189422022-03-19 20:06:36943 days ago1647720396
0x61b3C5BF...4aa9AB7dc
0.00025 ETH
144189422022-03-19 20:06:36943 days ago1647720396
0x61b3C5BF...4aa9AB7dc
0.04975 ETH
144189252022-03-19 20:02:21943 days ago1647720141
0x61b3C5BF...4aa9AB7dc
0.00001 ETH
144189252022-03-19 20:02:21943 days ago1647720141
0x61b3C5BF...4aa9AB7dc
0.00199 ETH
144180702022-03-19 17:00:04943 days ago1647709204  Contract Creation0 ETH
Loading...
Loading

Minimal Proxy Contract for 0x4fc3d5729919ddc2606b3b0d0121c6ec03c271b9

Contract Name:
GardenCenter

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 4 : GardenCenter.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.12;

import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
 
/**
* This is a Garden Center from Rarity.Garden that allows gas efficient trading for a specific collection.
* Please read the "collection" property for which collection this instance has been created.
*
* Site:    https://rarity.garden/
* Discord: https://discord.gg/Ur8XGaurSd
* Twitter: https://t.me/raritygarden
*/
contract GardenCenter
{

    using Strings for uint256;

    struct Listing{
        uint32 price;
        address owner;
    }

    bool public initialized;
    bool public isCollectionOwner;
    uint16 public rate;
    address public creator;
    address public collection;
    address public factory;
    mapping(uint256 => Listing) public listings;

    event Sale(address indexed _seller, address indexed _buyer, uint256 indexed _tokenId, uint256 _price);
    event Offer(address indexed _seller, uint256 indexed _tokenId, uint256 _price);
    event Removed(address indexed _owner, uint256 indexed _tokenId);

    constructor(address _collection)  {

        require(!initialized, "already initialized.");

        collection = _collection;
        creator = msg.sender;
        initialized = true;
        rate = 50;
        isCollectionOwner = true;
    }

    function construct(address _collection, address _sender, bool _isCollectionOwner) external {

        require(!initialized, "init: already initialized.");

        collection = _collection;
        creator = _sender;
        initialized = true;
        rate = 50;
        factory = msg.sender;
        isCollectionOwner = _isCollectionOwner;
    }

    function updateCreator(address _creator) external{

        require(IERC721(0x13fD344E39C30187D627e68075d6E9201163DF33).balanceOf(msg.sender) != 0, "updateCreator: not an RG unicorn holder.");
        require(msg.sender == creator, "updateCreator: not the current creator.");

        creator = _creator;
    }

    function updateRate(uint16 _rate) external{

        require(IERC721(0x13fD344E39C30187D627e68075d6E9201163DF33).balanceOf(msg.sender) != 0, "updateRate: not an RG unicorn holder.");
        require(msg.sender == creator, "updateRate: not the current creator.");
        require(_rate <= 2500, "updateRate: max. 25% fee allowed.");
        require(isCollectionOwner, "updateRate: not created by collection owner, default rate is .5% fixed.");

        rate = _rate;
    }

    receive() external payable {

        string memory _string = msg.value.toString();
        _string = fillZeros( _string );
        string memory _input = reverse( _string );
        string memory _flag = getSlice( _input, 14, 1 );

         if( strCmp( _flag, "0" ) ){

            string memory _slice = getSlice( _input, 1, 14 );
            string memory _inputOffer = reverse( _slice );

            string memory _tokenIdStr = getSlice( _inputOffer, 2, 5 );
            uint256 tokenId = toUint( _tokenIdStr );

            require(msg.sender == IERC721(collection).ownerOf(tokenId), "receive: not the owner.");

            _inputOffer = getSlice( _inputOffer, 7, 8 );
            uint256 price = toUint( _inputOffer );

            require(price != 0, "receive: price must be larger than zero.");

            listings[tokenId] = Listing( uint32(price), msg.sender );

            emit Offer(msg.sender, tokenId, price * 10**14);
        }
        else if( strCmp( _flag, "1" ) ){

            uint16 _rate = rate;
            string memory _slice = getSlice( _input, 9, 5 );
            _slice = reverse( _slice );
            uint256 tokenId = toUint( _slice );
            address _ownerOf = IERC721(collection).ownerOf(tokenId);
            Listing memory listing = listings[tokenId];

            require(listing.owner != address(0) && listing.owner == _ownerOf, "receive: invalid listing.");

            uint256 _price = listing.price;

            require(_price != 0, "receive: token not for sale.");

            _price *= 10**14;
            _slice = getSlice( _input, 15, bytes(_input).length - 14 );
            _slice = reverse( _slice );

            uint256 _value = toUint( _slice );
            _value *= 10**14;
            
            require(_value == _price, "receive: please send the exact value.");

            delete listings[tokenId];

            emit Sale(_ownerOf, msg.sender, tokenId, _price);

            uint256 _fee = _value;
            _fee *= 10**18;
            _fee /= 100;
            _fee *= _rate;
            _fee /= 10**20;

            (bool success,) = payable(_ownerOf).call{value:_value - _fee}("");
            require(success, "receive: eth transfer failed.");

            (success,) = payable(creator).call{value:_fee}("");
            require(success, "receive: creator fee transfer failed.");

            IERC721(collection).safeTransferFrom(_ownerOf, msg.sender, tokenId);

        } 
        else if( strCmp( _flag, "2" ) ){

            string memory _slice = getSlice( _input, 9, 5 );
            string memory _tokenIdStr = reverse( _slice );
            uint256 tokenId = toUint( _tokenIdStr );

            require(msg.sender == IERC721(collection).ownerOf(tokenId), "receive: not the owner.");

            delete listings[tokenId];

            emit Removed(msg.sender, tokenId);
        }
        else
        {
            revert();
        }
    }

    function getSlice(string memory source, uint startPos, uint numChars) internal pure returns (string memory) {
       uint ustartPos = uint(startPos -1);
       uint _numChars = uint(numChars);

        bytes memory sourcebytes = bytes(source);
       if (_numChars==0) {
           _numChars = ((sourcebytes.length - ustartPos) + 1);
       }
      
      bytes memory result = new bytes(_numChars);     

      for (uint i = 0; i<_numChars; i++) {
          result[i] = sourcebytes[i + ustartPos];
      }
      return string(result); 
    }

    function strCmp(string memory s1, string memory s2) internal pure returns (bool)
    {
        return keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2));
    }

    function fillZeros(string memory _str) internal pure returns(string memory) {

        bytes memory str = bytes(_str);

        if(str.length >= 18){

            return _str;
        }

        uint256 size = 18 - str.length;
        string memory tmp = new string(str.length + size);
        bytes memory _new = bytes(tmp);

        for(uint i = 0; i < size; i++) {

            _new[i] = "0";
        }

        for(uint i = 0; i < str.length; i++) {

            _new[i + size] = str[i];
        }

        return string(_new);
    }

    function reverse(string memory _str) internal pure returns(string memory) {
        bytes memory str = bytes(_str);
        string memory tmp = new string(str.length);
        bytes memory _reverse = bytes(tmp);

        for(uint i = 0; i < str.length; i++) {
            _reverse[str.length - i - 1] = str[i];
        }
        return string(_reverse);
    }

    function toUint(string memory numString) internal pure returns(uint) {
        uint val = 0;
        bytes   memory stringBytes = bytes(numString);
        bool leading = true;
        for (uint  i =  0; i<stringBytes.length; i++) {
            uint exp = stringBytes.length - i;
            bytes1 ival = stringBytes[i];
            uint8 uval = uint8(ival);
            uint jval = uval - uint(0x30);
            uint _val =  (uint(jval) * (10**(exp-1))); 
            if(_val == 0 && leading){
                continue;
            } else if( _val != 0 && leading ){
                leading = false;
            }
            val += _val;
        }
      return val;
    }
}

File 2 of 4 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

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;
}

File 3 of 4 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

File 4 of 4 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

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);
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_collection","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_price","type":"uint256"}],"name":"Offer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Removed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_seller","type":"address"},{"indexed":true,"internalType":"address","name":"_buyer","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_price","type":"uint256"}],"name":"Sale","type":"event"},{"inputs":[],"name":"collection","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"bool","name":"_isCollectionOwner","type":"bool"}],"name":"construct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isCollectionOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"listings","outputs":[{"internalType":"uint32","name":"price","type":"uint32"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rate","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_creator","type":"address"}],"name":"updateCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_rate","type":"uint16"}],"name":"updateRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

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.