Contract detail
EtchMarket
EtchMarket is a verified Robinhood Chain smart contract at 0x5a752b6f…3d4039ec with 0 indexed transactions.
- Address type
- Smart contract
- Transactions
- 0
- History coverage
- No indexed activity found
- Verification
- Verified
- Compiler
- v0.8.26+commit.8a97fa7a
- Verification match
- partial
- Creation transaction
- 0x29dab4ce…f51f2e62
- Created at block
- #28577501
- Language
- solidity
- EVM version
- cancun
- License
- mit
- Compiler optimization
- Enabled · 44444444 runs
Verified contract
Contract source code
// SPDX-License-Identifier: MIT
//
// ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗███████╗████████╗ ██████╗██╗ ██╗
// ██╔══██╗██╔═══██╗██╔══██╗██║████╗ ██║██╔════╝╚══██╔══╝██╔════╝██║ ██║
// ██████╔╝██║ ██║██████╔╝██║██╔██╗ ██║█████╗ ██║ ██║ ███████║
// ██╔══██╗██║ ██║██╔══██╗██║██║╚██╗██║██╔══╝ ██║ ██║ ██╔══██║
// ██║ ██║╚██████╔╝██████╔╝██║██║ ╚████║███████╗ ██║ ╚██████╗██║ ██║
// ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
//
// RobinEtch — the first inscriptions + token protocol using Uniswap V4 hooks
// on Robinhood Chain.
//
// Web: https://robinetch.app
// X: https://x.com/robinetchapp
//
pragma solidity 0.8.26;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
/// @title EtchMarket
/// @notice Minimal escrow marketplace for RobinEtch Inscriptions, priced in native ETH.
/// 2% marketplace fee, matching the protocol's 2/2 swap tax.
contract EtchMarket is ReentrancyGuard {
uint256 public constant FEE_BPS = 200;
uint256 public constant BPS_DENOMINATOR = 10_000;
IERC721 public immutable inscriptions;
address public immutable treasury;
struct Listing {
address seller;
uint96 price;
}
mapping(uint256 => Listing) public listings;
uint256[] private _listedIds;
mapping(uint256 => uint256) private _idxPlusOne;
event Listed(uint256 indexed id, address indexed seller, uint256 price);
event Cancelled(uint256 indexed id, address indexed seller);
event Purchased(uint256 indexed id, address indexed buyer, address indexed seller, uint256 price);
error NotListed();
error NotSeller();
error BadPrice();
error WrongPayment();
constructor(IERC721 inscriptions_, address treasury_) {
inscriptions = inscriptions_;
treasury = treasury_;
}
/// @notice Escrow-list an inscription for a fixed ETH price (requires prior approval).
function list(uint256 id, uint96 price) external nonReentrant {
if (price == 0) revert BadPrice();
inscriptions.transferFrom(msg.sender, address(this), id);
listings[id] = Listing(msg.sender, price);
_idxPlusOne[id] = _listedIds.length + 1;
_listedIds.push(id);
emit Listed(id, msg.sender, price);
}
function cancel(uint256 id) external nonReentrant {
Listing memory l = listings[id];
if (l.seller == address(0)) revert NotListed();
if (l.seller != msg.sender) revert NotSeller();
_remove(id);
inscriptions.transferFrom(address(this), msg.sender, id);
emit Cancelled(id, msg.sender);
}
function buy(uint256 id) external payable nonReentrant {
Listing memory l = listings[id];
if (l.seller == address(0)) revert NotListed();
if (msg.value != l.price) revert WrongPayment();
_remove(id);
uint256 fee = (uint256(l.price) * FEE_BPS) / BPS_DENOMINATOR;
(bool okSeller,) = l.seller.call{value: msg.value - fee}("");
require(okSeller, "seller payment failed");
if (fee > 0) {
(bool okFee,) = treasury.call{value: fee}("");
require(okFee, "fee payment failed");
}
inscriptions.transferFrom(address(this), msg.sender, id);
emit Purchased(id, msg.sender, l.seller, l.price);
}
function _remove(uint256 id) private {
uint256 idx = _idxPlusOne[id] - 1;
uint256 last = _listedIds.length - 1;
if (idx != last) {
uint256 moved = _listedIds[last];
_listedIds[idx] = moved;
_idxPlusOne[moved] = idx + 1;
}
_listedIds.pop();
delete _idxPlusOne[id];
delete listings[id];
}
/// @notice All active listings (small-scale friendly, one call for the frontend).
function listed() external view returns (uint256[] memory ids, address[] memory sellers, uint256[] memory prices) {
uint256 n = _listedIds.length;
ids = new uint256[](n);
sellers = new address[](n);
prices = new uint256[](n);
for (uint256 i = 0; i < n; i++) {
uint256 id = _listedIds[i];
ids[i] = id;
sellers[i] = listings[id].seller;
prices[i] = listings[id].price;
}
}
function listedCount() external view returns (uint256) {
return _listedIds.length;
}
}