Created
April 4, 2022 08:23
-
-
Save z0r0z/a06bf92d5bc8e80abd4bd67ada05eb98 to your computer and use it in GitHub Desktop.
pay rent to keep right to hold an NFT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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