ERC721.sol 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)
  3. pragma solidity ^0.8.19;
  4. import {IERC721} from "./IERC721.sol";
  5. import {IERC721Receiver} from "./IERC721Receiver.sol";
  6. import {IERC721Metadata} from "./extensions/IERC721Metadata.sol";
  7. import {Context} from "../../utils/Context.sol";
  8. import {Strings} from "../../utils/Strings.sol";
  9. import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol";
  10. import {IERC721Errors} from "../../interfaces/draft-IERC6093.sol";
  11. /**
  12. * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
  13. * the Metadata extension, but not including the Enumerable extension, which is available separately as
  14. * {ERC721Enumerable}.
  15. */
  16. abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
  17. using Strings for uint256;
  18. // Token name
  19. string private _name;
  20. // Token symbol
  21. string private _symbol;
  22. // Mapping from token ID to owner address
  23. mapping(uint256 => address) private _owners;
  24. // Mapping owner address to token count
  25. mapping(address => uint256) private _balances;
  26. // Mapping from token ID to approved address
  27. mapping(uint256 => address) private _tokenApprovals;
  28. // Mapping from owner to operator approvals
  29. mapping(address => mapping(address => bool)) private _operatorApprovals;
  30. /**
  31. * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
  32. */
  33. constructor(string memory name_, string memory symbol_) {
  34. _name = name_;
  35. _symbol = symbol_;
  36. }
  37. /**
  38. * @dev See {IERC165-supportsInterface}.
  39. */
  40. function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
  41. return
  42. interfaceId == type(IERC721).interfaceId ||
  43. interfaceId == type(IERC721Metadata).interfaceId ||
  44. super.supportsInterface(interfaceId);
  45. }
  46. /**
  47. * @dev See {IERC721-balanceOf}.
  48. */
  49. function balanceOf(address owner) public view virtual returns (uint256) {
  50. if (owner == address(0)) {
  51. revert ERC721InvalidOwner(address(0));
  52. }
  53. return _balances[owner];
  54. }
  55. /**
  56. * @dev See {IERC721-ownerOf}.
  57. */
  58. function ownerOf(uint256 tokenId) public view virtual returns (address) {
  59. address owner = _ownerOf(tokenId);
  60. if (owner == address(0)) {
  61. revert ERC721NonexistentToken(tokenId);
  62. }
  63. return owner;
  64. }
  65. /**
  66. * @dev See {IERC721Metadata-name}.
  67. */
  68. function name() public view virtual returns (string memory) {
  69. return _name;
  70. }
  71. /**
  72. * @dev See {IERC721Metadata-symbol}.
  73. */
  74. function symbol() public view virtual returns (string memory) {
  75. return _symbol;
  76. }
  77. /**
  78. * @dev See {IERC721Metadata-tokenURI}.
  79. */
  80. function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
  81. _requireMinted(tokenId);
  82. string memory baseURI = _baseURI();
  83. return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : "";
  84. }
  85. /**
  86. * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
  87. * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
  88. * by default, can be overridden in child contracts.
  89. */
  90. function _baseURI() internal view virtual returns (string memory) {
  91. return "";
  92. }
  93. /**
  94. * @dev See {IERC721-approve}.
  95. */
  96. function approve(address to, uint256 tokenId) public virtual {
  97. _approve(to, tokenId, _msgSender());
  98. }
  99. /**
  100. * @dev See {IERC721-getApproved}.
  101. */
  102. function getApproved(uint256 tokenId) public view virtual returns (address) {
  103. _requireMinted(tokenId);
  104. return _getApproved(tokenId);
  105. }
  106. /**
  107. * @dev See {IERC721-setApprovalForAll}.
  108. */
  109. function setApprovalForAll(address operator, bool approved) public virtual {
  110. _setApprovalForAll(_msgSender(), operator, approved);
  111. }
  112. /**
  113. * @dev See {IERC721-isApprovedForAll}.
  114. */
  115. function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {
  116. return _operatorApprovals[owner][operator];
  117. }
  118. /**
  119. * @dev See {IERC721-transferFrom}.
  120. */
  121. function transferFrom(address from, address to, uint256 tokenId) public virtual {
  122. if (to == address(0)) {
  123. revert ERC721InvalidReceiver(address(0));
  124. }
  125. // Setting an "auth" arguments enables the `_isApproved` check which verifies that the token exists
  126. // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
  127. address previousOwner = _update(to, tokenId, _msgSender());
  128. if (previousOwner != from) {
  129. revert ERC721IncorrectOwner(from, tokenId, previousOwner);
  130. }
  131. }
  132. /**
  133. * @dev See {IERC721-safeTransferFrom}.
  134. */
  135. function safeTransferFrom(address from, address to, uint256 tokenId) public {
  136. safeTransferFrom(from, to, tokenId, "");
  137. }
  138. /**
  139. * @dev See {IERC721-safeTransferFrom}.
  140. */
  141. function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
  142. transferFrom(from, to, tokenId);
  143. _checkOnERC721Received(from, to, tokenId, data);
  144. }
  145. /**
  146. * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
  147. *
  148. * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
  149. * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances
  150. * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by
  151. * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.
  152. */
  153. function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
  154. return _owners[tokenId];
  155. }
  156. /**
  157. * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.
  158. */
  159. function _getApproved(uint256 tokenId) internal view virtual returns (address) {
  160. return _tokenApprovals[tokenId];
  161. }
  162. /**
  163. * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
  164. * particular (ignoring whether it is owned by `owner`).
  165. *
  166. * WARNING: This function doesn't check that `owner` is the actual owner of `tokenId`.
  167. */
  168. function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
  169. return
  170. spender != address(0) &&
  171. (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
  172. }
  173. /**
  174. * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
  175. * Reverts if `spender` has not approval for all assets of the provided `owner` nor the actual owner approved the `spender` for the specific `tokenId`.
  176. *
  177. * WARNING: This function relies on {_isAuthorized}, so it doesn't check whether `owner` is the
  178. * actual owner of `tokenId`.
  179. */
  180. function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
  181. if (!_isAuthorized(owner, spender, tokenId)) {
  182. if (owner == address(0)) {
  183. revert ERC721NonexistentToken(tokenId);
  184. } else {
  185. revert ERC721InsufficientApproval(spender, tokenId);
  186. }
  187. }
  188. }
  189. /**
  190. * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
  191. *
  192. * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that
  193. * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
  194. *
  195. * WARNING: Increasing an account's balance using this function tends to be paired with an override of the
  196. * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
  197. * remain consistent with one another.
  198. */
  199. function _increaseBalance(address account, uint128 value) internal virtual {
  200. unchecked {
  201. _balances[account] += value;
  202. }
  203. }
  204. /**
  205. * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
  206. * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
  207. *
  208. * The `auth` argument is optional. If the value passed is non 0, then this function will check that
  209. * `auth` is either the owner of the token, or approved to operate on the token (by the owner).
  210. *
  211. * Emits a {Transfer} event.
  212. *
  213. * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
  214. */
  215. function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
  216. address from = _ownerOf(tokenId);
  217. // Perform (optional) operator check
  218. if (auth != address(0)) {
  219. _checkAuthorized(from, auth, tokenId);
  220. }
  221. // Execute the update
  222. if (from != address(0)) {
  223. delete _tokenApprovals[tokenId];
  224. unchecked {
  225. _balances[from] -= 1;
  226. }
  227. }
  228. if (to != address(0)) {
  229. unchecked {
  230. _balances[to] += 1;
  231. }
  232. }
  233. _owners[tokenId] = to;
  234. emit Transfer(from, to, tokenId);
  235. return from;
  236. }
  237. /**
  238. * @dev Mints `tokenId` and transfers it to `to`.
  239. *
  240. * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
  241. *
  242. * Requirements:
  243. *
  244. * - `tokenId` must not exist.
  245. * - `to` cannot be the zero address.
  246. *
  247. * Emits a {Transfer} event.
  248. */
  249. function _mint(address to, uint256 tokenId) internal {
  250. if (to == address(0)) {
  251. revert ERC721InvalidReceiver(address(0));
  252. }
  253. address previousOwner = _update(to, tokenId, address(0));
  254. if (previousOwner != address(0)) {
  255. revert ERC721InvalidSender(address(0));
  256. }
  257. }
  258. /**
  259. * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.
  260. *
  261. * Requirements:
  262. *
  263. * - `tokenId` must not exist.
  264. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
  265. *
  266. * Emits a {Transfer} event.
  267. */
  268. function _safeMint(address to, uint256 tokenId) internal {
  269. _safeMint(to, tokenId, "");
  270. }
  271. /**
  272. * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
  273. * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
  274. */
  275. function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {
  276. _mint(to, tokenId);
  277. _checkOnERC721Received(address(0), to, tokenId, data);
  278. }
  279. /**
  280. * @dev Destroys `tokenId`.
  281. * The approval is cleared when the token is burned.
  282. * This is an internal function that does not check if the sender is authorized to operate on the token.
  283. *
  284. * Requirements:
  285. *
  286. * - `tokenId` must exist.
  287. *
  288. * Emits a {Transfer} event.
  289. */
  290. function _burn(uint256 tokenId) internal {
  291. address previousOwner = _update(address(0), tokenId, address(0));
  292. if (previousOwner == address(0)) {
  293. revert ERC721NonexistentToken(tokenId);
  294. }
  295. }
  296. /**
  297. * @dev Transfers `tokenId` from `from` to `to`.
  298. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
  299. *
  300. * Requirements:
  301. *
  302. * - `to` cannot be the zero address.
  303. * - `tokenId` token must exists and be owned by `from`.
  304. *
  305. * Emits a {Transfer} event.
  306. */
  307. function _transfer(address from, address to, uint256 tokenId) internal {
  308. if (to == address(0)) {
  309. revert ERC721InvalidReceiver(address(0));
  310. }
  311. address previousOwner = _update(to, tokenId, address(0));
  312. if (previousOwner == address(0)) {
  313. revert ERC721NonexistentToken(tokenId);
  314. } else if (previousOwner != from) {
  315. revert ERC721IncorrectOwner(from, tokenId, previousOwner);
  316. }
  317. }
  318. /**
  319. * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients
  320. * are aware of the ERC721 standard to prevent tokens from being forever locked.
  321. *
  322. * `data` is additional data, it has no specified format and it is sent in call to `to`.
  323. *
  324. * This internal function is like {safeTransferFrom} in the sense that it invokes
  325. * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
  326. * implement alternative mechanisms to perform token transfer, such as signature-based.
  327. *
  328. * Requirements:
  329. *
  330. * - `tokenId` token must exist and be owned by `from`.
  331. * - `to` cannot be the zero address.
  332. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
  333. *
  334. * Emits a {Transfer} event.
  335. */
  336. function _safeTransfer(address from, address to, uint256 tokenId) internal {
  337. _safeTransfer(from, to, tokenId, "");
  338. }
  339. /**
  340. * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is
  341. * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
  342. */
  343. function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
  344. _transfer(from, to, tokenId);
  345. _checkOnERC721Received(from, to, tokenId, data);
  346. }
  347. /**
  348. * @dev Approve `to` to operate on `tokenId`
  349. *
  350. * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is
  351. * either the owner of the token, or approved to operate on all tokens held by this owner.
  352. *
  353. * Emits an {Approval} event.
  354. */
  355. function _approve(address to, uint256 tokenId, address auth) internal virtual returns (address) {
  356. address owner = ownerOf(tokenId);
  357. if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
  358. revert ERC721InvalidApprover(auth);
  359. }
  360. _tokenApprovals[tokenId] = to;
  361. emit Approval(owner, to, tokenId);
  362. return owner;
  363. }
  364. /**
  365. * @dev Approve `operator` to operate on all of `owner` tokens
  366. *
  367. * Requirements:
  368. * - operator can't be the address zero.
  369. *
  370. * Emits an {ApprovalForAll} event.
  371. */
  372. function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
  373. if (operator == address(0)) {
  374. revert ERC721InvalidOperator(operator);
  375. }
  376. _operatorApprovals[owner][operator] = approved;
  377. emit ApprovalForAll(owner, operator, approved);
  378. }
  379. /**
  380. * @dev Reverts if the `tokenId` has not been minted yet.
  381. */
  382. function _requireMinted(uint256 tokenId) internal view virtual {
  383. if (_ownerOf(tokenId) == address(0)) {
  384. revert ERC721NonexistentToken(tokenId);
  385. }
  386. }
  387. /**
  388. * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the
  389. * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract.
  390. *
  391. * @param from address representing the previous owner of the given token ID
  392. * @param to target address that will receive the tokens
  393. * @param tokenId uint256 ID of the token to be transferred
  394. * @param data bytes optional data to send along with the call
  395. */
  396. function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
  397. if (to.code.length > 0) {
  398. try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
  399. if (retval != IERC721Receiver.onERC721Received.selector) {
  400. revert ERC721InvalidReceiver(to);
  401. }
  402. } catch (bytes memory reason) {
  403. if (reason.length == 0) {
  404. revert ERC721InvalidReceiver(to);
  405. } else {
  406. /// @solidity memory-safe-assembly
  407. assembly {
  408. revert(add(32, reason), mload(reason))
  409. }
  410. }
  411. }
  412. }
  413. }
  414. }