A smart contract system that enables ENS domain owners to rent out their domains for a specified duration. This contract supports both wrapped (ERC1155) and unwrapped (ERC721) ENS names.
- Owners can list their ENS domains for rent
- Set a price per second in ETH
- Define a maximum end date for rentals
- Supports both wrapped and unwrapped ENS domains
- Automatic handling of domain custody during rental period
- Renters can lease domains for any period up to the maximum end date
- Pay-per-second pricing model
- Automatic refund of excess payments
- Instant transfer of ENS name control to renter
- Protection against rental period overlaps
- Automatic validation of domain expiry
- Protection against zero prices
- Validation of rental end dates
- Checks for active rental periods
- Safe handling of both ERC721 and ERC1155 tokens
- Proper ETH transfer safety checks
- Lenders can reclaim domains after rental period
- Recovery mechanism for expired rentals
- Automatic return of domain control
- Clear rental terms tracking
- Rental ownership through NFT
- Protocol fees
- Dynamic auction parameters
The system consists of three main components:
- Base Registrar Interface (ERC721)
- Name Wrapper Interface (ERC1155)
- ENS Registry Interface
Change the domain name in the script to the desired domain and set the private key in the .env file.
forge script script/lendAndBorrow.s.sol \
--rpc-url sepolia \
-vvvvv \
--chain 11155111 \
--verify \
--broadcast \
--slow
struct RentalTerms {
address lender; // Domain owner
uint256 pricePerSecond; // Rental price in wei/second
uint256 maxEndTimestamp; // Maximum rental end date
address currentBorrower; // Current renter
uint256 rentalEnd; // Current rental end time
bytes32 nameNode; // ENS node hash
}
function listDomain(
uint256 tokenId,
uint256 pricePerSecond,
uint256 maxEndTimestamp,
bytes32 nameNode
) external
function rentDomain(
uint256 tokenId,
uint256 desiredEndTimestamp
) external payable
function reclaimDomain(
uint256 tokenId
) external
event DomainListed(uint256 indexed tokenId, address indexed lender, uint256 pricePerSecond, uint256 maxEndTimestamp, bytes32 nameNode);
event DomainRented(uint256 indexed tokenId, address indexed borrower, uint256 rentalEnd, uint256 totalPrice);
event DomainReclaimed(uint256 indexed tokenId, address indexed lender);
The contract includes custom errors for better gas efficiency and clearer error messages:
ZeroPriceNotAllowed()
MaxEndTimeMustBeFuture()
MaxEndTimeExceedsExpiry()
DomainNotListed()
ExceedsMaxEndTime()
- And more...
// List domain for 0.0001 ETH per second until Dec 31, 2024
contract.listDomain(
tokenId,
100000000000000, // 0.0001 ETH in wei
1735689600, // Dec 31, 2024
nameNode
);
// Rent domain until Nov 1, 2024
contract.rentDomain{value: 1 ether}(
tokenId,
1698796800 // Nov 1, 2024
);
- Contract holds ENS domains during rental periods
- Implements reentrancy protection
- Safe ETH transfer handling
- Proper access control for domain operations
- Validation of all time-based parameters
- Protection against rental overlap
- OpenZeppelin Contracts
- ERC721Holder
- ERC1155Holder
MIT License