Skip to content

Instantly share code, notes, and snippets.

@z0r0z
Created April 4, 2022 08:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save z0r0z/a06bf92d5bc8e80abd4bd67ada05eb98 to your computer and use it in GitHub Desktop.
Save z0r0z/a06bf92d5bc8e80abd4bd67ada05eb98 to your computer and use it in GitHub Desktop.
pay rent to keep right to hold an NFT
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import "https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol";
contract RentNFT is ERC721("RentNFT", "RENT"), Ownable {
using SafeTransferLib for address;
mapping(uint256 => Rent) public rents;
struct Rent {
uint64 start;
uint64 term;
uint64 due;
}
// ** RENT LOGIC ** //
function payRent(uint256 id, uint256 amount) public payable {
Rent storage rent = rents[id];
rent.due = rent.due - uint64(amount);
owner().safeTransferETH(amount);
}
// ** RENT MGMT ** //
function setRent(address to, uint256 id, uint256 term, uint256 due) public onlyOwner {
if (ownerOf[id] == address(0)) {
_mint(to, id);
}
rents[id] = Rent({
start: uint64(block.timestamp),
term: uint64(term),
due: uint64(due)
});
}
function retrieve(address from, address to, uint256 id) public onlyOwner {
Rent storage rent = rents[id];
if (block.timestamp > rent.term && rent.due != 0) {
require(from == ownerOf[id], "WRONG_FROM");
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
unchecked {
balanceOf[from]--;
balanceOf[to]++;
}
ownerOf[id] = to;
delete getApproved[id];
emit Transfer(from, to, id);
} else {
revert();
}
}
// ** GETTERS ** //
function goodStanding(uint256 id) public view returns (address owner, bool standing) {
Rent storage rent = rents[id];
owner = ownerOf[id];
if (rent.term > block.timestamp) {
standing = true;
} else {
if (rent.due != 0) standing = false;
}
}
function amountDue(uint256 id) public view returns (uint256) {
return rents[id].due;
}
function tokenURI(uint256) public override pure returns (string memory) {
return "RENT";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment