on master help sign in
Add syntax tests for Solidity language.
commitc933be926dfed57f9601c31cef918a3eff86a843 authorErsikan <julien.philippon@epitech.eu> dateMon 29 Mar 2021, 14:50 (6 years ago) parentfc88040
3 files changed+779
tests/syntax-tests/highlighted/Solidity/ERC721.sol+376 tests/syntax-tests/source/Solidity/ERC721.sol+376 tests/syntax-tests/source/Solidity/LICENSE.md+27
tests/syntax-tests/highlighted/Solidity/ERC721.solnew file+376
@@ -0,0 +1,376 @@
1+// SPDX-License-Identifier: MIT
2+
3+pragma solidity ^0.8.0;
4+
5+import "./IERC721.sol";
6+import "./IERC721Receiver.sol";
7+import "./extensions/IERC721Metadata.sol";
8+import "../../utils/Address.sol";
9+import "../../utils/Context.sol";
10+import "../../utils/Strings.sol";
11+import "../../utils/introspection/ERC165.sol";
12+
13+/**
14+ * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
15+ * the Metadata extension, but not including the Enumerable extension, which is available separately as
16+ * {ERC721Enumerable}.
17+ */
18+contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
19+ using Address for address;
20+ using Strings for uint256;
21+
22+ // Token name
23+ string private _name;
24+
25+ // Token symbol
26+ string private _symbol;
27+
28+ // Mapping from token ID to owner address
29+ mapping (uint256 => address) private _owners;
30+
31+ // Mapping owner address to token count
32+ mapping (address => uint256) private _balances;
33+
34+ // Mapping from token ID to approved address
35+ mapping (uint256 => address) private _tokenApprovals;
36+
37+ // Mapping from owner to operator approvals
38+ mapping (address => mapping (address => bool)) private _operatorApprovals;
39+
40+ /**
41+ * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
42+ */
43+ constructor (string memory name_, string memory symbol_) {
44+ _name = name_;
45+ _symbol = symbol_;
46+ }
47+
48+ /**
49+ * @dev See {IERC165-supportsInterface}.
50+ */
51+ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
52+ return interfaceId == type(IERC721).interfaceId
53+ || interfaceId == type(IERC721Metadata).interfaceId
54+ || super.supportsInterface(interfaceId);
55+ }
56+
57+ /**
58+ * @dev See {IERC721-balanceOf}.
59+ */
60+ function balanceOf(address owner) public view virtual override returns (uint256) {
61+ require(owner != address(0), "ERC721: balance query for the zero address");
62+ return _balances[owner];
63+ }
64+
65+ /**
66+ * @dev See {IERC721-ownerOf}.
67+ */
68+ function ownerOf(uint256 tokenId) public view virtual override returns (address) {
69+ address owner = _owners[tokenId];
70+ require(owner != address(0), "ERC721: owner query for nonexistent token");
71+ return owner;
72+ }
73+
74+ /**
75+ * @dev See {IERC721Metadata-name}.
76+ */
77+ function name() public view virtual override returns (string memory) {
78+ return _name;
79+ }
80+
81+ /**
82+ * @dev See {IERC721Metadata-symbol}.
83+ */
84+ function symbol() public view virtual override returns (string memory) {
85+ return _symbol;
86+ }
87+
88+ /**
89+ * @dev See {IERC721Metadata-tokenURI}.
90+ */
91+ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
92+ require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
93+
94+ string memory baseURI = _baseURI();
95+ return bytes(baseURI).length > 0
96+ ? string(abi.encodePacked(baseURI, tokenId.toString()))
97+ : '';
98+ }
99+
100+ /**
101+ * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
102+ * in child contracts.
103+ */
104+ function _baseURI() internal view virtual returns (string memory) {
105+ return "";
106+ }
107+
108+ /**
109+ * @dev See {IERC721-approve}.
110+ */
111+ function approve(address to, uint256 tokenId) public virtual override {
112+ address owner = ERC721.ownerOf(tokenId);
113+ require(to != owner, "ERC721: approval to current owner");
114+
115+ require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
116+ "ERC721: approve caller is not owner nor approved for all"
117+ );
118+
119+ _approve(to, tokenId);
120+ }
121+
122+ /**
123+ * @dev See {IERC721-getApproved}.
124+ */
125+ function getApproved(uint256 tokenId) public view virtual override returns (address) {
126+ require(_exists(tokenId), "ERC721: approved query for nonexistent token");
127+
128+ return _tokenApprovals[tokenId];
129+ }
130+
131+ /**
132+ * @dev See {IERC721-setApprovalForAll}.
133+ */
134+ function setApprovalForAll(address operator, bool approved) public virtual override {
135+ require(operator != _msgSender(), "ERC721: approve to caller");
136+
137+ _operatorApprovals[_msgSender()][operator] = approved;
138+ emit ApprovalForAll(_msgSender(), operator, approved);
139+ }
140+
141+ /**
142+ * @dev See {IERC721-isApprovedForAll}.
143+ */
144+ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
145+ return _operatorApprovals[owner][operator];
146+ }
147+
148+ /**
149+ * @dev See {IERC721-transferFrom}.
150+ */
151+ function transferFrom(address from, address to, uint256 tokenId) public virtual override {
152+ //solhint-disable-next-line max-line-length
153+ require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
154+
155+ _transfer(from, to, tokenId);
156+ }
157+
158+ /**
159+ * @dev See {IERC721-safeTransferFrom}.
160+ */
161+ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
162+ safeTransferFrom(from, to, tokenId, "");
163+ }
164+
165+ /**
166+ * @dev See {IERC721-safeTransferFrom}.
167+ */
168+ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
169+ require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
170+ _safeTransfer(from, to, tokenId, _data);
171+ }
172+
173+ /**
174+ * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
175+ * are aware of the ERC721 protocol to prevent tokens from being forever locked.
176+ *
177+ * `_data` is additional data, it has no specified format and it is sent in call to `to`.
178+ *
179+ * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
180+ * implement alternative mechanisms to perform token transfer, such as signature-based.
181+ *
182+ * Requirements:
183+ *
184+ * - `from` cannot be the zero address.
185+ * - `to` cannot be the zero address.
186+ * - `tokenId` token must exist and be owned by `from`.
187+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
188+ *
189+ * Emits a {Transfer} event.
190+ */
191+ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
192+ _transfer(from, to, tokenId);
193+ require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
194+ }
195+
196+ /**
197+ * @dev Returns whether `tokenId` exists.
198+ *
199+ * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
200+ *
201+ * Tokens start existing when they are minted (`_mint`),
202+ * and stop existing when they are burned (`_burn`).
203+ */
204+ function _exists(uint256 tokenId) internal view virtual returns (bool) {
205+ return _owners[tokenId] != address(0);
206+ }
207+
208+ /**
209+ * @dev Returns whether `spender` is allowed to manage `tokenId`.
210+ *
211+ * Requirements:
212+ *
213+ * - `tokenId` must exist.
214+ */
215+ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
216+ require(_exists(tokenId), "ERC721: operator query for nonexistent token");
217+ address owner = ERC721.ownerOf(tokenId);
218+ return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
219+ }
220+
221+ /**
222+ * @dev Safely mints `tokenId` and transfers it to `to`.
223+ *
224+ * Requirements:
225+ *
226+ * - `tokenId` must not exist.
227+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
228+ *
229+ * Emits a {Transfer} event.
230+ */
231+ function _safeMint(address to, uint256 tokenId) internal virtual {
232+ _safeMint(to, tokenId, "");
233+ }
234+
235+ /**
236+ * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
237+ * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
238+ */
239+ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
240+ _mint(to, tokenId);
241+ require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
242+ }
243+
244+ /**
245+ * @dev Mints `tokenId` and transfers it to `to`.
246+ *
247+ * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
248+ *
249+ * Requirements:
250+ *
251+ * - `tokenId` must not exist.
252+ * - `to` cannot be the zero address.
253+ *
254+ * Emits a {Transfer} event.
255+ */
256+ function _mint(address to, uint256 tokenId) internal virtual {
257+ require(to != address(0), "ERC721: mint to the zero address");
258+ require(!_exists(tokenId), "ERC721: token already minted");
259+
260+ _beforeTokenTransfer(address(0), to, tokenId);
261+
262+ _balances[to] += 1;
263+ _owners[tokenId] = to;
264+
265+ emit Transfer(address(0), to, tokenId);
266+ }
267+
268+ /**
269+ * @dev Destroys `tokenId`.
270+ * The approval is cleared when the token is burned.
271+ *
272+ * Requirements:
273+ *
274+ * - `tokenId` must exist.
275+ *
276+ * Emits a {Transfer} event.
277+ */
278+ function _burn(uint256 tokenId) internal virtual {
279+ address owner = ERC721.ownerOf(tokenId);
280+
281+ _beforeTokenTransfer(owner, address(0), tokenId);
282+
283+ // Clear approvals
284+ _approve(address(0), tokenId);
285+
286+ _balances[owner] -= 1;
287+ delete _owners[tokenId];
288+
289+ emit Transfer(owner, address(0), tokenId);
290+ }
291+
292+ /**
293+ * @dev Transfers `tokenId` from `from` to `to`.
294+ * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
295+ *
296+ * Requirements:
297+ *
298+ * - `to` cannot be the zero address.
299+ * - `tokenId` token must be owned by `from`.
300+ *
301+ * Emits a {Transfer} event.
302+ */
303+ function _transfer(address from, address to, uint256 tokenId) internal virtual {
304+ require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
305+ require(to != address(0), "ERC721: transfer to the zero address");
306+
307+ _beforeTokenTransfer(from, to, tokenId);
308+
309+ // Clear approvals from the previous owner
310+ _approve(address(0), tokenId);
311+
312+ _balances[from] -= 1;
313+ _balances[to] += 1;
314+ _owners[tokenId] = to;
315+
316+ emit Transfer(from, to, tokenId);
317+ }
318+
319+ /**
320+ * @dev Approve `to` to operate on `tokenId`
321+ *
322+ * Emits a {Approval} event.
323+ */
324+ function _approve(address to, uint256 tokenId) internal virtual {
325+ _tokenApprovals[tokenId] = to;
326+ emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
327+ }
328+
329+ /**
330+ * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
331+ * The call is not executed if the target address is not a contract.
332+ *
333+ * @param from address representing the previous owner of the given token ID
334+ * @param to target address that will receive the tokens
335+ * @param tokenId uint256 ID of the token to be transferred
336+ * @param _data bytes optional data to send along with the call
337+ * @return bool whether the call correctly returned the expected magic value
338+ */
339+ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
340+ private returns (bool)
341+ {
342+ if (to.isContract()) {
343+ try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
344+ return retval == IERC721Receiver(to).onERC721Received.selector;
345+ } catch (bytes memory reason) {
346+ if (reason.length == 0) {
347+ revert("ERC721: transfer to non ERC721Receiver implementer");
348+ } else {
349+ // solhint-disable-next-line no-inline-assembly
350+ assembly {
351+ revert(add(32, reason), mload(reason))
352+ }
353+ }
354+ }
355+ } else {
356+ return true;
357+ }
358+ }
359+
360+ /**
361+ * @dev Hook that is called before any token transfer. This includes minting
362+ * and burning.
363+ *
364+ * Calling conditions:
365+ *
366+ * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
367+ * transferred to `to`.
368+ * - When `from` is zero, `tokenId` will be minted for `to`.
369+ * - When `to` is zero, ``from``'s `tokenId` will be burned.
370+ * - `from` cannot be the zero address.
371+ * - `to` cannot be the zero address.
372+ *
373+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
374+ */
375+ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
376+}
tests/syntax-tests/source/Solidity/ERC721.solnew file+376
@@ -0,0 +1,376 @@
1+// SPDX-License-Identifier: MIT
2+
3+pragma solidity ^0.8.0;
4+
5+import "./IERC721.sol";
6+import "./IERC721Receiver.sol";
7+import "./extensions/IERC721Metadata.sol";
8+import "../../utils/Address.sol";
9+import "../../utils/Context.sol";
10+import "../../utils/Strings.sol";
11+import "../../utils/introspection/ERC165.sol";
12+
13+/**
14+ * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
15+ * the Metadata extension, but not including the Enumerable extension, which is available separately as
16+ * {ERC721Enumerable}.
17+ */
18+contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
19+ using Address for address;
20+ using Strings for uint256;
21+
22+ // Token name
23+ string private _name;
24+
25+ // Token symbol
26+ string private _symbol;
27+
28+ // Mapping from token ID to owner address
29+ mapping (uint256 => address) private _owners;
30+
31+ // Mapping owner address to token count
32+ mapping (address => uint256) private _balances;
33+
34+ // Mapping from token ID to approved address
35+ mapping (uint256 => address) private _tokenApprovals;
36+
37+ // Mapping from owner to operator approvals
38+ mapping (address => mapping (address => bool)) private _operatorApprovals;
39+
40+ /**
41+ * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
42+ */
43+ constructor (string memory name_, string memory symbol_) {
44+ _name = name_;
45+ _symbol = symbol_;
46+ }
47+
48+ /**
49+ * @dev See {IERC165-supportsInterface}.
50+ */
51+ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
52+ return interfaceId == type(IERC721).interfaceId
53+ || interfaceId == type(IERC721Metadata).interfaceId
54+ || super.supportsInterface(interfaceId);
55+ }
56+
57+ /**
58+ * @dev See {IERC721-balanceOf}.
59+ */
60+ function balanceOf(address owner) public view virtual override returns (uint256) {
61+ require(owner != address(0), "ERC721: balance query for the zero address");
62+ return _balances[owner];
63+ }
64+
65+ /**
66+ * @dev See {IERC721-ownerOf}.
67+ */
68+ function ownerOf(uint256 tokenId) public view virtual override returns (address) {
69+ address owner = _owners[tokenId];
70+ require(owner != address(0), "ERC721: owner query for nonexistent token");
71+ return owner;
72+ }
73+
74+ /**
75+ * @dev See {IERC721Metadata-name}.
76+ */
77+ function name() public view virtual override returns (string memory) {
78+ return _name;
79+ }
80+
81+ /**
82+ * @dev See {IERC721Metadata-symbol}.
83+ */
84+ function symbol() public view virtual override returns (string memory) {
85+ return _symbol;
86+ }
87+
88+ /**
89+ * @dev See {IERC721Metadata-tokenURI}.
90+ */
91+ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
92+ require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
93+
94+ string memory baseURI = _baseURI();
95+ return bytes(baseURI).length > 0
96+ ? string(abi.encodePacked(baseURI, tokenId.toString()))
97+ : '';
98+ }
99+
100+ /**
101+ * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
102+ * in child contracts.
103+ */
104+ function _baseURI() internal view virtual returns (string memory) {
105+ return "";
106+ }
107+
108+ /**
109+ * @dev See {IERC721-approve}.
110+ */
111+ function approve(address to, uint256 tokenId) public virtual override {
112+ address owner = ERC721.ownerOf(tokenId);
113+ require(to != owner, "ERC721: approval to current owner");
114+
115+ require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
116+ "ERC721: approve caller is not owner nor approved for all"
117+ );
118+
119+ _approve(to, tokenId);
120+ }
121+
122+ /**
123+ * @dev See {IERC721-getApproved}.
124+ */
125+ function getApproved(uint256 tokenId) public view virtual override returns (address) {
126+ require(_exists(tokenId), "ERC721: approved query for nonexistent token");
127+
128+ return _tokenApprovals[tokenId];
129+ }
130+
131+ /**
132+ * @dev See {IERC721-setApprovalForAll}.
133+ */
134+ function setApprovalForAll(address operator, bool approved) public virtual override {
135+ require(operator != _msgSender(), "ERC721: approve to caller");
136+
137+ _operatorApprovals[_msgSender()][operator] = approved;
138+ emit ApprovalForAll(_msgSender(), operator, approved);
139+ }
140+
141+ /**
142+ * @dev See {IERC721-isApprovedForAll}.
143+ */
144+ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
145+ return _operatorApprovals[owner][operator];
146+ }
147+
148+ /**
149+ * @dev See {IERC721-transferFrom}.
150+ */
151+ function transferFrom(address from, address to, uint256 tokenId) public virtual override {
152+ //solhint-disable-next-line max-line-length
153+ require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
154+
155+ _transfer(from, to, tokenId);
156+ }
157+
158+ /**
159+ * @dev See {IERC721-safeTransferFrom}.
160+ */
161+ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
162+ safeTransferFrom(from, to, tokenId, "");
163+ }
164+
165+ /**
166+ * @dev See {IERC721-safeTransferFrom}.
167+ */
168+ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
169+ require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
170+ _safeTransfer(from, to, tokenId, _data);
171+ }
172+
173+ /**
174+ * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
175+ * are aware of the ERC721 protocol to prevent tokens from being forever locked.
176+ *
177+ * `_data` is additional data, it has no specified format and it is sent in call to `to`.
178+ *
179+ * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
180+ * implement alternative mechanisms to perform token transfer, such as signature-based.
181+ *
182+ * Requirements:
183+ *
184+ * - `from` cannot be the zero address.
185+ * - `to` cannot be the zero address.
186+ * - `tokenId` token must exist and be owned by `from`.
187+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
188+ *
189+ * Emits a {Transfer} event.
190+ */
191+ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
192+ _transfer(from, to, tokenId);
193+ require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
194+ }
195+
196+ /**
197+ * @dev Returns whether `tokenId` exists.
198+ *
199+ * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
200+ *
201+ * Tokens start existing when they are minted (`_mint`),
202+ * and stop existing when they are burned (`_burn`).
203+ */
204+ function _exists(uint256 tokenId) internal view virtual returns (bool) {
205+ return _owners[tokenId] != address(0);
206+ }
207+
208+ /**
209+ * @dev Returns whether `spender` is allowed to manage `tokenId`.
210+ *
211+ * Requirements:
212+ *
213+ * - `tokenId` must exist.
214+ */
215+ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
216+ require(_exists(tokenId), "ERC721: operator query for nonexistent token");
217+ address owner = ERC721.ownerOf(tokenId);
218+ return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
219+ }
220+
221+ /**
222+ * @dev Safely mints `tokenId` and transfers it to `to`.
223+ *
224+ * Requirements:
225+ *
226+ * - `tokenId` must not exist.
227+ * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
228+ *
229+ * Emits a {Transfer} event.
230+ */
231+ function _safeMint(address to, uint256 tokenId) internal virtual {
232+ _safeMint(to, tokenId, "");
233+ }
234+
235+ /**
236+ * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
237+ * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
238+ */
239+ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
240+ _mint(to, tokenId);
241+ require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
242+ }
243+
244+ /**
245+ * @dev Mints `tokenId` and transfers it to `to`.
246+ *
247+ * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
248+ *
249+ * Requirements:
250+ *
251+ * - `tokenId` must not exist.
252+ * - `to` cannot be the zero address.
253+ *
254+ * Emits a {Transfer} event.
255+ */
256+ function _mint(address to, uint256 tokenId) internal virtual {
257+ require(to != address(0), "ERC721: mint to the zero address");
258+ require(!_exists(tokenId), "ERC721: token already minted");
259+
260+ _beforeTokenTransfer(address(0), to, tokenId);
261+
262+ _balances[to] += 1;
263+ _owners[tokenId] = to;
264+
265+ emit Transfer(address(0), to, tokenId);
266+ }
267+
268+ /**
269+ * @dev Destroys `tokenId`.
270+ * The approval is cleared when the token is burned.
271+ *
272+ * Requirements:
273+ *
274+ * - `tokenId` must exist.
275+ *
276+ * Emits a {Transfer} event.
277+ */
278+ function _burn(uint256 tokenId) internal virtual {
279+ address owner = ERC721.ownerOf(tokenId);
280+
281+ _beforeTokenTransfer(owner, address(0), tokenId);
282+
283+ // Clear approvals
284+ _approve(address(0), tokenId);
285+
286+ _balances[owner] -= 1;
287+ delete _owners[tokenId];
288+
289+ emit Transfer(owner, address(0), tokenId);
290+ }
291+
292+ /**
293+ * @dev Transfers `tokenId` from `from` to `to`.
294+ * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
295+ *
296+ * Requirements:
297+ *
298+ * - `to` cannot be the zero address.
299+ * - `tokenId` token must be owned by `from`.
300+ *
301+ * Emits a {Transfer} event.
302+ */
303+ function _transfer(address from, address to, uint256 tokenId) internal virtual {
304+ require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
305+ require(to != address(0), "ERC721: transfer to the zero address");
306+
307+ _beforeTokenTransfer(from, to, tokenId);
308+
309+ // Clear approvals from the previous owner
310+ _approve(address(0), tokenId);
311+
312+ _balances[from] -= 1;
313+ _balances[to] += 1;
314+ _owners[tokenId] = to;
315+
316+ emit Transfer(from, to, tokenId);
317+ }
318+
319+ /**
320+ * @dev Approve `to` to operate on `tokenId`
321+ *
322+ * Emits a {Approval} event.
323+ */
324+ function _approve(address to, uint256 tokenId) internal virtual {
325+ _tokenApprovals[tokenId] = to;
326+ emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
327+ }
328+
329+ /**
330+ * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
331+ * The call is not executed if the target address is not a contract.
332+ *
333+ * @param from address representing the previous owner of the given token ID
334+ * @param to target address that will receive the tokens
335+ * @param tokenId uint256 ID of the token to be transferred
336+ * @param _data bytes optional data to send along with the call
337+ * @return bool whether the call correctly returned the expected magic value
338+ */
339+ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
340+ private returns (bool)
341+ {
342+ if (to.isContract()) {
343+ try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
344+ return retval == IERC721Receiver(to).onERC721Received.selector;
345+ } catch (bytes memory reason) {
346+ if (reason.length == 0) {
347+ revert("ERC721: transfer to non ERC721Receiver implementer");
348+ } else {
349+ // solhint-disable-next-line no-inline-assembly
350+ assembly {
351+ revert(add(32, reason), mload(reason))
352+ }
353+ }
354+ }
355+ } else {
356+ return true;
357+ }
358+ }
359+
360+ /**
361+ * @dev Hook that is called before any token transfer. This includes minting
362+ * and burning.
363+ *
364+ * Calling conditions:
365+ *
366+ * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
367+ * transferred to `to`.
368+ * - When `from` is zero, `tokenId` will be minted for `to`.
369+ * - When `to` is zero, ``from``'s `tokenId` will be burned.
370+ * - `from` cannot be the zero address.
371+ * - `to` cannot be the zero address.
372+ *
373+ * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
374+ */
375+ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
376+}
tests/syntax-tests/source/Solidity/LICENSE.mdnew file+27
@@ -0,0 +1,27 @@
1+The `ERC721.sol` file has been added from
2+[](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol)
3+under the following license:
4+
5+The MIT License (MIT)
6+
7+Copyright (c) 2016-2020 zOS Global Limited
8+
9+Permission is hereby granted, free of charge, to any person obtaining
10+a copy of this software and associated documentation files (the
11+"Software"), to deal in the Software without restriction, including
12+without limitation the rights to use, copy, modify, merge, publish,
13+distribute, sublicense, and/or sell copies of the Software, and to
14+permit persons to whom the Software is furnished to do so, subject to
15+the following conditions:
16+
17+The above copyright notice and this permission notice shall be included
18+in all copies or substantial portions of the Software.
19+
20+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27+