forked from GuildCrypt/oathforge
/
OathForge.sol
118 lines (98 loc) · 4.68 KB
/
OathForge.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
pragma solidity ^0.4.24;
import "ERC721.sol";
import "ERC721Metadata.sol";
import "math/SafeMath.sol";
import "ownership/Ownable.sol";
/// @title OathForge: NFT Registry
/// @author GuildCrypt
contract OathForge is ERC721, ERC721Metadata, Ownable {
using SafeMath for uint256;
uint256 private _totalSupply;
uint256 private _nextTokenId;
mapping(uint256 => uint256) private _sunsetInitiatedAt;
mapping(uint256 => uint256) private _sunsetLength;
mapping(uint256 => uint256) private _redemptionCodeHashSubmittedAt;
mapping(uint256 => bytes32) private _redemptionCodeHash;
/// @param name The ERC721 Metadata name
/// @param symbol The ERC721 Metadata symbol
constructor(string name, string symbol) ERC721Metadata(name, symbol) public {}
/// @dev Emits when a sunset has been initiated
/// @param tokenId The token id
event SunsetInitiated(uint256 indexed tokenId);
/// @dev Emits when a redemption code hash has been submitted
/// @param tokenId The token id
/// @param redemptionCodeHash The redemption code hash
event RedemptionCodeHashSubmitted(uint256 indexed tokenId, bytes32 redemptionCodeHash);
/// @dev Returns the total number of tokens (minted - burned) registered
function totalSupply() external view returns(uint256){
return _totalSupply;
}
/// @dev Returns the token id of the next minted token
function nextTokenId() external view returns(uint256){
return _nextTokenId;
}
/// @dev Returns the timestamp at which a token's sunset was initated. Returns 0 if no sunset has been initated.
/// @param tokenId The token id
function sunsetInitiatedAt(uint256 tokenId) external view returns(uint256){
return _sunsetInitiatedAt[tokenId];
}
/// @dev Returns the sunset length of a token
/// @param tokenId The token id
function sunsetLength(uint256 tokenId) external view returns(uint256){
return _sunsetLength[tokenId];
}
/// @dev Returns the redemption code hash submitted for a token
/// @param tokenId The token id
function redemptionCodeHash(uint256 tokenId) external view returns(bytes32){
return _redemptionCodeHash[tokenId];
}
/// @dev Returns the timestamp at which a redemption code hash was submitted
/// @param tokenId The token id
function redemptionCodeHashSubmittedAt(uint256 tokenId) external view returns(uint256){
return _redemptionCodeHashSubmittedAt[tokenId];
}
/// @dev Mint a token. Only `owner` may call this function.
/// @param to The receiver of the token
/// @param tokenURI The tokenURI of the the tokenURI
/// @param __sunsetLength The length (in seconds) that a sunset period can last
function mint(address to, string tokenURI, uint256 __sunsetLength) public onlyOwner {
_mint(to, _nextTokenId);
_sunsetLength[_nextTokenId] = __sunsetLength;
_setTokenURI(_nextTokenId, tokenURI);
_nextTokenId = _nextTokenId.add(1);
_totalSupply = _totalSupply.add(1);
}
/// @dev Initiate a sunset. Sets `sunsetInitiatedAt` to current timestamp. Only `owner` may call this function.
/// @param tokenId The id of the token
function initiateSunset(uint256 tokenId) external onlyOwner {
require(_sunsetInitiatedAt[tokenId] == 0);
_sunsetInitiatedAt[tokenId] = now;
emit SunsetInitiated(tokenId);
}
/// @dev Submit a redemption code hash for a specific token. Burns the token. Sets `redemptionCodeHashSubmittedAt` to current timestamp. Decreases `totalSupply` by 1.
/// @param tokenId The id of the token
/// @param __redemptionCodeHash The redemption code hash
function submitRedemptionCodeHash(uint256 tokenId, bytes32 __redemptionCodeHash) external {
_burn(msg.sender, tokenId);
_redemptionCodeHashSubmittedAt[tokenId] = now;
_redemptionCodeHash[tokenId] = __redemptionCodeHash;
_totalSupply = _totalSupply.sub(1);
emit RedemptionCodeHashSubmitted(tokenId, __redemptionCodeHash);
}
/// @dev Transfers the ownership of a given token ID to another address. Usage of this method is discouraged, use `safeTransferFrom` whenever possible. Requires the msg sender to be the owner, approved, or operator
/// @param from current owner of the token
/// @param to address to receive the ownership of the given token ID
/// @param tokenId uint256 ID of the token to be transferred
function transferFrom(address from, address to, uint256 tokenId) public {
if (_sunsetInitiatedAt[tokenId] > 0) {
require(now <= _sunsetInitiatedAt[tokenId].add(_sunsetLength[tokenId]));
}
super.transferFrom(from, to, tokenId);
}
/// @dev Set `tokenUri`. Only `owner` may do this.
/// @param tokenId The id of the token
/// @param tokenURI The token URI
function setTokenURI(uint256 tokenId, string tokenURI) external onlyOwner {
_setTokenURI(tokenId, tokenURI);
}
}