Skip to content

Commit 64e3c45

Browse files
committed
Update validator.
1 parent 7d0cd23 commit 64e3c45

File tree

10 files changed

+9364
-2062
lines changed

10 files changed

+9364
-2062
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ This is an open source package for NodeJS written with [TypeScript](https://www.
88

99
This package is actively maintained, well tested and already used in production environments. The source code is available on [GitHub](https://github.com/0xcert/erc721-validator) where you can also find our [issue tracker](https://github.com/0xcert/erc721-validator/issues).
1010

11+
## How it works
12+
13+
For more information on how the validator works please check the [article explaining the technique](https://medium.com/hackernoon/https-medium-com-momannn-live-testing-smart-contracts-with-estimategas-f45429086c3a).
14+
1115
## Installation
1216

1317
Run the command below to install the package.

contracts/validator.sol

+39-121
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,6 @@
1-
pragma solidity ^0.4.24;
1+
// SPDX-License-Identifier: MIT
22

3-
/**
4-
* @dev Math operations with safety checks that throw on error. This contract is based
5-
* on the source code at https://goo.gl/iyQsmU.
6-
*/
7-
library SafeMath {
8-
9-
/**
10-
* @dev Multiplies two numbers, throws on overflow.
11-
* @param _a Factor number.
12-
* @param _b Factor number.
13-
*/
14-
function mul(
15-
uint256 _a,
16-
uint256 _b
17-
)
18-
internal
19-
pure
20-
returns (uint256)
21-
{
22-
if (_a == 0) {
23-
return 0;
24-
}
25-
uint256 c = _a * _b;
26-
assert(c / _a == _b);
27-
return c;
28-
}
29-
30-
/**
31-
* @dev Integer division of two numbers, truncating the quotient.
32-
* @param _a Dividend number.
33-
* @param _b Divisor number.
34-
*/
35-
function div(
36-
uint256 _a,
37-
uint256 _b
38-
)
39-
internal
40-
pure
41-
returns (uint256)
42-
{
43-
uint256 c = _a / _b;
44-
// assert(b > 0); // Solidity automatically throws when dividing by 0
45-
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
46-
return c;
47-
}
48-
49-
/**
50-
* @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
51-
* @param _a Minuend number.
52-
* @param _b Subtrahend number.
53-
*/
54-
function sub(
55-
uint256 _a,
56-
uint256 _b
57-
)
58-
internal
59-
pure
60-
returns (uint256)
61-
{
62-
assert(_b <= _a);
63-
return _a - _b;
64-
}
65-
66-
/**
67-
* @dev Adds two numbers, throws on overflow.
68-
* @param _a Number.
69-
* @param _b Number.
70-
*/
71-
function add(
72-
uint256 _a,
73-
uint256 _b
74-
)
75-
internal
76-
pure
77-
returns (uint256)
78-
{
79-
uint256 c = _a + _b;
80-
assert(c >= _a);
81-
return c;
82-
}
83-
}
3+
pragma solidity ^0.8.7;
844

855
/**
866
* @dev Utility library of inline functions on addresses.
@@ -96,19 +16,19 @@ library AddressUtils {
9616
)
9717
internal
9818
view
99-
returns (bool)
19+
returns (bool addressCheck)
10020
{
101-
uint256 size;
102-
103-
/**
104-
* XXX Currently there is no better way to check if there is a contract in an address than to
105-
* check the size of the code at that address.
106-
* See https://ethereum.stackexchange.com/a/14016/36603 for more details about how this works.
107-
* TODO: Check this again before the Serenity release, because all addresses will be
108-
* contracts then.
109-
*/
110-
assembly { size := extcodesize(_addr) } // solium-disable-line security/no-inline-assembly
111-
return size > 0;
21+
// This method relies in extcodesize, which returns 0 for contracts in
22+
// construction, since the code is only stored at the end of the
23+
// constructor execution.
24+
25+
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
26+
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
27+
// for accounts without code, i.e. `keccak256('')`
28+
bytes32 codehash;
29+
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
30+
assembly { codehash := extcodehash(_addr) } // solhint-disable-line
31+
addressCheck = (codehash != 0x0 && codehash != accountHash);
11232
}
11333

11434
}
@@ -191,7 +111,7 @@ interface ERC721 {
191111
address _from,
192112
address _to,
193113
uint256 _tokenId,
194-
bytes _data
114+
bytes calldata _data
195115
)
196116
external;
197117

@@ -335,15 +255,15 @@ interface ERC721Metadata {
335255
function name()
336256
external
337257
view
338-
returns (string _name);
258+
returns (string memory _name);
339259

340260
/**
341261
* @dev Returns a abbreviated name for a collection of NFTs in this contract.
342262
*/
343263
function symbol()
344264
external
345265
view
346-
returns (string _symbol);
266+
returns (string memory _symbol);
347267

348268
/**
349269
* @dev Returns a distinct Uniform Resource Identifier (URI) for a given asset. It Throws if
@@ -353,7 +273,7 @@ interface ERC721Metadata {
353273
function tokenURI(uint256 _tokenId)
354274
external
355275
view
356-
returns (string);
276+
returns (string memory);
357277

358278
}
359279

@@ -378,7 +298,7 @@ interface ERC721TokenReceiver {
378298
address _operator,
379299
address _from,
380300
uint256 _tokenId,
381-
bytes _data
301+
bytes calldata _data
382302
)
383303
external
384304
returns(bytes4);
@@ -408,7 +328,6 @@ interface ERC165 {
408328
contract BasicValidator
409329
{
410330
using AddressUtils for address;
411-
using SafeMath for uint256;
412331

413332
bytes4 constant ERC165ID = 0x01ffc9a7;
414333
bytes4 constant ERC721ID = 0x80ac58cd;
@@ -419,7 +338,6 @@ contract BasicValidator
419338
uint256 _caseId,
420339
address _target
421340
)
422-
public
423341
{
424342
if (_caseId == 1) {
425343
sanityCheck(_target);
@@ -589,8 +507,9 @@ contract Stub1 is
589507
address _operator,
590508
address _from,
591509
uint256 _tokenId,
592-
bytes _data
510+
bytes calldata _data
593511
)
512+
override
594513
external
595514
returns(bytes4)
596515
{
@@ -621,8 +540,9 @@ contract Stub2 is
621540
address _operator,
622541
address _from,
623542
uint256 _tokenId,
624-
bytes _data
543+
bytes calldata _data
625544
)
545+
override
626546
external
627547
returns(bytes4)
628548
{
@@ -645,8 +565,9 @@ contract Stub3 is
645565
address _operator,
646566
address _from,
647567
uint256 _tokenId,
648-
bytes _data
568+
bytes calldata _data
649569
)
570+
override
650571
external
651572
returns(bytes4)
652573
{
@@ -666,7 +587,6 @@ contract TokenValidator
666587
address _target,
667588
uint256 _tokenId
668589
)
669-
public
670590
{
671591
if (_caseId == 1) {
672592
checkTokenUri(_target, _tokenId);
@@ -721,7 +641,6 @@ contract TokenValidator
721641

722642
contract TransferValidator
723643
{
724-
using SafeMath for uint256;
725644
bytes4 constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02;
726645
address constant stubAddress = 0x85A9916425960aA35B2a527D77C71855DC0215B3;
727646

@@ -731,7 +650,6 @@ contract TransferValidator
731650
uint256 _tokenId,
732651
address _giver
733652
)
734-
public
735653
payable
736654
{
737655
if (_caseId == 1) {
@@ -800,7 +718,7 @@ contract TransferValidator
800718
)
801719
internal
802720
{
803-
Giver(_giver).getToken.value(1000000 ether)(_target, _tokenId);
721+
Giver(_giver).getToken{value:1000000 ether}(_target, _tokenId);
804722
}
805723

806724
/**
@@ -829,7 +747,7 @@ contract TransferValidator
829747
{
830748
uint256 balance = ERC721(_target).balanceOf(stubAddress);
831749
ERC721(_target).transferFrom(address(this), stubAddress, _tokenId);
832-
require(ERC721(_target).balanceOf(stubAddress) == balance.add(1));
750+
require(ERC721(_target).balanceOf(stubAddress) == balance + 1);
833751
}
834752
/**
835753
* @dev Get a token from giver, transferFrom to zero address, should throw.
@@ -854,7 +772,7 @@ contract TransferValidator
854772
internal
855773
{
856774
Stub2 stub = new Stub2();
857-
ERC721(_target).safeTransferFrom(address(this), stub, _tokenId, "ffff");
775+
ERC721(_target).safeTransferFrom(address(this), address(stub), _tokenId, "ffff");
858776
}
859777

860778
/**
@@ -868,7 +786,7 @@ contract TransferValidator
868786
internal
869787
{
870788
Stub1 stub = new Stub1();
871-
ERC721(_target).safeTransferFrom(address(this), stub, _tokenId);
789+
ERC721(_target).safeTransferFrom(address(this), address(stub), _tokenId);
872790
}
873791

874792
/**
@@ -882,7 +800,7 @@ contract TransferValidator
882800
internal
883801
{
884802
Stub4 stub = new Stub4();
885-
ERC721(_target).safeTransferFrom(address(this), stub, _tokenId, "ffff");
803+
ERC721(_target).safeTransferFrom(address(this), address(stub), _tokenId, "ffff");
886804
}
887805

888806
/**
@@ -896,7 +814,7 @@ contract TransferValidator
896814
internal
897815
{
898816
Stub3 stub = new Stub3();
899-
ERC721(_target).safeTransferFrom(address(this), stub, _tokenId);
817+
ERC721(_target).safeTransferFrom(address(this), address(stub), _tokenId);
900818
}
901819

902820
/**
@@ -922,10 +840,10 @@ contract TransferValidator
922840
internal
923841
{
924842
Stub1 stub = new Stub1();
925-
ERC721(_target).approve(stub, _tokenId);
843+
ERC721(_target).approve(address(stub), _tokenId);
926844
uint256 balance = ERC721(_target).balanceOf(stubAddress);
927845
stub.transferToken(_target, _tokenId, stubAddress);
928-
require(ERC721(_target).balanceOf(stubAddress) == balance.add(1));
846+
require(ERC721(_target).balanceOf(stubAddress) == balance + 1);
929847
}
930848

931849
/**
@@ -951,10 +869,10 @@ contract TransferValidator
951869
internal
952870
{
953871
Stub1 stub = new Stub1();
954-
ERC721(_target).setApprovalForAll(stub, true);
872+
ERC721(_target).setApprovalForAll(address(stub), true);
955873
uint256 balance = ERC721(_target).balanceOf(stubAddress);
956874
stub.transferToken(_target, _tokenId, stubAddress);
957-
require(ERC721(_target).balanceOf(stubAddress) == balance.add(1));
875+
require(ERC721(_target).balanceOf(stubAddress) == balance + 1);
958876
}
959877

960878
/**
@@ -987,7 +905,7 @@ library StringUtils {
987905
/// @dev Does a byte-by-byte lexicographical comparison of two strings.
988906
/// @return a negative number if `_a` is smaller, zero if they are equal
989907
/// and a positive numbe if `_b` is smaller.
990-
function compare(string _a, string _b) internal returns (int) {
908+
function compare(string memory _a, string memory _b) internal returns (int) {
991909
bytes memory a = bytes(_a);
992910
bytes memory b = bytes(_b);
993911
uint minLength = a.length;
@@ -1005,7 +923,7 @@ library StringUtils {
1005923
return 0;
1006924
}
1007925

1008-
function compare2(bytes _a, string _b) internal returns (int) {
926+
function compare2(bytes memory _a, string memory _b) internal returns (int) {
1009927
bytes memory a = _a;
1010928
bytes memory b = bytes(_b);
1011929
uint minLength = a.length;
@@ -1023,12 +941,12 @@ library StringUtils {
1023941
return 0;
1024942
}
1025943
/// @dev Compares two strings and returns true iff they are equal.
1026-
function equal(string _a, string _b) internal returns (bool) {
944+
function equal(string memory _a, string memory _b) internal returns (bool) {
1027945
return compare(_a, _b) == 0;
1028946
}
1029947

1030948
/// @dev Finds the index of the first occurrence of _needle in _haystack
1031-
function indexOf(string _haystack, string _needle) internal returns (int)
949+
function indexOf(string memory _haystack, string memory _needle) internal returns (int)
1032950
{
1033951
bytes memory h = bytes(_haystack);
1034952
bytes memory n = bytes(_needle);

0 commit comments

Comments
 (0)