Description:
Smart contract deployed on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
interface IERC20 {
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
interface IERC20Permit {
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
}
interface IENS {
function owner(bytes32 node) external view returns (address);
function setOwner(bytes32 node, address owner) external;
}
interface INameWrapper {
function ownerOf(uint256 tokenId) external view returns (address);
function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes calldata data) external;
}
contract ENSBid {
IENS constant ENS = IENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
INameWrapper constant NAME_WRAPPER = INameWrapper(0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401);
// Bid data
string public ensName;
bytes32 public ensNode;
address public buyer;
address public token;
uint256 public amount;
// Permit signature
uint256 public deadline;
uint8 public v;
bytes32 public r;
bytes32 public s;
bool public permitSet = false;
bool public executed = false;
constructor(
string memory _ensName,
bytes32 _ensNode,
address _buyer,
address _token,
uint256 _amount
) {
ensName = _ensName;
ensNode = _ensNode;
buyer = _buyer;
token = _token;
amount = _amount;
}
// Buyer submits permit signature
function setPermit(uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s) external {
require(msg.sender == buyer, "Only buyer");
require(!executed, "Already executed");
deadline = _deadline;
v = _v;
r = _r;
s = _s;
permitSet = true;
}
// Check if address is the owner of the ENS (supports wrapped and unwrapped)
function isENSOwner(address user) public view returns (bool) {
address registryOwner = ENS.owner(ensNode);
// If the registry owner is the NameWrapper, check the NameWrapper ownership
if (registryOwner == address(NAME_WRAPPER)) {
return NAME_WRAPPER.ownerOf(uint256(ensNode)) == user;
}
// Otherwise, check direct registry ownership
return registryOwner == user;
}
// ENS owner accepts: permit + payment + ENS transfer in one tx
function accept() external {
require(permitSet, "No permit");
require(!executed, "Already executed");
require(isENSOwner(msg.sender), "Not ENS owner");
// Execute permit and transfer USDC
IERC20Permit(token).permit(buyer, address(this), amount, deadline, v, r, s);
IERC20(token).transferFrom(buyer, msg.sender, amount);
// Transfer ENS (wrapped or unwrapped)
address registryOwner = ENS.owner(ensNode);
if (registryOwner == address(NAME_WRAPPER)) {
// Wrapped ENS: transfer via NameWrapper
NAME_WRAPPER.safeTransferFrom(msg.sender, buyer, uint256(ensNode), 1, "");
} else {
// Unwrapped ENS: transfer via registry
ENS.setOwner(ensNode, buyer);
}
executed = true;
}
// Check if bid can be executed
function canExecute() external view returns (bool) {
address registryOwner = ENS.owner(ensNode);
return permitSet && !executed && registryOwner != address(0);
}
// Get bid status
function getStatus() external view returns (string memory) {
if (executed) return "EXECUTED";
if (permitSet) return "ACTIVE";
return "PENDING_PERMIT";
}
}
Submitted on: 2025-09-19 13:17:49
Comments
Log in to comment.
No comments yet.