/
LandV3.sol
201 lines (184 loc) · 7.14 KB
/
LandV3.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/* solhint-disable no-empty-blocks */
pragma solidity 0.5.9;
import "./Land/erc721/LandBaseTokenV3.sol";
import "./Land/erc721/ERC721BaseTokenV2.sol";
import "./OperatorFilterer/contracts/upgradeable/OperatorFiltererUpgradeable.sol";
contract LandV3 is LandBaseTokenV3, OperatorFiltererUpgradeable {
/**
* @notice Return the name of the token contract
* @return The name of the token contract
*/
function name() external pure returns (string memory) {
return "Sandbox's LANDs";
}
/**
* @notice Return the symbol of the token contract
* @return The symbol of the token contract
*/
function symbol() external pure returns (string memory) {
return "LAND";
}
// solium-disable-next-line security/no-assign-params
function uint2str(uint256 _i) internal pure returns (string memory) {
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len - 1;
while (_i != 0) {
bstr[k--] = byte(uint8(48 + (_i % 10)));
_i /= 10;
}
return string(bstr);
}
/**
* @notice Return the URI of a specific token
* @param id The id of the token
* @return The URI of the token
*/
function tokenURI(uint256 id) public view returns (string memory) {
require(_ownerOf(id) != address(0), "LandV3: Id does not exist");
return string(abi.encodePacked("https://api.sandbox.game/lands/", uint2str(id), "/metadata.json"));
}
/**
* @notice Check if the contract supports an interface
* 0x01ffc9a7 is ERC-165
* 0x80ac58cd is ERC-721
* 0x5b5e139f is ERC-721 metadata
* @param id The id of the interface
* @return True if the interface is supported
*/
function supportsInterface(bytes4 id) external pure returns (bool) {
return id == 0x01ffc9a7 || id == 0x80ac58cd || id == 0x5b5e139f;
}
/// @notice This function is used to register Land contract on the Operator Filterer Registry of Opensea.can only be called by admin.
/// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.
/// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.
/// @param subscribe bool to signify subscription "true"" or to copy the list "false".
function register(address subscriptionOrRegistrantToCopy, bool subscribe) external onlyAdmin {
require(subscriptionOrRegistrantToCopy != address(0),"LandV3: subscription can't be zero address");
_register(subscriptionOrRegistrantToCopy, subscribe);
}
/// @notice sets filter registry address deployed in test
/// @param registry the address of the registry
function setOperatorRegistry(address registry) external onlyAdmin {
operatorFilterRegistry = IOperatorFilterRegistry(registry);
}
/**
* @notice Approve an operator to spend tokens on the sender behalf
* @param sender The address giving the approval
* @param operator The address receiving the approval
* @param id The id of the token
*/
function approveFor(
address sender,
address operator,
uint256 id
) external onlyAllowedOperatorApproval(operator) {
address owner = _ownerOf(id);
require(sender != address(0), "LandV3: sender is zero address");
require(
msg.sender == sender ||
_metaTransactionContracts[msg.sender] ||
_operatorsForAll[sender][msg.sender] ||
_superOperators[msg.sender],
"LandV3: not authorized to approve"
);
require(owner == sender, "LandV3: owner != sender");
_approveFor(owner, operator, id);
}
/**
* @notice Set the approval for an operator to manage all the tokens of the sender
* @param operator The address receiving the approval
* @param approved The determination of the approval
*/
function setApprovalForAll(address operator, bool approved) external onlyAllowedOperatorApproval(operator) {
_setApprovalForAll(msg.sender, operator, approved);
}
/**
* @notice Set the approval for an operator to manage all the tokens of the sender
* @param sender The address giving the approval
* @param operator The address receiving the approval
* @param approved The determination of the approval
*/
function setApprovalForAllFor(
address sender,
address operator,
bool approved
) external onlyAllowedOperatorApproval(operator) {
require(sender != address(0), "LandV3: Invalid sender address");
require(
msg.sender == sender || _metaTransactionContracts[msg.sender] || _superOperators[msg.sender],
"LandV3: not authorized to approve for all"
);
_setApprovalForAll(sender, operator, approved);
}
/**
* @notice Approve an operator to spend tokens on the sender behalf
* @param operator The address receiving the approval
* @param id The id of the token
*/
function approve(address operator, uint256 id) external onlyAllowedOperatorApproval(operator) {
address owner = _ownerOf(id);
require(owner != address(0), "LandV3: token does not exist");
require(
owner == msg.sender || _operatorsForAll[owner][msg.sender] || _superOperators[msg.sender],
"LandV3: not authorized to approve"
);
_approveFor(owner, operator, id);
}
/**
* @notice Transfer a token between 2 addresses
* @param from The sender of the token
* @param to The recipient of the token
* @param id The id of the token
*/
function transferFrom(
address from,
address to,
uint256 id
) external onlyAllowedOperator(from) {
bool metaTx = _checkTransfer(from, to, id);
_transferFrom(from, to, id);
if (to.isContract() && _checkInterfaceWith10000Gas(to, ERC721_MANDATORY_RECEIVER)) {
require(
_checkOnERC721Received(metaTx ? from : msg.sender, from, to, id, ""),
"LandV3: erc721 transfer rejected by to"
);
}
}
/**
* @notice Transfer a token between 2 addresses letting the receiver knows of the transfer
* @param from The sender of the token
* @param to The recipient of the token
* @param id The id of the token
* @param data Additional data
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes memory data
) public onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, id, data);
}
/**
* @notice Transfer a token between 2 addresses letting the receiver knows of the transfer
* @param from The send of the token
* @param to The recipient of the token
* @param id The id of the token
*/
function safeTransferFrom(
address from,
address to,
uint256 id
) external onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, id, "");
}
}