Commit 9425a7e0 by Hadrien Croubois

Merge branch 'solc-0.8'

Conflicts:
	CHANGELOG.md
	package-lock.json
	test/math/SafeMath.test.js
parents e2861562 93438eca
...@@ -43,4 +43,6 @@ jobs: ...@@ -43,4 +43,6 @@ jobs:
- run: npm ci - run: npm ci
if: steps.cache.outputs.cache-hit != 'true' if: steps.cache.outputs.cache-hit != 'true'
- run: npm run coverage - run: npm run coverage
env:
NODE_OPTIONS: --max_old_space_size=4096
- uses: codecov/codecov-action@v1 - uses: codecov/codecov-action@v1
# Changelog # Changelog
## Unreleased
* Now targeting the 0.8.x line of Solidity compilers. For 0.6.x (resp 0.7.x) support, use version 3.4.0 (resp 3.4.0-solc-0.7) of OpenZeppelin.
* `Context`: making `_msgData` return `bytes calldata` instead of `bytes memory` ([#2492](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2492))
## 3.4.0 (2021-02-02) ## 3.4.0 (2021-02-02)
* `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411)) * `BeaconProxy`: added new kind of proxy that allows simultaneous atomic upgrades. ([#2411](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2411))
...@@ -30,6 +35,12 @@ If you're using our implementation of ERC777 from version 3.3.0 or earlier, and ...@@ -30,6 +35,12 @@ If you're using our implementation of ERC777 from version 3.3.0 or earlier, and
* `TimelockController`: added a contract to augment access control schemes with a delay. ([#2354](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2354)) * `TimelockController`: added a contract to augment access control schemes with a delay. ([#2354](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2354))
* `EnumerableSet`: added `Bytes32Set`, for sets of `bytes32`. ([#2395](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2395)) * `EnumerableSet`: added `Bytes32Set`, for sets of `bytes32`. ([#2395](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2395))
## 3.2.2-solc-0.7 (2020-10-28)
* Resolve warnings introduced by Solidity 0.7.4. ([#2396](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2396))
## 3.2.1-solc-0.7 (2020-09-15)
* `ERC777`: Remove a warning about function state visibility in Solidity 0.7. ([#2327](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2327))
## 3.2.0 (2020-09-10) ## 3.2.0 (2020-09-10)
### New features ### New features
......
...@@ -27,12 +27,12 @@ OpenZeppelin Contracts features a [stable API](https://docs.openzeppelin.com/con ...@@ -27,12 +27,12 @@ OpenZeppelin Contracts features a [stable API](https://docs.openzeppelin.com/con
Once installed, you can use the contracts in the library by importing them: Once installed, you can use the contracts in the library by importing them:
```solidity ```solidity
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyCollectible is ERC721 { contract MyCollectible is ERC721 {
constructor() ERC721("MyCollectible", "MCO") public { constructor() ERC721("MyCollectible", "MCO") {
} }
} }
``` ```
......
const fs = require('fs');
const path = require('path');
usePlugin('solidity-coverage');
usePlugin('@nomiclabs/buidler-truffle5');
for (const f of fs.readdirSync(path.join(__dirname, 'buidler'))) {
require(path.join(__dirname, 'buidler', f));
}
module.exports = {
networks: {
buidlerevm: {
blockGasLimit: 10000000,
},
},
solc: {
version: '0.6.12',
},
};
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
import "./IRelayRecipient.sol"; import "./IRelayRecipient.sol";
...@@ -87,11 +87,11 @@ abstract contract GSNRecipient is IRelayRecipient, Context { ...@@ -87,11 +87,11 @@ abstract contract GSNRecipient is IRelayRecipient, Context {
* *
* IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead. * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead.
*/ */
function _msgSender() internal view virtual override returns (address payable) { function _msgSender() internal view virtual override returns (address msgSender) {
if (msg.sender != getHubAddr()) { if (msg.sender == getHubAddr()) {
return msg.sender; assembly { msgSender := shr(96, calldataload(sub(calldatasize(), 20))) }
} else { } else {
return _getRelayedCallSender(); return msg.sender;
} }
} }
...@@ -101,11 +101,11 @@ abstract contract GSNRecipient is IRelayRecipient, Context { ...@@ -101,11 +101,11 @@ abstract contract GSNRecipient is IRelayRecipient, Context {
* *
* IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.data`, and use {_msgData} instead. * IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.data`, and use {_msgData} instead.
*/ */
function _msgData() internal view virtual override returns (bytes memory) { function _msgData() internal view virtual override returns (bytes calldata) {
if (msg.sender != getHubAddr()) { if (msg.sender == getHubAddr()) {
return msg.data; return msg.data[:msg.data.length - 20];
} else { } else {
return _getRelayedCallData(); return msg.data;
} }
} }
...@@ -191,40 +191,4 @@ abstract contract GSNRecipient is IRelayRecipient, Context { ...@@ -191,40 +191,4 @@ abstract contract GSNRecipient is IRelayRecipient, Context {
// charged for 1.4 times the spent amount. // charged for 1.4 times the spent amount.
return (gas * gasPrice * (100 + serviceFee)) / 100; return (gas * gasPrice * (100 + serviceFee)) / 100;
} }
function _getRelayedCallSender() private pure returns (address payable result) {
// We need to read 20 bytes (an address) located at array index msg.data.length - 20. In memory, the array
// is prefixed with a 32-byte length value, so we first add 32 to get the memory read index. However, doing
// so would leave the address in the upper 20 bytes of the 32-byte word, which is inconvenient and would
// require bit shifting. We therefore subtract 12 from the read index so the address lands on the lower 20
// bytes. This can always be done due to the 32-byte prefix.
// The final memory read index is msg.data.length - 20 + 32 - 12 = msg.data.length. Using inline assembly is the
// easiest/most-efficient way to perform this operation.
// These fields are not accessible from assembly
bytes memory array = msg.data;
uint256 index = msg.data.length;
// solhint-disable-next-line no-inline-assembly
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
return result;
}
function _getRelayedCallData() private pure returns (bytes memory) {
// RelayHub appends the sender address at the end of the calldata, so in order to retrieve the actual msg.data,
// we must strip the last 20 bytes (length of an address type) from it.
uint256 actualDataLength = msg.data.length - 20;
bytes memory actualData = new bytes(actualDataLength);
for (uint256 i = 0; i < actualDataLength; ++i) {
actualData[i] = msg.data[i];
}
return actualData;
}
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./GSNRecipient.sol"; import "./GSNRecipient.sol";
import "../math/SafeMath.sol";
import "../access/Ownable.sol"; import "../access/Ownable.sol";
import "../token/ERC20/SafeERC20.sol"; import "../token/ERC20/SafeERC20.sol";
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
...@@ -19,7 +18,6 @@ import "../token/ERC20/ERC20.sol"; ...@@ -19,7 +18,6 @@ import "../token/ERC20/ERC20.sol";
*/ */
contract GSNRecipientERC20Fee is GSNRecipient { contract GSNRecipientERC20Fee is GSNRecipient {
using SafeERC20 for __unstable__ERC20Owned; using SafeERC20 for __unstable__ERC20Owned;
using SafeMath for uint256;
enum GSNRecipientERC20FeeErrorCodes { enum GSNRecipientERC20FeeErrorCodes {
INSUFFICIENT_BALANCE INSUFFICIENT_BALANCE
...@@ -30,7 +28,7 @@ contract GSNRecipientERC20Fee is GSNRecipient { ...@@ -30,7 +28,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
/** /**
* @dev The arguments to the constructor are the details that the gas payment token will have: `name` and `symbol`. `decimals` is hard-coded to 18. * @dev The arguments to the constructor are the details that the gas payment token will have: `name` and `symbol`. `decimals` is hard-coded to 18.
*/ */
constructor(string memory name, string memory symbol) public { constructor(string memory name, string memory symbol) {
_token = new __unstable__ERC20Owned(name, symbol); _token = new __unstable__ERC20Owned(name, symbol);
} }
...@@ -100,11 +98,11 @@ contract GSNRecipientERC20Fee is GSNRecipient { ...@@ -100,11 +98,11 @@ contract GSNRecipientERC20Fee is GSNRecipient {
// actualCharge is an _estimated_ charge, which assumes postRelayedCall will use all available gas. // actualCharge is an _estimated_ charge, which assumes postRelayedCall will use all available gas.
// This implementation's gas cost can be roughly estimated as 10k gas, for the two SSTORE operations in an // This implementation's gas cost can be roughly estimated as 10k gas, for the two SSTORE operations in an
// ERC20 transfer. // ERC20 transfer.
uint256 overestimation = _computeCharge(_POST_RELAYED_CALL_MAX_GAS.sub(10000), gasPrice, transactionFee); uint256 overestimation = _computeCharge(_POST_RELAYED_CALL_MAX_GAS - 10000, gasPrice, transactionFee);
actualCharge = actualCharge.sub(overestimation); actualCharge = actualCharge - overestimation;
// After the relayed call has been executed and the actual charge estimated, the excess pre-charge is returned // After the relayed call has been executed and the actual charge estimated, the excess pre-charge is returned
token().safeTransfer(from, maxPossibleCharge.sub(actualCharge)); token().safeTransfer(from, maxPossibleCharge - actualCharge);
} }
} }
...@@ -118,7 +116,7 @@ contract GSNRecipientERC20Fee is GSNRecipient { ...@@ -118,7 +116,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
contract __unstable__ERC20Owned is ERC20, Ownable { contract __unstable__ERC20Owned is ERC20, Ownable {
uint256 private constant _UINT256_MAX = 2**256 - 1; uint256 private constant _UINT256_MAX = 2**256 - 1;
constructor(string memory name, string memory symbol) public ERC20(name, symbol) { } constructor(string memory name, string memory symbol) ERC20(name, symbol) { }
// The owner (GSNRecipientERC20Fee) can mint tokens // The owner (GSNRecipientERC20Fee) can mint tokens
function mint(address account, uint256 amount) public virtual onlyOwner { function mint(address account, uint256 amount) public virtual onlyOwner {
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./GSNRecipient.sol"; import "./GSNRecipient.sol";
import "../cryptography/ECDSA.sol"; import "../cryptography/ECDSA.sol";
...@@ -23,7 +23,7 @@ contract GSNRecipientSignature is GSNRecipient { ...@@ -23,7 +23,7 @@ contract GSNRecipientSignature is GSNRecipient {
/** /**
* @dev Sets the trusted signer that is going to be producing signatures to approve relayed calls. * @dev Sets the trusted signer that is going to be producing signatures to approve relayed calls.
*/ */
constructor(address trustedSigner) public { constructor(address trustedSigner) {
require(trustedSigner != address(0), "GSNRecipientSignature: trusted signer is the zero address"); require(trustedSigner != address(0), "GSNRecipientSignature: trusted signer is the zero address");
_trustedSigner = trustedSigner; _trustedSigner = trustedSigner;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract * @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Base interface for a contract that will be called via the GSN from {IRelayHub}. * @dev Base interface for a contract that will be called via the GSN from {IRelayHub}.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/EnumerableSet.sol"; import "../utils/EnumerableSet.sol";
import "../utils/Address.sol"; import "../utils/Address.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
/** /**
...@@ -23,7 +23,7 @@ abstract contract Ownable is Context { ...@@ -23,7 +23,7 @@ abstract contract Ownable is Context {
/** /**
* @dev Initializes the contract setting the deployer as the initial owner. * @dev Initializes the contract setting the deployer as the initial owner.
*/ */
constructor () internal { constructor () {
address msgSender = _msgSender(); address msgSender = _msgSender();
_owner = msgSender; _owner = msgSender;
emit OwnershipTransferred(address(0), msgSender); emit OwnershipTransferred(address(0), msgSender);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.9 <0.8.0; pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;
import "./../math/SafeMath.sol";
import "./AccessControl.sol"; import "./AccessControl.sol";
/** /**
...@@ -22,7 +20,6 @@ import "./AccessControl.sol"; ...@@ -22,7 +20,6 @@ import "./AccessControl.sol";
* _Available since v3.3._ * _Available since v3.3._
*/ */
contract TimelockController is AccessControl { contract TimelockController is AccessControl {
bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE"); bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
...@@ -54,7 +51,7 @@ contract TimelockController is AccessControl { ...@@ -54,7 +51,7 @@ contract TimelockController is AccessControl {
/** /**
* @dev Initializes the contract with a given `minDelay`. * @dev Initializes the contract with a given `minDelay`.
*/ */
constructor(uint256 minDelay, address[] memory proposers, address[] memory executors) public { constructor(uint256 minDelay, address[] memory proposers, address[] memory executors) {
_setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE); _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE); _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);
_setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE); _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);
...@@ -199,7 +196,7 @@ contract TimelockController is AccessControl { ...@@ -199,7 +196,7 @@ contract TimelockController is AccessControl {
require(!isOperation(id), "TimelockController: operation already scheduled"); require(!isOperation(id), "TimelockController: operation already scheduled");
require(delay >= getMinDelay(), "TimelockController: insufficient delay"); require(delay >= getMinDelay(), "TimelockController: insufficient delay");
// solhint-disable-next-line not-rely-on-time // solhint-disable-next-line not-rely-on-time
_timestamps[id] = SafeMath.add(block.timestamp, delay); _timestamps[id] = block.timestamp + delay;
} }
/** /**
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev These functions deal with verification of Merkle trees (hash trees), * @dev These functions deal with verification of Merkle trees (hash trees),
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
...@@ -45,13 +45,13 @@ abstract contract EIP712 { ...@@ -45,13 +45,13 @@ abstract contract EIP712 {
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade]. * contract upgrade].
*/ */
constructor(string memory name, string memory version) internal { constructor(string memory name, string memory version) {
bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version)); bytes32 hashedVersion = keccak256(bytes(version));
bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
_HASHED_NAME = hashedName; _HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion; _HASHED_VERSION = hashedVersion;
_CACHED_CHAIN_ID = _getChainId(); _CACHED_CHAIN_ID = block.chainid;
_CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
_TYPE_HASH = typeHash; _TYPE_HASH = typeHash;
} }
...@@ -59,8 +59,8 @@ abstract contract EIP712 { ...@@ -59,8 +59,8 @@ abstract contract EIP712 {
/** /**
* @dev Returns the domain separator for the current chain. * @dev Returns the domain separator for the current chain.
*/ */
function _domainSeparatorV4() internal view virtual returns (bytes32) { function _domainSeparatorV4() internal view returns (bytes32) {
if (_getChainId() == _CACHED_CHAIN_ID) { if (block.chainid == _CACHED_CHAIN_ID) {
return _CACHED_DOMAIN_SEPARATOR; return _CACHED_DOMAIN_SEPARATOR;
} else { } else {
return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
...@@ -73,7 +73,7 @@ abstract contract EIP712 { ...@@ -73,7 +73,7 @@ abstract contract EIP712 {
typeHash, typeHash,
name, name,
version, version,
_getChainId(), block.chainid,
address(this) address(this)
) )
); );
...@@ -97,12 +97,4 @@ abstract contract EIP712 { ...@@ -97,12 +97,4 @@ abstract contract EIP712 {
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", _domainSeparatorV4(), structHash)); return keccak256(abi.encodePacked("\x19\x01", _domainSeparatorV4(), structHash));
} }
function _getChainId() private view returns (uint256 chainId) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
// solhint-disable-next-line no-inline-assembly
assembly {
chainId := chainid()
}
}
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.5 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "./IERC20Permit.sol"; import "./IERC20Permit.sol";
...@@ -31,7 +31,7 @@ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { ...@@ -31,7 +31,7 @@ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
* *
* It's a good idea to use the same `name` that is defined as the ERC20 token name. * It's a good idea to use the same `name` that is defined as the ERC20 token name.
*/ */
constructor(string memory name) internal EIP712(name, "1") { constructor(string memory name) EIP712(name, "1") {
} }
/** /**
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./IERC165.sol"; import "./IERC165.sol";
...@@ -11,20 +11,15 @@ import "./IERC165.sol"; ...@@ -11,20 +11,15 @@ import "./IERC165.sol";
* their support of an interface. * their support of an interface.
*/ */
abstract contract ERC165 is IERC165 { abstract contract ERC165 is IERC165 {
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/** /**
* @dev Mapping of interface ids to whether or not it's supported. * @dev Mapping of interface ids to whether or not it's supported.
*/ */
mapping(bytes4 => bool) private _supportedInterfaces; mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal { constructor () {
// Derived contracts need only register support for their own interfaces, // Derived contracts need only register support for their own interfaces,
// we register support for ERC165 itself here // we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165); _registerInterface(type(IERC165).interfaceId);
} }
/** /**
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
import "./IERC165.sol";
/** /**
* @dev Library used to query support of an interface declared via {IERC165}. * @dev Library used to query support of an interface declared via {IERC165}.
...@@ -13,18 +15,13 @@ library ERC165Checker { ...@@ -13,18 +15,13 @@ library ERC165Checker {
// As per the EIP-165 spec, no interface should ever match 0xffffffff // As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
/** /**
* @dev Returns true if `account` supports the {IERC165} interface, * @dev Returns true if `account` supports the {IERC165} interface,
*/ */
function supportsERC165(address account) internal view returns (bool) { function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of // Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return _supportsERC165Interface(account, _INTERFACE_ID_ERC165) && return _supportsERC165Interface(account, type(IERC165).interfaceId) &&
!_supportsERC165Interface(account, _INTERFACE_ID_INVALID); !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
} }
...@@ -103,29 +100,9 @@ library ERC165Checker { ...@@ -103,29 +100,9 @@ library ERC165Checker {
* Interface identification is specified in ERC-165. * Interface identification is specified in ERC-165.
*/ */
function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) { function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
// success determines whether the staticcall succeeded and result determines bytes memory encodedParams = abi.encodeWithSelector(IERC165(account).supportsInterface.selector, interfaceId);
// whether the contract at account indicates support of _interfaceId
(bool success, bool result) = _callERC165SupportsInterface(account, interfaceId);
return (success && result);
}
/**
* @notice Calls the function with selector 0x01ffc9a7 (ERC165) and suppresses throw
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return success true if the STATICCALL succeeded, false otherwise
* @return result true if the STATICCALL succeeded and the contract at account
* indicates support of the interface with identifier interfaceId, false otherwise
*/
function _callERC165SupportsInterface(address account, bytes4 interfaceId)
private
view
returns (bool, bool)
{
bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, interfaceId);
(bool success, bytes memory result) = account.staticcall{ gas: 30000 }(encodedParams); (bool success, bytes memory result) = account.staticcall{ gas: 30000 }(encodedParams);
if (result.length < 32) return (false, false); if (result.length < 32) return false;
return (success, abi.decode(result, (bool))); return success && abi.decode(result, (bool));
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./IERC1820Implementer.sol"; import "./IERC1820Implementer.sol";
...@@ -13,7 +13,7 @@ import "./IERC1820Implementer.sol"; ...@@ -13,7 +13,7 @@ import "./IERC1820Implementer.sol";
* registration to be complete. * registration to be complete.
*/ */
contract ERC1820Implementer is IERC1820Implementer { contract ERC1820Implementer is IERC1820Implementer {
bytes32 constant private _ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked("ERC1820_ACCEPT_MAGIC")); bytes32 private constant _ERC1820_ACCEPT_MAGIC = keccak256("ERC1820_ACCEPT_MAGIC");
mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces; mapping(bytes32 => mapping(address => bool)) private _supportedInterfaces;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface of the ERC165 standard, as defined in the * @dev Interface of the ERC165 standard, as defined in the
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface for an ERC1820 implementer, as defined in the * @dev Interface for an ERC1820 implementer, as defined in the
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface of the global ERC1820 Registry, as defined in the * @dev Interface of the global ERC1820 Registry, as defined in the
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Standard math utilities missing in the Solidity language. * @dev Standard math utilities missing in the Solidity language.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Wrappers over Solidity's arithmetic operations with added overflow * @dev Wrappers over Solidity's arithmetic operations.
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/ */
library SafeMath { library SafeMath {
/** /**
...@@ -22,10 +12,12 @@ library SafeMath { ...@@ -22,10 +12,12 @@ library SafeMath {
* _Available since v3.4._ * _Available since v3.4._
*/ */
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b; uint256 c = a + b;
if (c < a) return (false, 0); if (c < a) return (false, 0);
return (true, c); return (true, c);
} }
}
/** /**
* @dev Returns the substraction of two unsigned integers, with an overflow flag. * @dev Returns the substraction of two unsigned integers, with an overflow flag.
...@@ -33,9 +25,11 @@ library SafeMath { ...@@ -33,9 +25,11 @@ library SafeMath {
* _Available since v3.4._ * _Available since v3.4._
*/ */
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0); if (b > a) return (false, 0);
return (true, a - b); return (true, a - b);
} }
}
/** /**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag. * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
...@@ -43,6 +37,7 @@ library SafeMath { ...@@ -43,6 +37,7 @@ library SafeMath {
* _Available since v3.4._ * _Available since v3.4._
*/ */
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested. // benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
...@@ -51,6 +46,7 @@ library SafeMath { ...@@ -51,6 +46,7 @@ library SafeMath {
if (c / a != b) return (false, 0); if (c / a != b) return (false, 0);
return (true, c); return (true, c);
} }
}
/** /**
* @dev Returns the division of two unsigned integers, with a division by zero flag. * @dev Returns the division of two unsigned integers, with a division by zero flag.
...@@ -58,9 +54,11 @@ library SafeMath { ...@@ -58,9 +54,11 @@ library SafeMath {
* _Available since v3.4._ * _Available since v3.4._
*/ */
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0); if (b == 0) return (false, 0);
return (true, a / b); return (true, a / b);
} }
}
/** /**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
...@@ -68,9 +66,11 @@ library SafeMath { ...@@ -68,9 +66,11 @@ library SafeMath {
* _Available since v3.4._ * _Available since v3.4._
*/ */
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0); if (b == 0) return (false, 0);
return (true, a % b); return (true, a % b);
} }
}
/** /**
* @dev Returns the addition of two unsigned integers, reverting on * @dev Returns the addition of two unsigned integers, reverting on
...@@ -83,9 +83,7 @@ library SafeMath { ...@@ -83,9 +83,7 @@ library SafeMath {
* - Addition cannot overflow. * - Addition cannot overflow.
*/ */
function add(uint256 a, uint256 b) internal pure returns (uint256) { function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b; return a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
} }
/** /**
...@@ -99,7 +97,6 @@ library SafeMath { ...@@ -99,7 +97,6 @@ library SafeMath {
* - Subtraction cannot overflow. * - Subtraction cannot overflow.
*/ */
function sub(uint256 a, uint256 b) internal pure returns (uint256) { function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b; return a - b;
} }
...@@ -114,26 +111,20 @@ library SafeMath { ...@@ -114,26 +111,20 @@ library SafeMath {
* - Multiplication cannot overflow. * - Multiplication cannot overflow.
*/ */
function mul(uint256 a, uint256 b) internal pure returns (uint256) { function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0; return a * b;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
} }
/** /**
* @dev Returns the integer division of two unsigned integers, reverting on * @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero. * division by zero. The result is rounded towards zero.
* *
* Counterpart to Solidity's `/` operator. Note: this function uses a * Counterpart to Solidity's `/` operator.
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
* *
* Requirements: * Requirements:
* *
* - The divisor cannot be zero. * - The divisor cannot be zero.
*/ */
function div(uint256 a, uint256 b) internal pure returns (uint256) { function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b; return a / b;
} }
...@@ -150,7 +141,6 @@ library SafeMath { ...@@ -150,7 +141,6 @@ library SafeMath {
* - The divisor cannot be zero. * - The divisor cannot be zero.
*/ */
function mod(uint256 a, uint256 b) internal pure returns (uint256) { function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b; return a % b;
} }
...@@ -168,16 +158,19 @@ library SafeMath { ...@@ -168,16 +158,19 @@ library SafeMath {
* - Subtraction cannot overflow. * - Subtraction cannot overflow.
*/ */
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage); require(b <= a, errorMessage);
return a - b; return a - b;
} }
}
/** /**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on * @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero. * division by zero. The result is rounded towards zero.
* *
* CAUTION: This function is deprecated because it requires allocating memory for the error * Counterpart to Solidity's `%` operator. This function uses a `revert`
* message unnecessarily. For custom revert reasons use {tryDiv}. * opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
* *
* Counterpart to Solidity's `/` operator. Note: this function uses a * Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity * `revert` opcode (which leaves remaining gas untouched) while Solidity
...@@ -188,9 +181,11 @@ library SafeMath { ...@@ -188,9 +181,11 @@ library SafeMath {
* - The divisor cannot be zero. * - The divisor cannot be zero.
*/ */
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage); require(b > 0, errorMessage);
return a / b; return a / b;
} }
}
/** /**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
...@@ -208,7 +203,9 @@ library SafeMath { ...@@ -208,7 +203,9 @@ library SafeMath {
* - The divisor cannot be zero. * - The divisor cannot be zero.
*/ */
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage); require(b > 0, errorMessage);
return a % b; return a % b;
} }
}
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @title SignedSafeMath * @title SignedSafeMath
* @dev Signed math operations with safety checks that revert on error. * @dev Signed math operations that revert on error.
*/ */
library SignedSafeMath { library SignedSafeMath {
int256 constant private _INT256_MIN = -2**255;
/** /**
* @dev Returns the multiplication of two signed integers, reverting on * @dev Returns the multiplication of two signed integers, reverting on
* overflow. * overflow.
...@@ -20,40 +18,21 @@ library SignedSafeMath { ...@@ -20,40 +18,21 @@ library SignedSafeMath {
* - Multiplication cannot overflow. * - Multiplication cannot overflow.
*/ */
function mul(int256 a, int256 b) internal pure returns (int256) { function mul(int256 a, int256 b) internal pure returns (int256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the return a * b;
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
} }
/** /**
* @dev Returns the integer division of two signed integers. Reverts on * @dev Returns the integer division of two signed integers. Reverts on
* division by zero. The result is rounded towards zero. * division by zero. The result is rounded towards zero.
* *
* Counterpart to Solidity's `/` operator. Note: this function uses a * Counterpart to Solidity's `/` operator.
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
* *
* Requirements: * Requirements:
* *
* - The divisor cannot be zero. * - The divisor cannot be zero.
*/ */
function div(int256 a, int256 b) internal pure returns (int256) { function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "SignedSafeMath: division by zero"); return a / b;
require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;
return c;
} }
/** /**
...@@ -67,10 +46,7 @@ library SignedSafeMath { ...@@ -67,10 +46,7 @@ library SignedSafeMath {
* - Subtraction cannot overflow. * - Subtraction cannot overflow.
*/ */
function sub(int256 a, int256 b) internal pure returns (int256) { function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b; return a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
} }
/** /**
...@@ -84,9 +60,6 @@ library SignedSafeMath { ...@@ -84,9 +60,6 @@ library SignedSafeMath {
* - Addition cannot overflow. * - Addition cannot overflow.
*/ */
function add(int256 a, int256 b) internal pure returns (int256) { function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b; return a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../access/AccessControl.sol"; import "../access/AccessControl.sol";
contract AccessControlMock is AccessControl { contract AccessControlMock is AccessControl {
constructor() public { constructor() {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Address.sol"; import "../utils/Address.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Arrays.sol"; import "../utils/Arrays.sol";
...@@ -9,7 +9,7 @@ contract ArraysImpl { ...@@ -9,7 +9,7 @@ contract ArraysImpl {
uint256[] private _array; uint256[] private _array;
constructor (uint256[] memory array) public { constructor (uint256[] memory array) {
_array = array; _array = array;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
contract BadBeaconNoImpl { contract BadBeaconNoImpl {
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
contract CallReceiverMock { contract CallReceiverMock {
string public sharedAnswer; string public sharedAnswer;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../proxy/Clones.sol"; import "../proxy/Clones.sol";
import "../utils/Address.sol"; import "../utils/Address.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../payment/escrow/ConditionalEscrow.sol"; import "../payment/escrow/ConditionalEscrow.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Counters.sol"; import "../utils/Counters.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Create2.sol"; import "../utils/Create2.sol";
import "../introspection/ERC1820Implementer.sol"; import "../introspection/ERC1820Implementer.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
abstract contract Impl { abstract contract Impl {
function version() public pure virtual returns (string memory); function version() public pure virtual returns (string memory);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../cryptography/ECDSA.sol"; import "../cryptography/ECDSA.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../drafts/EIP712.sol"; import "../drafts/EIP712.sol";
import "../cryptography/ECDSA.sol"; import "../cryptography/ECDSA.sol";
contract EIP712External is EIP712 { contract EIP712External is EIP712 {
constructor(string memory name, string memory version) public EIP712(name, version) {} constructor(string memory name, string memory version) EIP712(name, version) {}
function domainSeparator() external view returns (bytes32) { function domainSeparator() external view returns (bytes32) {
return _domainSeparatorV4(); return _domainSeparatorV4();
...@@ -22,11 +22,7 @@ contract EIP712External is EIP712 { ...@@ -22,11 +22,7 @@ contract EIP712External is EIP712 {
require(recoveredSigner == signer); require(recoveredSigner == signer);
} }
function getChainId() external view returns (uint256 chainId) { function getChainId() external view returns (uint256) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return block.chainid;
// solhint-disable-next-line no-inline-assembly
assembly {
chainId := chainid()
}
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC1155/ERC1155Burnable.sol"; import "../token/ERC1155/ERC1155Burnable.sol";
contract ERC1155BurnableMock is ERC1155Burnable { contract ERC1155BurnableMock is ERC1155Burnable {
constructor(string memory uri) public ERC1155(uri) { } constructor(string memory uri) ERC1155(uri) { }
function mint(address to, uint256 id, uint256 value, bytes memory data) public { function mint(address to, uint256 id, uint256 value, bytes memory data) public {
_mint(to, id, value, data); _mint(to, id, value, data);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC1155/ERC1155.sol"; import "../token/ERC1155/ERC1155.sol";
...@@ -9,7 +9,7 @@ import "../token/ERC1155/ERC1155.sol"; ...@@ -9,7 +9,7 @@ import "../token/ERC1155/ERC1155.sol";
* This mock just publicizes internal functions for testing purposes * This mock just publicizes internal functions for testing purposes
*/ */
contract ERC1155Mock is ERC1155 { contract ERC1155Mock is ERC1155 {
constructor (string memory uri) public ERC1155(uri) { constructor (string memory uri) ERC1155(uri) {
// solhint-disable-previous-line no-empty-blocks // solhint-disable-previous-line no-empty-blocks
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ERC1155Mock.sol"; import "./ERC1155Mock.sol";
import "../token/ERC1155/ERC1155Pausable.sol"; import "../token/ERC1155/ERC1155Pausable.sol";
contract ERC1155PausableMock is ERC1155Mock, ERC1155Pausable { contract ERC1155PausableMock is ERC1155Mock, ERC1155Pausable {
constructor(string memory uri) public ERC1155Mock(uri) { } constructor(string memory uri) ERC1155Mock(uri) { }
function pause() external { function pause() external {
_pause(); _pause();
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC1155/IERC1155Receiver.sol"; import "../token/ERC1155/IERC1155Receiver.sol";
import "./ERC165Mock.sol"; import "./ERC165Mock.sol";
...@@ -20,7 +20,6 @@ contract ERC1155ReceiverMock is IERC1155Receiver, ERC165Mock { ...@@ -20,7 +20,6 @@ contract ERC1155ReceiverMock is IERC1155Receiver, ERC165Mock {
bytes4 batRetval, bytes4 batRetval,
bool batReverts bool batReverts
) )
public
{ {
_recRetval = recRetval; _recRetval = recRetval;
_recReverts = recReverts; _recReverts = recReverts;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../introspection/IERC165.sol"; import "../../introspection/IERC165.sol";
...@@ -29,7 +29,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 { ...@@ -29,7 +29,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
* @dev A contract implementing SupportsInterfaceWithLookup * @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itself. * implement ERC165 itself.
*/ */
constructor () public { constructor () {
_registerInterface(INTERFACE_ID_ERC165); _registerInterface(INTERFACE_ID_ERC165);
} }
...@@ -50,7 +50,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 { ...@@ -50,7 +50,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
} }
contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock { contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock {
constructor (bytes4[] memory interfaceIds) public { constructor (bytes4[] memory interfaceIds) {
for (uint256 i = 0; i < interfaceIds.length; i++) { for (uint256 i = 0; i < interfaceIds.length; i++) {
_registerInterface(interfaceIds[i]); _registerInterface(interfaceIds[i]);
} }
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ERC165MissingData {
function supportsInterface(bytes4 interfaceId) public view {} // missing return
}
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
contract ERC165NotSupported { } contract ERC165NotSupported { }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../introspection/ERC165Checker.sol"; import "../introspection/ERC165Checker.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../introspection/ERC165.sol"; import "../introspection/ERC165.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../introspection/ERC1820Implementer.sol"; import "../introspection/ERC1820Implementer.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20Burnable.sol"; import "../token/ERC20/ERC20Burnable.sol";
...@@ -10,7 +10,7 @@ contract ERC20BurnableMock is ERC20Burnable { ...@@ -10,7 +10,7 @@ contract ERC20BurnableMock is ERC20Burnable {
string memory symbol, string memory symbol,
address initialAccount, address initialAccount,
uint256 initialBalance uint256 initialBalance
) public ERC20(name, symbol) { ) ERC20(name, symbol) {
_mint(initialAccount, initialBalance); _mint(initialAccount, initialBalance);
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20Capped.sol"; import "../token/ERC20/ERC20Capped.sol";
contract ERC20CappedMock is ERC20Capped { contract ERC20CappedMock is ERC20Capped {
constructor (string memory name, string memory symbol, uint256 cap) constructor (string memory name, string memory symbol, uint256 cap)
public ERC20(name, symbol) ERC20Capped(cap) ERC20(name, symbol) ERC20Capped(cap)
{ } { }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
contract ERC20DecimalsMock is ERC20 { contract ERC20DecimalsMock is ERC20 {
constructor (string memory name, string memory symbol, uint8 decimals) public ERC20(name, symbol) { constructor (string memory name, string memory symbol, uint8 decimals) ERC20(name, symbol) {
_setupDecimals(decimals); _setupDecimals(decimals);
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
...@@ -11,7 +11,7 @@ contract ERC20Mock is ERC20 { ...@@ -11,7 +11,7 @@ contract ERC20Mock is ERC20 {
string memory symbol, string memory symbol,
address initialAccount, address initialAccount,
uint256 initialBalance uint256 initialBalance
) public payable ERC20(name, symbol) { ) payable ERC20(name, symbol) {
_mint(initialAccount, initialBalance); _mint(initialAccount, initialBalance);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20Pausable.sol"; import "../token/ERC20/ERC20Pausable.sol";
...@@ -11,7 +11,7 @@ contract ERC20PausableMock is ERC20Pausable { ...@@ -11,7 +11,7 @@ contract ERC20PausableMock is ERC20Pausable {
string memory symbol, string memory symbol,
address initialAccount, address initialAccount,
uint256 initialBalance uint256 initialBalance
) public ERC20(name, symbol) { ) ERC20(name, symbol) {
_mint(initialAccount, initialBalance); _mint(initialAccount, initialBalance);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../drafts/ERC20Permit.sol"; import "../drafts/ERC20Permit.sol";
...@@ -10,15 +10,11 @@ contract ERC20PermitMock is ERC20Permit { ...@@ -10,15 +10,11 @@ contract ERC20PermitMock is ERC20Permit {
string memory symbol, string memory symbol,
address initialAccount, address initialAccount,
uint256 initialBalance uint256 initialBalance
) public payable ERC20(name, symbol) ERC20Permit(name) { ) payable ERC20(name, symbol) ERC20Permit(name) {
_mint(initialAccount, initialBalance); _mint(initialAccount, initialBalance);
} }
function getChainId() external view returns (uint256 chainId) { function getChainId() external view returns (uint256) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return block.chainid;
// solhint-disable-next-line no-inline-assembly
assembly {
chainId := chainid()
}
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20Snapshot.sol"; import "../token/ERC20/ERC20Snapshot.sol";
...@@ -11,7 +11,7 @@ contract ERC20SnapshotMock is ERC20Snapshot { ...@@ -11,7 +11,7 @@ contract ERC20SnapshotMock is ERC20Snapshot {
string memory symbol, string memory symbol,
address initialAccount, address initialAccount,
uint256 initialBalance uint256 initialBalance
) public ERC20(name, symbol) { ) ERC20(name, symbol) {
_mint(initialAccount, initialBalance); _mint(initialAccount, initialBalance);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC721/ERC721Burnable.sol"; import "../token/ERC721/ERC721Burnable.sol";
contract ERC721BurnableMock is ERC721Burnable { contract ERC721BurnableMock is ERC721Burnable {
constructor(string memory name, string memory symbol) public ERC721(name, symbol) { } constructor(string memory name, string memory symbol) ERC721(name, symbol) { }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
_mint(to, tokenId); _mint(to, tokenId);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC721/ERC721.sol"; import "../token/ERC721/ERC721.sol";
import "../GSN/GSNRecipient.sol"; import "../GSN/GSNRecipient.sol";
...@@ -12,7 +12,6 @@ import "../GSN/GSNRecipientSignature.sol"; ...@@ -12,7 +12,6 @@ import "../GSN/GSNRecipientSignature.sol";
*/ */
contract ERC721GSNRecipientMock is ERC721, GSNRecipient, GSNRecipientSignature { contract ERC721GSNRecipientMock is ERC721, GSNRecipient, GSNRecipientSignature {
constructor(string memory name, string memory symbol, address trustedSigner) constructor(string memory name, string memory symbol, address trustedSigner)
public
ERC721(name, symbol) ERC721(name, symbol)
GSNRecipientSignature(trustedSigner) GSNRecipientSignature(trustedSigner)
{ } { }
...@@ -21,7 +20,7 @@ contract ERC721GSNRecipientMock is ERC721, GSNRecipient, GSNRecipientSignature { ...@@ -21,7 +20,7 @@ contract ERC721GSNRecipientMock is ERC721, GSNRecipient, GSNRecipientSignature {
_mint(_msgSender(), tokenId); _mint(_msgSender(), tokenId);
} }
function _msgSender() internal view override(Context, GSNRecipient) returns (address payable) { function _msgSender() internal view override(Context, GSNRecipient) returns (address) {
return GSNRecipient._msgSender(); return GSNRecipient._msgSender();
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC721/ERC721.sol"; import "../token/ERC721/ERC721.sol";
...@@ -9,7 +9,7 @@ import "../token/ERC721/ERC721.sol"; ...@@ -9,7 +9,7 @@ import "../token/ERC721/ERC721.sol";
* This mock just provides a public safeMint, mint, and burn functions for testing purposes * This mock just provides a public safeMint, mint, and burn functions for testing purposes
*/ */
contract ERC721Mock is ERC721 { contract ERC721Mock is ERC721 {
constructor (string memory name, string memory symbol) public ERC721(name, symbol) { } constructor (string memory name, string memory symbol) ERC721(name, symbol) { }
function exists(uint256 tokenId) public view returns (bool) { function exists(uint256 tokenId) public view returns (bool) {
return _exists(tokenId); return _exists(tokenId);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC721/ERC721Pausable.sol"; import "../token/ERC721/ERC721Pausable.sol";
...@@ -9,7 +9,7 @@ import "../token/ERC721/ERC721Pausable.sol"; ...@@ -9,7 +9,7 @@ import "../token/ERC721/ERC721Pausable.sol";
* This mock just provides a public mint, burn and exists functions for testing purposes * This mock just provides a public mint, burn and exists functions for testing purposes
*/ */
contract ERC721PausableMock is ERC721Pausable { contract ERC721PausableMock is ERC721Pausable {
constructor (string memory name, string memory symbol) public ERC721(name, symbol) { } constructor (string memory name, string memory symbol) ERC721(name, symbol) { }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
super._mint(to, tokenId); super._mint(to, tokenId);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../token/ERC721/IERC721Receiver.sol"; import "../token/ERC721/IERC721Receiver.sol";
contract ERC721ReceiverMock is IERC721Receiver { contract ERC721ReceiverMock is IERC721Receiver {
bytes4 private _retval; enum Error {
bool private _reverts; None,
RevertWithMessage,
RevertWithoutMessage,
Panic
}
bytes4 private immutable _retval;
Error private immutable _error;
event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas); event Received(address operator, address from, uint256 tokenId, bytes data, uint256 gas);
constructor (bytes4 retval, bool reverts) public { constructor (bytes4 retval, Error error) {
_retval = retval; _retval = retval;
_reverts = reverts; _error = error;
} }
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public override returns (bytes4) public override returns (bytes4)
{ {
require(!_reverts, "ERC721ReceiverMock: reverting"); if (_error == Error.RevertWithMessage) {
revert("ERC721ReceiverMock: reverting");
} else if (_error == Error.RevertWithoutMessage) {
revert();
} else if (_error == Error.Panic) {
uint256 a = uint256(0) / uint256(0);
a;
}
emit Received(operator, from, tokenId, data, gasleft()); emit Received(operator, from, tokenId, data, gasleft());
return _retval; return _retval;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
import "../token/ERC777/ERC777.sol"; import "../token/ERC777/ERC777.sol";
...@@ -14,7 +14,7 @@ contract ERC777Mock is Context, ERC777 { ...@@ -14,7 +14,7 @@ contract ERC777Mock is Context, ERC777 {
string memory name, string memory name,
string memory symbol, string memory symbol,
address[] memory defaultOperators address[] memory defaultOperators
) public ERC777(name, symbol, defaultOperators) { ) ERC777(name, symbol, defaultOperators) {
_mint(initialHolder, initialBalance, "", ""); _mint(initialHolder, initialBalance, "", "");
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
import "../token/ERC777/IERC777.sol"; import "../token/ERC777/IERC777.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/EnumerableMap.sol"; import "../utils/EnumerableMap.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/EnumerableSet.sol"; import "../utils/EnumerableSet.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
contract EtherReceiverMock { contract EtherReceiverMock {
bool private _acceptEther; bool private _acceptEther;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../GSN/GSNRecipient.sol"; import "../GSN/GSNRecipient.sol";
import "../GSN/GSNRecipientERC20Fee.sol"; import "../GSN/GSNRecipientERC20Fee.sol";
contract GSNRecipientERC20FeeMock is GSNRecipient, GSNRecipientERC20Fee { contract GSNRecipientERC20FeeMock is GSNRecipient, GSNRecipientERC20Fee {
constructor(string memory name, string memory symbol) public GSNRecipientERC20Fee(name, symbol) { } constructor(string memory name, string memory symbol) GSNRecipientERC20Fee(name, symbol) { }
function mint(address account, uint256 amount) public { function mint(address account, uint256 amount) public {
_mint(account, amount); _mint(account, amount);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ContextMock.sol"; import "./ContextMock.sol";
import "../GSN/GSNRecipient.sol"; import "../GSN/GSNRecipient.sol";
...@@ -13,7 +13,7 @@ contract GSNRecipientMock is ContextMock, GSNRecipient { ...@@ -13,7 +13,7 @@ contract GSNRecipientMock is ContextMock, GSNRecipient {
function acceptRelayedCall(address, address, bytes calldata, uint256, uint256, uint256, uint256, bytes calldata, uint256) function acceptRelayedCall(address, address, bytes calldata, uint256, uint256, uint256, uint256, bytes calldata, uint256)
external external
view pure
override override
returns (uint256, bytes memory) returns (uint256, bytes memory)
{ {
...@@ -28,11 +28,11 @@ contract GSNRecipientMock is ContextMock, GSNRecipient { ...@@ -28,11 +28,11 @@ contract GSNRecipientMock is ContextMock, GSNRecipient {
return _upgradeRelayHub(newRelayHub); return _upgradeRelayHub(newRelayHub);
} }
function _msgSender() internal override(Context, GSNRecipient) view virtual returns (address payable) { function _msgSender() internal override(Context, GSNRecipient) view virtual returns (address) {
return GSNRecipient._msgSender(); return GSNRecipient._msgSender();
} }
function _msgData() internal override(Context, GSNRecipient) view virtual returns (bytes memory) { function _msgData() internal override(Context, GSNRecipient) view virtual returns (bytes calldata) {
return GSNRecipient._msgData(); return GSNRecipient._msgData();
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../GSN/GSNRecipient.sol"; import "../GSN/GSNRecipient.sol";
import "../GSN/GSNRecipientSignature.sol"; import "../GSN/GSNRecipientSignature.sol";
contract GSNRecipientSignatureMock is GSNRecipient, GSNRecipientSignature { contract GSNRecipientSignatureMock is GSNRecipient, GSNRecipientSignature {
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) { } constructor(address trustedSigner) GSNRecipientSignature(trustedSigner) { }
event MockFunctionCalled(); event MockFunctionCalled();
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../proxy/Initializable.sol"; import "../proxy/Initializable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../math/Math.sol"; import "../math/Math.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import { MerkleProof } from "../cryptography/MerkleProof.sol"; import { MerkleProof } from "../cryptography/MerkleProof.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../proxy/Initializable.sol"; import "../proxy/Initializable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../access/Ownable.sol"; import "../access/Ownable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Pausable.sol"; import "../utils/Pausable.sol";
...@@ -8,7 +8,7 @@ contract PausableMock is Pausable { ...@@ -8,7 +8,7 @@ contract PausableMock is Pausable {
bool public drasticMeasureTaken; bool public drasticMeasureTaken;
uint256 public count; uint256 public count;
constructor () public { constructor () {
drasticMeasureTaken = false; drasticMeasureTaken = false;
count = 0; count = 0;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../payment/PullPayment.sol"; import "../payment/PullPayment.sol";
// mock class using PullPayment // mock class using PullPayment
contract PullPaymentMock is PullPayment { contract PullPaymentMock is PullPayment {
constructor () public payable { } constructor () payable { }
// test helper function to call asyncTransfer // test helper function to call asyncTransfer
function callTransfer(address dest, uint256 amount) public { function callTransfer(address dest, uint256 amount) public {
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
contract ReentrancyAttack is Context { contract ReentrancyAttack is Context {
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/ReentrancyGuard.sol"; import "../utils/ReentrancyGuard.sol";
import "./ReentrancyAttack.sol"; import "./ReentrancyAttack.sol";
...@@ -8,7 +8,7 @@ import "./ReentrancyAttack.sol"; ...@@ -8,7 +8,7 @@ import "./ReentrancyAttack.sol";
contract ReentrancyMock is ReentrancyGuard { contract ReentrancyMock is ReentrancyGuard {
uint256 public counter; uint256 public counter;
constructor () public { constructor () {
counter = 0; counter = 0;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../proxy/Initializable.sol"; import "../proxy/Initializable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/SafeCast.sol"; import "../utils/SafeCast.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
import "../token/ERC20/IERC20.sol"; import "../token/ERC20/IERC20.sol";
...@@ -98,7 +98,7 @@ contract SafeERC20Wrapper is Context { ...@@ -98,7 +98,7 @@ contract SafeERC20Wrapper is Context {
IERC20 private _token; IERC20 private _token;
constructor (IERC20 token) public { constructor (IERC20 token) {
_token = token; _token = token;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../math/SignedSafeMath.sol"; import "../math/SignedSafeMath.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../proxy/Initializable.sol"; import "../proxy/Initializable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Strings.sol"; import "../utils/Strings.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";
...@@ -20,8 +20,6 @@ import "../utils/Address.sol"; ...@@ -20,8 +20,6 @@ import "../utils/Address.sol";
* function. * function.
*/ */
contract PaymentSplitter is Context { contract PaymentSplitter is Context {
using SafeMath for uint256;
event PayeeAdded(address account, uint256 shares); event PayeeAdded(address account, uint256 shares);
event PaymentReleased(address to, uint256 amount); event PaymentReleased(address to, uint256 amount);
event PaymentReceived(address from, uint256 amount); event PaymentReceived(address from, uint256 amount);
...@@ -40,7 +38,7 @@ contract PaymentSplitter is Context { ...@@ -40,7 +38,7 @@ contract PaymentSplitter is Context {
* All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
* duplicates in `payees`. * duplicates in `payees`.
*/ */
constructor (address[] memory payees, uint256[] memory shares_) public payable { constructor (address[] memory payees, uint256[] memory shares_) payable {
// solhint-disable-next-line max-line-length // solhint-disable-next-line max-line-length
require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch"); require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
require(payees.length > 0, "PaymentSplitter: no payees"); require(payees.length > 0, "PaymentSplitter: no payees");
...@@ -105,13 +103,13 @@ contract PaymentSplitter is Context { ...@@ -105,13 +103,13 @@ contract PaymentSplitter is Context {
function release(address payable account) public virtual { function release(address payable account) public virtual {
require(_shares[account] > 0, "PaymentSplitter: account has no shares"); require(_shares[account] > 0, "PaymentSplitter: account has no shares");
uint256 totalReceived = address(this).balance.add(_totalReleased); uint256 totalReceived = address(this).balance + _totalReleased;
uint256 payment = totalReceived.mul(_shares[account]).div(_totalShares).sub(_released[account]); uint256 payment = totalReceived * _shares[account] / _totalShares - _released[account];
require(payment != 0, "PaymentSplitter: account is not due payment"); require(payment != 0, "PaymentSplitter: account is not due payment");
_released[account] = _released[account].add(payment); _released[account] = _released[account] + payment;
_totalReleased = _totalReleased.add(payment); _totalReleased = _totalReleased + payment;
Address.sendValue(account, payment); Address.sendValue(account, payment);
emit PaymentReleased(account, payment); emit PaymentReleased(account, payment);
...@@ -129,7 +127,7 @@ contract PaymentSplitter is Context { ...@@ -129,7 +127,7 @@ contract PaymentSplitter is Context {
_payees.push(account); _payees.push(account);
_shares[account] = shares_; _shares[account] = shares_;
_totalShares = _totalShares.add(shares_); _totalShares = _totalShares + shares_;
emit PayeeAdded(account, shares_); emit PayeeAdded(account, shares_);
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
import "./escrow/Escrow.sol"; import "./escrow/Escrow.sol";
...@@ -25,7 +25,7 @@ import "./escrow/Escrow.sol"; ...@@ -25,7 +25,7 @@ import "./escrow/Escrow.sol";
abstract contract PullPayment { abstract contract PullPayment {
Escrow private _escrow; Escrow private _escrow;
constructor () internal { constructor () {
_escrow = new Escrow(); _escrow = new Escrow();
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./Escrow.sol"; import "./Escrow.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../math/SafeMath.sol";
import "../../access/Ownable.sol"; import "../../access/Ownable.sol";
import "../../utils/Address.sol"; import "../../utils/Address.sol";
...@@ -20,7 +19,6 @@ import "../../utils/Address.sol"; ...@@ -20,7 +19,6 @@ import "../../utils/Address.sol";
* to the escrow's deposit and withdraw. * to the escrow's deposit and withdraw.
*/ */
contract Escrow is Ownable { contract Escrow is Ownable {
using SafeMath for uint256;
using Address for address payable; using Address for address payable;
event Deposited(address indexed payee, uint256 weiAmount); event Deposited(address indexed payee, uint256 weiAmount);
...@@ -38,7 +36,7 @@ contract Escrow is Ownable { ...@@ -38,7 +36,7 @@ contract Escrow is Ownable {
*/ */
function deposit(address payee) public payable virtual onlyOwner { function deposit(address payee) public payable virtual onlyOwner {
uint256 amount = msg.value; uint256 amount = msg.value;
_deposits[payee] = _deposits[payee].add(amount); _deposits[payee] = _deposits[payee] + amount;
emit Deposited(payee, amount); emit Deposited(payee, amount);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ConditionalEscrow.sol"; import "./ConditionalEscrow.sol";
...@@ -15,6 +15,8 @@ import "./ConditionalEscrow.sol"; ...@@ -15,6 +15,8 @@ import "./ConditionalEscrow.sol";
* with `RefundEscrow` will be made through the owner contract. * with `RefundEscrow` will be made through the owner contract.
*/ */
contract RefundEscrow is ConditionalEscrow { contract RefundEscrow is ConditionalEscrow {
using Address for address payable;
enum State { Active, Refunding, Closed } enum State { Active, Refunding, Closed }
event RefundsClosed(); event RefundsClosed();
...@@ -27,7 +29,7 @@ contract RefundEscrow is ConditionalEscrow { ...@@ -27,7 +29,7 @@ contract RefundEscrow is ConditionalEscrow {
* @dev Constructor. * @dev Constructor.
* @param beneficiary_ The beneficiary of the deposits. * @param beneficiary_ The beneficiary of the deposits.
*/ */
constructor (address payable beneficiary_) public { constructor (address payable beneficiary_) {
require(beneficiary_ != address(0), "RefundEscrow: beneficiary is the zero address"); require(beneficiary_ != address(0), "RefundEscrow: beneficiary is the zero address");
_beneficiary = beneficiary_; _beneficiary = beneficiary_;
_state = State.Active; _state = State.Active;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../access/AccessControl.sol"; import "../access/AccessControl.sol";
import "../utils/Context.sol"; import "../utils/Context.sol";
...@@ -30,7 +30,7 @@ contract ERC1155PresetMinterPauser is Context, AccessControl, ERC1155Burnable, E ...@@ -30,7 +30,7 @@ contract ERC1155PresetMinterPauser is Context, AccessControl, ERC1155Burnable, E
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE`, and `PAUSER_ROLE` to the account that
* deploys the contract. * deploys the contract.
*/ */
constructor(string memory uri) public ERC1155(uri) { constructor(string memory uri) ERC1155(uri) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender());
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.2; pragma solidity ^0.8.0;
import "../token/ERC20/ERC20Burnable.sol"; import "../token/ERC20/ERC20Burnable.sol";
...@@ -26,7 +26,7 @@ contract ERC20PresetFixedSupply is ERC20Burnable { ...@@ -26,7 +26,7 @@ contract ERC20PresetFixedSupply is ERC20Burnable {
string memory symbol, string memory symbol,
uint256 initialSupply, uint256 initialSupply,
address owner address owner
) public ERC20(name, symbol) { ) ERC20(name, symbol) {
_mint(owner, initialSupply); _mint(owner, initialSupply);
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../access/AccessControl.sol"; import "../access/AccessControl.sol";
import "../utils/Context.sol"; import "../utils/Context.sol";
...@@ -32,7 +32,7 @@ contract ERC20PresetMinterPauser is Context, AccessControl, ERC20Burnable, ERC20 ...@@ -32,7 +32,7 @@ contract ERC20PresetMinterPauser is Context, AccessControl, ERC20Burnable, ERC20
* *
* See {ERC20-constructor}. * See {ERC20-constructor}.
*/ */
constructor(string memory name, string memory symbol) public ERC20(name, symbol) { constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender());
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../access/AccessControl.sol"; import "../access/AccessControl.sol";
import "../utils/Context.sol"; import "../utils/Context.sol";
...@@ -39,7 +39,7 @@ contract ERC721PresetMinterPauserAutoId is Context, AccessControl, ERC721Burnabl ...@@ -39,7 +39,7 @@ contract ERC721PresetMinterPauserAutoId is Context, AccessControl, ERC721Burnabl
* Token URIs will be autogenerated based on `baseURI` and their token IDs. * Token URIs will be autogenerated based on `baseURI` and their token IDs.
* See {ERC721-tokenURI}. * See {ERC721-tokenURI}.
*/ */
constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) { constructor(string memory name, string memory symbol, string memory baseURI) ERC721(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
_setupRole(MINTER_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender());
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.2; pragma solidity ^0.8.0;
import "../token/ERC777/ERC777.sol"; import "../token/ERC777/ERC777.sol";
...@@ -23,7 +23,7 @@ contract ERC777PresetFixedSupply is ERC777 { ...@@ -23,7 +23,7 @@ contract ERC777PresetFixedSupply is ERC777 {
address[] memory defaultOperators, address[] memory defaultOperators,
uint256 initialSupply, uint256 initialSupply,
address owner address owner
) public ERC777(name, symbol, defaultOperators) { ) ERC777(name, symbol, defaultOperators) {
_mint(owner, initialSupply, "", ""); _mint(owner, initialSupply, "", "");
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./Proxy.sol"; import "./Proxy.sol";
import "../utils/Address.sol"; import "../utils/Address.sol";
...@@ -32,7 +32,7 @@ contract BeaconProxy is Proxy { ...@@ -32,7 +32,7 @@ contract BeaconProxy is Proxy {
* *
* - `beacon` must be a contract with the interface {IBeacon}. * - `beacon` must be a contract with the interface {IBeacon}.
*/ */
constructor(address beacon, bytes memory data) public payable { constructor(address beacon, bytes memory data) payable {
assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1)); assert(_BEACON_SLOT == bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1));
_setBeacon(beacon, data); _setBeacon(beacon, data);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev This is the interface that {BeaconProxy} expects of its beacon. * @dev This is the interface that {BeaconProxy} expects of its beacon.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-version // solhint-disable-next-line compiler-version
pragma solidity >=0.4.24 <0.8.0; pragma solidity ^0.8.0;
import "../utils/Address.sol"; import "../utils/Address.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../access/Ownable.sol"; import "../access/Ownable.sol";
import "./TransparentUpgradeableProxy.sol"; import "./TransparentUpgradeableProxy.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./UpgradeableProxy.sol"; import "./UpgradeableProxy.sol";
...@@ -30,7 +30,7 @@ contract TransparentUpgradeableProxy is UpgradeableProxy { ...@@ -30,7 +30,7 @@ contract TransparentUpgradeableProxy is UpgradeableProxy {
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
* optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}. * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
*/ */
constructor(address _logic, address admin_, bytes memory _data) public payable UpgradeableProxy(_logic, _data) { constructor(address _logic, address admin_, bytes memory _data) payable UpgradeableProxy(_logic, _data) {
assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
_setAdmin(admin_); _setAdmin(admin_);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./IBeacon.sol"; import "./IBeacon.sol";
import "../access/Ownable.sol"; import "../access/Ownable.sol";
...@@ -24,7 +24,7 @@ contract UpgradeableBeacon is IBeacon, Ownable { ...@@ -24,7 +24,7 @@ contract UpgradeableBeacon is IBeacon, Ownable {
* @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the
* beacon. * beacon.
*/ */
constructor(address implementation_) public { constructor(address implementation_) {
_setImplementation(implementation_); _setImplementation(implementation_);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./Proxy.sol"; import "./Proxy.sol";
import "../utils/Address.sol"; import "../utils/Address.sol";
...@@ -21,7 +21,7 @@ contract UpgradeableProxy is Proxy { ...@@ -21,7 +21,7 @@ contract UpgradeableProxy is Proxy {
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializating the storage of the proxy like a Solidity constructor. * function call, and allows initializating the storage of the proxy like a Solidity constructor.
*/ */
constructor(address _logic, bytes memory _data) public payable { constructor(address _logic, bytes memory _data) payable {
assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
_setImplementation(_logic); _setImplementation(_logic);
if(_data.length > 0) { if(_data.length > 0) {
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./IERC1155.sol"; import "./IERC1155.sol";
import "./IERC1155MetadataURI.sol"; import "./IERC1155MetadataURI.sol";
import "./IERC1155Receiver.sol"; import "./IERC1155Receiver.sol";
import "../../utils/Context.sol"; import "../../utils/Context.sol";
import "../../introspection/ERC165.sol"; import "../../introspection/ERC165.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol"; import "../../utils/Address.sol";
/** /**
...@@ -19,7 +18,6 @@ import "../../utils/Address.sol"; ...@@ -19,7 +18,6 @@ import "../../utils/Address.sol";
* _Available since v3.1._ * _Available since v3.1._
*/ */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using SafeMath for uint256;
using Address for address; using Address for address;
// Mapping from token ID to account balances // Mapping from token ID to account balances
...@@ -31,35 +29,17 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { ...@@ -31,35 +29,17 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri; string private _uri;
/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
* bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
*
* => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
* 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
*/
bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
/*
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
*/
bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
/** /**
* @dev See {_setURI}. * @dev See {_setURI}.
*/ */
constructor (string memory uri_) public { constructor (string memory uri_) {
_setURI(uri_); _setURI(uri_);
// register the supported interfaces to conform to ERC1155 via ERC165 // register the supported interfaces to conform to ERC1155 via ERC165
_registerInterface(_INTERFACE_ID_ERC1155); _registerInterface(type(IERC1155).interfaceId);
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165 // register the supported interfaces to conform to ERC1155MetadataURI via ERC165
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI); _registerInterface(type(IERC1155MetadataURI).interfaceId);
} }
/** /**
...@@ -157,8 +137,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { ...@@ -157,8 +137,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
_beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data); _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer"); require(_balances[id][from] >= amount, "ERC1155: insufficient balance for transfer");
_balances[id][to] = _balances[id][to].add(amount); _balances[id][from] -= amount;
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount); emit TransferSingle(operator, from, to, id, amount);
...@@ -194,11 +175,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { ...@@ -194,11 +175,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
uint256 id = ids[i]; uint256 id = ids[i];
uint256 amount = amounts[i]; uint256 amount = amounts[i];
_balances[id][from] = _balances[id][from].sub( require(_balances[id][from] >= amount, "ERC1155: insufficient balance for transfer");
amount, _balances[id][from] -= amount;
"ERC1155: insufficient balance for transfer" _balances[id][to] += amount;
);
_balances[id][to] = _balances[id][to].add(amount);
} }
emit TransferBatch(operator, from, to, ids, amounts); emit TransferBatch(operator, from, to, ids, amounts);
...@@ -247,7 +226,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { ...@@ -247,7 +226,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
_beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data); _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
_balances[id][account] = _balances[id][account].add(amount); _balances[id][account] += amount;
emit TransferSingle(operator, address(0), account, id, amount); emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data); _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
...@@ -271,7 +250,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { ...@@ -271,7 +250,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint i = 0; i < ids.length; i++) { for (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]); _balances[ids[i]][to] += amounts[i];
} }
emit TransferBatch(operator, address(0), to, ids, amounts); emit TransferBatch(operator, address(0), to, ids, amounts);
...@@ -294,10 +273,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { ...@@ -294,10 +273,8 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
_beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), ""); _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
_balances[id][account] = _balances[id][account].sub( require(_balances[id][account] >= amount, "ERC1155: burn amount exceeds balance");
amount, _balances[id][account] -= amount;
"ERC1155: burn amount exceeds balance"
);
emit TransferSingle(operator, account, address(0), id, amount); emit TransferSingle(operator, account, address(0), id, amount);
} }
...@@ -318,10 +295,11 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { ...@@ -318,10 +295,11 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
_beforeTokenTransfer(operator, account, address(0), ids, amounts, ""); _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
for (uint i = 0; i < ids.length; i++) { for (uint i = 0; i < ids.length; i++) {
_balances[ids[i]][account] = _balances[ids[i]][account].sub( uint256 id = ids[i];
amounts[i], uint256 amount = amounts[i];
"ERC1155: burn amount exceeds balance"
); require(_balances[id][account] >= amount, "ERC1155: burn amount exceeds balance");
_balances[id][account] -= amount;
} }
emit TransferBatch(operator, account, address(0), ids, amounts); emit TransferBatch(operator, account, address(0), ids, amounts);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ERC1155.sol"; import "./ERC1155.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol"; import "./ERC1155Receiver.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ERC1155.sol"; import "./ERC1155.sol";
import "../../utils/Pausable.sol"; import "../../utils/Pausable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./IERC1155Receiver.sol"; import "./IERC1155Receiver.sol";
import "../../introspection/ERC165.sol"; import "../../introspection/ERC165.sol";
...@@ -9,10 +9,7 @@ import "../../introspection/ERC165.sol"; ...@@ -9,10 +9,7 @@ import "../../introspection/ERC165.sol";
* @dev _Available since v3.1._ * @dev _Available since v3.1._
*/ */
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
constructor() internal { constructor() {
_registerInterface( _registerInterface(type(IERC1155Receiver).interfaceId);
ERC1155Receiver(address(0)).onERC1155Received.selector ^
ERC1155Receiver(address(0)).onERC1155BatchReceived.selector
);
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
import "../../introspection/IERC165.sol"; import "../../introspection/IERC165.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
import "./IERC1155.sol"; import "./IERC1155.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../introspection/IERC165.sol"; import "../../introspection/IERC165.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../utils/Context.sol"; import "../../utils/Context.sol";
import "./IERC20.sol"; import "./IERC20.sol";
import "../../math/SafeMath.sol";
/** /**
* @dev Implementation of the {IERC20} interface. * @dev Implementation of the {IERC20} interface.
...@@ -31,8 +30,6 @@ import "../../math/SafeMath.sol"; ...@@ -31,8 +30,6 @@ import "../../math/SafeMath.sol";
* allowances. See {IERC20-approve}. * allowances. See {IERC20-approve}.
*/ */
contract ERC20 is Context, IERC20 { contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances; mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances; mapping (address => mapping (address => uint256)) private _allowances;
...@@ -52,7 +49,7 @@ contract ERC20 is Context, IERC20 { ...@@ -52,7 +49,7 @@ contract ERC20 is Context, IERC20 {
* All three of these values are immutable: they can only be set once during * All three of these values are immutable: they can only be set once during
* construction. * construction.
*/ */
constructor (string memory name_, string memory symbol_) public { constructor (string memory name_, string memory symbol_) {
_name = name_; _name = name_;
_symbol = symbol_; _symbol = symbol_;
_decimals = 18; _decimals = 18;
...@@ -151,7 +148,10 @@ contract ERC20 is Context, IERC20 { ...@@ -151,7 +148,10 @@ contract ERC20 is Context, IERC20 {
*/ */
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount); _transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
require(_allowances[sender][_msgSender()] >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), _allowances[sender][_msgSender()] - amount);
return true; return true;
} }
...@@ -168,7 +168,7 @@ contract ERC20 is Context, IERC20 { ...@@ -168,7 +168,7 @@ contract ERC20 is Context, IERC20 {
* - `spender` cannot be the zero address. * - `spender` cannot be the zero address.
*/ */
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true; return true;
} }
...@@ -187,7 +187,9 @@ contract ERC20 is Context, IERC20 { ...@@ -187,7 +187,9 @@ contract ERC20 is Context, IERC20 {
* `subtractedValue`. * `subtractedValue`.
*/ */
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); require(_allowances[_msgSender()][spender] >= subtractedValue, "ERC20: decreased allowance below zero");
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] - subtractedValue);
return true; return true;
} }
...@@ -211,8 +213,10 @@ contract ERC20 is Context, IERC20 { ...@@ -211,8 +213,10 @@ contract ERC20 is Context, IERC20 {
_beforeTokenTransfer(sender, recipient, amount); _beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); require(_balances[sender] >= amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount); _balances[sender] -= amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount); emit Transfer(sender, recipient, amount);
} }
...@@ -230,8 +234,8 @@ contract ERC20 is Context, IERC20 { ...@@ -230,8 +234,8 @@ contract ERC20 is Context, IERC20 {
_beforeTokenTransfer(address(0), account, amount); _beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount); _totalSupply += amount;
_balances[account] = _balances[account].add(amount); _balances[account] += amount;
emit Transfer(address(0), account, amount); emit Transfer(address(0), account, amount);
} }
...@@ -251,8 +255,10 @@ contract ERC20 is Context, IERC20 { ...@@ -251,8 +255,10 @@ contract ERC20 is Context, IERC20 {
_beforeTokenTransfer(account, address(0), amount); _beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); require(_balances[account] >= amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount); _balances[account] -= amount;
_totalSupply -= amount;
emit Transfer(account, address(0), amount); emit Transfer(account, address(0), amount);
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../utils/Context.sol"; import "../../utils/Context.sol";
import "./ERC20.sol"; import "./ERC20.sol";
...@@ -11,8 +11,6 @@ import "./ERC20.sol"; ...@@ -11,8 +11,6 @@ import "./ERC20.sol";
* recognized off-chain (via event analysis). * recognized off-chain (via event analysis).
*/ */
abstract contract ERC20Burnable is Context, ERC20 { abstract contract ERC20Burnable is Context, ERC20 {
using SafeMath for uint256;
/** /**
* @dev Destroys `amount` tokens from the caller. * @dev Destroys `amount` tokens from the caller.
* *
...@@ -34,9 +32,8 @@ abstract contract ERC20Burnable is Context, ERC20 { ...@@ -34,9 +32,8 @@ abstract contract ERC20Burnable is Context, ERC20 {
* `amount`. * `amount`.
*/ */
function burnFrom(address account, uint256 amount) public virtual { function burnFrom(address account, uint256 amount) public virtual {
uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance"); require(allowance(account, _msgSender()) >= amount, "ERC20: burn amount exceeds allowance");
_approve(account, _msgSender(), allowance(account, _msgSender()) - amount);
_approve(account, _msgSender(), decreasedAllowance);
_burn(account, amount); _burn(account, amount);
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ERC20.sol"; import "./ERC20.sol";
...@@ -8,15 +8,13 @@ import "./ERC20.sol"; ...@@ -8,15 +8,13 @@ import "./ERC20.sol";
* @dev Extension of {ERC20} that adds a cap to the supply of tokens. * @dev Extension of {ERC20} that adds a cap to the supply of tokens.
*/ */
abstract contract ERC20Capped is ERC20 { abstract contract ERC20Capped is ERC20 {
using SafeMath for uint256;
uint256 private _cap; uint256 private _cap;
/** /**
* @dev Sets the value of the `cap`. This value is immutable, it can only be * @dev Sets the value of the `cap`. This value is immutable, it can only be
* set once during construction. * set once during construction.
*/ */
constructor (uint256 cap_) internal { constructor (uint256 cap_) {
require(cap_ > 0, "ERC20Capped: cap is 0"); require(cap_ > 0, "ERC20Capped: cap is 0");
_cap = cap_; _cap = cap_;
} }
...@@ -39,7 +37,7 @@ abstract contract ERC20Capped is ERC20 { ...@@ -39,7 +37,7 @@ abstract contract ERC20Capped is ERC20 {
super._beforeTokenTransfer(from, to, amount); super._beforeTokenTransfer(from, to, amount);
if (from == address(0)) { // When minting tokens if (from == address(0)) { // When minting tokens
require(totalSupply().add(amount) <= cap(), "ERC20Capped: cap exceeded"); require(totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded");
} }
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ERC20.sol"; import "./ERC20.sol";
import "../../utils/Pausable.sol"; import "../../utils/Pausable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../math/SafeMath.sol";
import "../../utils/Arrays.sol"; import "../../utils/Arrays.sol";
import "../../utils/Counters.sol"; import "../../utils/Counters.sol";
import "./ERC20.sol"; import "./ERC20.sol";
...@@ -35,7 +34,6 @@ abstract contract ERC20Snapshot is ERC20 { ...@@ -35,7 +34,6 @@ abstract contract ERC20Snapshot is ERC20 {
// Inspired by Jordi Baylina's MiniMeToken to record historical balances: // Inspired by Jordi Baylina's MiniMeToken to record historical balances:
// https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol
using SafeMath for uint256;
using Arrays for uint256[]; using Arrays for uint256[];
using Counters for Counters.Counter; using Counters for Counters.Counter;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface of the ERC20 standard as defined in the EIP. * @dev Interface of the ERC20 standard as defined in the EIP.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./IERC20.sol"; import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol"; import "../../utils/Address.sol";
/** /**
...@@ -16,7 +15,6 @@ import "../../utils/Address.sol"; ...@@ -16,7 +15,6 @@ import "../../utils/Address.sol";
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc. * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/ */
library SafeERC20 { library SafeERC20 {
using SafeMath for uint256;
using Address for address; using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal { function safeTransfer(IERC20 token, address to, uint256 value) internal {
...@@ -46,14 +44,18 @@ library SafeERC20 { ...@@ -46,14 +44,18 @@ library SafeERC20 {
} }
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value); uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
} }
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
} }
}
/** /**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./SafeERC20.sol"; import "./SafeERC20.sol";
...@@ -23,7 +23,7 @@ contract TokenTimelock { ...@@ -23,7 +23,7 @@ contract TokenTimelock {
// timestamp when token release is enabled // timestamp when token release is enabled
uint256 private _releaseTime; uint256 private _releaseTime;
constructor (IERC20 token_, address beneficiary_, uint256 releaseTime_) public { constructor (IERC20 token_, address beneficiary_, uint256 releaseTime_) {
// solhint-disable-next-line not-rely-on-time // solhint-disable-next-line not-rely-on-time
require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time"); require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time");
_token = token_; _token = token_;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../utils/Context.sol"; import "../../utils/Context.sol";
import "./IERC721.sol"; import "./IERC721.sol";
...@@ -8,7 +8,6 @@ import "./IERC721Metadata.sol"; ...@@ -8,7 +8,6 @@ import "./IERC721Metadata.sol";
import "./IERC721Enumerable.sol"; import "./IERC721Enumerable.sol";
import "./IERC721Receiver.sol"; import "./IERC721Receiver.sol";
import "../../introspection/ERC165.sol"; import "../../introspection/ERC165.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol"; import "../../utils/Address.sol";
import "../../utils/EnumerableSet.sol"; import "../../utils/EnumerableSet.sol";
import "../../utils/EnumerableMap.sol"; import "../../utils/EnumerableMap.sol";
...@@ -19,16 +18,11 @@ import "../../utils/Strings.sol"; ...@@ -19,16 +18,11 @@ import "../../utils/Strings.sol";
* @dev see https://eips.ethereum.org/EIPS/eip-721 * @dev see https://eips.ethereum.org/EIPS/eip-721
*/ */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
using SafeMath for uint256;
using Address for address; using Address for address;
using EnumerableSet for EnumerableSet.UintSet; using EnumerableSet for EnumerableSet.UintSet;
using EnumerableMap for EnumerableMap.UintToAddressMap; using EnumerableMap for EnumerableMap.UintToAddressMap;
using Strings for uint256; using Strings for uint256;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
// Mapping from holder address to their (enumerable) set of owned tokens // Mapping from holder address to their (enumerable) set of owned tokens
mapping (address => EnumerableSet.UintSet) private _holderTokens; mapping (address => EnumerableSet.UintSet) private _holderTokens;
...@@ -53,51 +47,17 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable ...@@ -53,51 +47,17 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
// Base URI // Base URI
string private _baseURI; string private _baseURI;
/*
* bytes4(keccak256('balanceOf(address)')) == 0x70a08231
* bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
* bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
* bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
*
* => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
* 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
*/
bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
/*
* bytes4(keccak256('name()')) == 0x06fdde03
* bytes4(keccak256('symbol()')) == 0x95d89b41
* bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
*
* => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
*/
bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
/*
* bytes4(keccak256('totalSupply()')) == 0x18160ddd
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
* bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
*
* => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
*/
bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
/** /**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/ */
constructor (string memory name_, string memory symbol_) public { constructor (string memory name_, string memory symbol_) {
_name = name_; _name = name_;
_symbol = symbol_; _symbol = symbol_;
// register the supported interfaces to conform to ERC721 via ERC165 // register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(_INTERFACE_ID_ERC721); _registerInterface(type(IERC721).interfaceId);
_registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(type(IERC721Metadata).interfaceId);
_registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); _registerInterface(type(IERC721Enumerable).interfaceId);
} }
/** /**
...@@ -435,18 +395,22 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable ...@@ -435,18 +395,22 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
private returns (bool) private returns (bool)
{ {
if (!to.isContract()) { if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
// solhint-disable-next-line no-inline-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true; return true;
} }
bytes memory returndata = to.functionCall(abi.encodeWithSelector(
IERC721Receiver(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
), "ERC721: transfer to non ERC721Receiver implementer");
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
} }
function _approve(address to, uint256 tokenId) private { function _approve(address to, uint256 tokenId) private {
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../utils/Context.sol"; import "../../utils/Context.sol";
import "./ERC721.sol"; import "./ERC721.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./IERC721Receiver.sol"; import "./IERC721Receiver.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./ERC721.sol"; import "./ERC721.sol";
import "../../utils/Pausable.sol"; import "../../utils/Pausable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
import "../../introspection/IERC165.sol"; import "../../introspection/IERC165.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
import "./IERC721.sol"; import "./IERC721.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
import "./IERC721.sol"; import "./IERC721.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @title ERC721 token receiver interface * @title ERC721 token receiver interface
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../../utils/Context.sol"; import "../../utils/Context.sol";
import "./IERC777.sol"; import "./IERC777.sol";
import "./IERC777Recipient.sol"; import "./IERC777Recipient.sol";
import "./IERC777Sender.sol"; import "./IERC777Sender.sol";
import "../../token/ERC20/IERC20.sol"; import "../../token/ERC20/IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol"; import "../../utils/Address.sol";
import "../../introspection/IERC1820Registry.sol"; import "../../introspection/IERC1820Registry.sol";
...@@ -27,7 +26,6 @@ import "../../introspection/IERC1820Registry.sol"; ...@@ -27,7 +26,6 @@ import "../../introspection/IERC1820Registry.sol";
* destroyed. This makes integration with ERC20 applications seamless. * destroyed. This makes integration with ERC20 applications seamless.
*/ */
contract ERC777 is Context, IERC777, IERC20 { contract ERC777 is Context, IERC777, IERC20 {
using SafeMath for uint256;
using Address for address; using Address for address;
IERC1820Registry constant internal _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); IERC1820Registry constant internal _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
...@@ -39,16 +37,8 @@ contract ERC777 is Context, IERC777, IERC20 { ...@@ -39,16 +37,8 @@ contract ERC777 is Context, IERC777, IERC20 {
string private _name; string private _name;
string private _symbol; string private _symbol;
// We inline the result of the following hashes because Solidity doesn't resolve them at compile time. bytes32 private constant _TOKENS_SENDER_INTERFACE_HASH = keccak256("ERC777TokensSender");
// See https://github.com/ethereum/solidity/issues/4024. bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
// keccak256("ERC777TokensSender")
bytes32 constant private _TOKENS_SENDER_INTERFACE_HASH =
0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;
// keccak256("ERC777TokensRecipient")
bytes32 constant private _TOKENS_RECIPIENT_INTERFACE_HASH =
0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;
// This isn't ever read from - it's only used to respond to the defaultOperators query. // This isn't ever read from - it's only used to respond to the defaultOperators query.
address[] private _defaultOperatorsArray; address[] private _defaultOperatorsArray;
...@@ -70,9 +60,7 @@ contract ERC777 is Context, IERC777, IERC20 { ...@@ -70,9 +60,7 @@ contract ERC777 is Context, IERC777, IERC20 {
string memory name_, string memory name_,
string memory symbol_, string memory symbol_,
address[] memory defaultOperators_ address[] memory defaultOperators_
) ) {
public
{
_name = name_; _name = name_;
_symbol = symbol_; _symbol = symbol_;
...@@ -289,7 +277,9 @@ contract ERC777 is Context, IERC777, IERC20 { ...@@ -289,7 +277,9 @@ contract ERC777 is Context, IERC777, IERC20 {
_callTokensToSend(spender, holder, recipient, amount, "", ""); _callTokensToSend(spender, holder, recipient, amount, "", "");
_move(spender, holder, recipient, amount, "", ""); _move(spender, holder, recipient, amount, "", "");
_approve(holder, spender, _allowances[holder][spender].sub(amount, "ERC777: transfer amount exceeds allowance"));
require(_allowances[holder][spender] >= amount, "ERC777: transfer amount exceeds allowance");
_approve(holder, spender, _allowances[holder][spender] - amount);
_callTokensReceived(spender, holder, recipient, amount, "", "", false); _callTokensReceived(spender, holder, recipient, amount, "", "", false);
...@@ -329,8 +319,8 @@ contract ERC777 is Context, IERC777, IERC20 { ...@@ -329,8 +319,8 @@ contract ERC777 is Context, IERC777, IERC20 {
_beforeTokenTransfer(operator, address(0), account, amount); _beforeTokenTransfer(operator, address(0), account, amount);
// Update state variables // Update state variables
_totalSupply = _totalSupply.add(amount); _totalSupply += amount;
_balances[account] = _balances[account].add(amount); _balances[account] += amount;
_callTokensReceived(operator, address(0), account, amount, userData, operatorData, true); _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);
...@@ -395,8 +385,9 @@ contract ERC777 is Context, IERC777, IERC20 { ...@@ -395,8 +385,9 @@ contract ERC777 is Context, IERC777, IERC20 {
_beforeTokenTransfer(operator, from, address(0), amount); _beforeTokenTransfer(operator, from, address(0), amount);
// Update state variables // Update state variables
_balances[from] = _balances[from].sub(amount, "ERC777: burn amount exceeds balance"); require(_balances[from] >= amount, "ERC777: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount); _balances[from] -= amount;
_totalSupply -= amount;
emit Burned(operator, from, amount, data, operatorData); emit Burned(operator, from, amount, data, operatorData);
emit Transfer(from, address(0), amount); emit Transfer(from, address(0), amount);
...@@ -414,8 +405,9 @@ contract ERC777 is Context, IERC777, IERC20 { ...@@ -414,8 +405,9 @@ contract ERC777 is Context, IERC777, IERC20 {
{ {
_beforeTokenTransfer(operator, from, to, amount); _beforeTokenTransfer(operator, from, to, amount);
_balances[from] = _balances[from].sub(amount, "ERC777: transfer amount exceeds balance"); require(_balances[from] >= amount, "ERC777: transfer amount exceeds balance");
_balances[to] = _balances[to].add(amount); _balances[from] -= amount;
_balances[to] += amount;
emit Sent(operator, from, to, amount, userData, operatorData); emit Sent(operator, from, to, amount, userData, operatorData);
emit Transfer(from, to, amount); emit Transfer(from, to, amount);
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface of the ERC777Token standard as defined in the EIP. * @dev Interface of the ERC777Token standard as defined in the EIP.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Interface of the ERC777TokensSender standard as defined in the EIP. * @dev Interface of the ERC777TokensSender standard as defined in the EIP.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Collection of functions related to the address type * @dev Collection of functions related to the address type
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../math/Math.sol"; import "../math/Math.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/* /*
* @dev Provides information about the current execution context, including the * @dev Provides information about the current execution context, including the
...@@ -13,11 +13,11 @@ pragma solidity >=0.6.0 <0.8.0; ...@@ -13,11 +13,11 @@ pragma solidity >=0.6.0 <0.8.0;
* This contract is only required for intermediate, library-like contracts. * This contract is only required for intermediate, library-like contracts.
*/ */
abstract contract Context { abstract contract Context {
function _msgSender() internal view virtual returns (address payable) { function _msgSender() internal view virtual returns (address) {
return msg.sender; return msg.sender;
} }
function _msgData() internal view virtual returns (bytes memory) { function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data; return msg.data;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "../math/SafeMath.sol";
/** /**
* @title Counters * @title Counters
...@@ -11,13 +9,8 @@ import "../math/SafeMath.sol"; ...@@ -11,13 +9,8 @@ import "../math/SafeMath.sol";
* of elements in a mapping, issuing ERC721 ids, or counting request ids. * of elements in a mapping, issuing ERC721 ids, or counting request ids.
* *
* Include with `using Counters for Counters.Counter;` * Include with `using Counters for Counters.Counter;`
* Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
* overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
* directly accessed.
*/ */
library Counters { library Counters {
using SafeMath for uint256;
struct Counter { struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to // This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
...@@ -30,11 +23,10 @@ library Counters { ...@@ -30,11 +23,10 @@ library Counters {
} }
function increment(Counter storage counter) internal { function increment(Counter storage counter) internal {
// The {SafeMath} overflow check can be skipped here, see the comment at the top
counter._value += 1; counter._value += 1;
} }
function decrement(Counter storage counter) internal { function decrement(Counter storage counter) internal {
counter._value = counter._value.sub(1); counter._value = counter._value - 1;
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Library for managing an enumerable variant of Solidity's * @dev Library for managing an enumerable variant of Solidity's
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Library for managing * @dev Library for managing
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
import "./Context.sol"; import "./Context.sol";
...@@ -29,7 +29,7 @@ abstract contract Pausable is Context { ...@@ -29,7 +29,7 @@ abstract contract Pausable is Context {
/** /**
* @dev Initializes the contract in unpaused state. * @dev Initializes the contract in unpaused state.
*/ */
constructor () internal { constructor () {
_paused = false; _paused = false;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev Contract module that helps prevent reentrant calls to a function. * @dev Contract module that helps prevent reentrant calls to a function.
...@@ -35,7 +35,7 @@ abstract contract ReentrancyGuard { ...@@ -35,7 +35,7 @@ abstract contract ReentrancyGuard {
uint256 private _status; uint256 private _status;
constructor () internal { constructor () {
_status = _NOT_ENTERED; _status = _NOT_ENTERED;
} }
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0; pragma solidity ^0.8.0;
/** /**
* @dev String operations. * @dev String operations.
...@@ -23,10 +23,10 @@ library Strings { ...@@ -23,10 +23,10 @@ library Strings {
temp /= 10; temp /= 10;
} }
bytes memory buffer = new bytes(digits); bytes memory buffer = new bytes(digits);
uint256 index = digits - 1; uint256 index = digits;
temp = value; temp = value;
while (temp != 0) { while (temp != 0) {
buffer[index--] = bytes1(uint8(48 + temp % 10)); buffer[--index] = bytes1(uint8(48 + uint256(temp % 10)));
temp /= 10; temp /= 10;
} }
return string(buffer); return string(buffer);
......
...@@ -13,7 +13,7 @@ OpenZeppelin provides xref:api:access.adoc#Ownable[`Ownable`] for implementing o ...@@ -13,7 +13,7 @@ OpenZeppelin provides xref:api:access.adoc#Ownable[`Ownable`] for implementing o
---- ----
// contracts/MyContract.sol // contracts/MyContract.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/access/Ownable.sol";
...@@ -62,7 +62,7 @@ Here's a simple example of using `AccessControl` in an xref:tokens.adoc#ERC20[`E ...@@ -62,7 +62,7 @@ Here's a simple example of using `AccessControl` in an xref:tokens.adoc#ERC20[`E
---- ----
// contracts/MyToken.sol // contracts/MyToken.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
...@@ -71,7 +71,7 @@ contract MyToken is ERC20, AccessControl { ...@@ -71,7 +71,7 @@ contract MyToken is ERC20, AccessControl {
// Create a new role identifier for the minter role // Create a new role identifier for the minter role
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
constructor(address minter) public ERC20("MyToken", "TKN") { constructor(address minter) ERC20("MyToken", "TKN") {
// Grant the minter role to a specified account // Grant the minter role to a specified account
_setupRole(MINTER_ROLE, minter); _setupRole(MINTER_ROLE, minter);
} }
...@@ -94,7 +94,7 @@ Let's augment our ERC20 token example by also defining a 'burner' role, which le ...@@ -94,7 +94,7 @@ Let's augment our ERC20 token example by also defining a 'burner' role, which le
---- ----
// contracts/MyToken.sol // contracts/MyToken.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
...@@ -103,7 +103,7 @@ contract MyToken is ERC20, AccessControl { ...@@ -103,7 +103,7 @@ contract MyToken is ERC20, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
constructor(address minter, address burner) public ERC20("MyToken", "TKN") { constructor(address minter, address burner) ERC20("MyToken", "TKN") {
_setupRole(MINTER_ROLE, minter); _setupRole(MINTER_ROLE, minter);
_setupRole(BURNER_ROLE, burner); _setupRole(BURNER_ROLE, burner);
} }
...@@ -139,7 +139,7 @@ Let's take a look at the ERC20 token example, this time taking advantage of the ...@@ -139,7 +139,7 @@ Let's take a look at the ERC20 token example, this time taking advantage of the
---- ----
// contracts/MyToken.sol // contracts/MyToken.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
...@@ -148,7 +148,7 @@ contract MyToken is ERC20, AccessControl { ...@@ -148,7 +148,7 @@ contract MyToken is ERC20, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
constructor() public ERC20("MyToken", "TKN") { constructor() ERC20("MyToken", "TKN") {
// Grant the contract deployer the default admin role: it will be able // Grant the contract deployer the default admin role: it will be able
// to grant and revoke any roles // to grant and revoke any roles
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
......
...@@ -34,7 +34,7 @@ Here's what a contract for tokenized items might look like: ...@@ -34,7 +34,7 @@ Here's what a contract for tokenized items might look like:
---- ----
// contracts/GameItems.sol // contracts/GameItems.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
...@@ -45,7 +45,7 @@ contract GameItems is ERC1155 { ...@@ -45,7 +45,7 @@ contract GameItems is ERC1155 {
uint256 public constant SWORD = 3; uint256 public constant SWORD = 3;
uint256 public constant SHIELD = 4; uint256 public constant SHIELD = 4;
constructor() public ERC1155("https://game.example/api/item/{id}.json") { constructor() ERC1155("https://game.example/api/item/{id}.json") {
_mint(msg.sender, GOLD, 10**18, ""); _mint(msg.sender, GOLD, 10**18, "");
_mint(msg.sender, SILVER, 10**27, ""); _mint(msg.sender, SILVER, 10**27, "");
_mint(msg.sender, THORS_HAMMER, 1, ""); _mint(msg.sender, THORS_HAMMER, 1, "");
...@@ -132,7 +132,7 @@ In order for our contract to receive ERC1155 tokens we can inherit from the conv ...@@ -132,7 +132,7 @@ In order for our contract to receive ERC1155 tokens we can inherit from the conv
---- ----
// contracts/MyContract.sol // contracts/MyContract.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC1155/ERC1155Holder.sol"; import "@openzeppelin/contracts/token/ERC1155/ERC1155Holder.sol";
......
...@@ -14,7 +14,7 @@ Let's say we want a token with a fixed supply of 1000, initially allocated to th ...@@ -14,7 +14,7 @@ Let's say we want a token with a fixed supply of 1000, initially allocated to th
[source,solidity] [source,solidity]
---- ----
contract ERC20FixedSupply is ERC20 { contract ERC20FixedSupply is ERC20 {
constructor() public { constructor() {
totalSupply += 1000; totalSupply += 1000;
balances[msg.sender] += 1000; balances[msg.sender] += 1000;
} }
...@@ -26,7 +26,7 @@ Starting with Contracts v2 this pattern is not only discouraged, but disallowed. ...@@ -26,7 +26,7 @@ Starting with Contracts v2 this pattern is not only discouraged, but disallowed.
[source,solidity] [source,solidity]
---- ----
contract ERC20FixedSupply is ERC20 { contract ERC20FixedSupply is ERC20 {
constructor() public ERC20("Fixed", "FIX") { constructor() ERC20("Fixed", "FIX") {
_mint(msg.sender, 1000); _mint(msg.sender, 1000);
} }
} }
...@@ -44,7 +44,7 @@ The mechanism we will implement is a token reward for the miners that produce Et ...@@ -44,7 +44,7 @@ The mechanism we will implement is a token reward for the miners that produce Et
[source,solidity] [source,solidity]
---- ----
contract ERC20WithMinerReward is ERC20 { contract ERC20WithMinerReward is ERC20 {
constructor() public ERC20("Reward", "RWD") {} constructor() ERC20("Reward", "RWD") {}
function mintMinerReward() public { function mintMinerReward() public {
_mint(block.coinbase, 1000); _mint(block.coinbase, 1000);
...@@ -68,7 +68,7 @@ The accounts with the minter role don't need to be externally owned, though, and ...@@ -68,7 +68,7 @@ The accounts with the minter role don't need to be externally owned, though, and
contract MinerRewardMinter { contract MinerRewardMinter {
ERC20PresetMinterPauser _token; ERC20PresetMinterPauser _token;
constructor(ERC20PresetMinterPauser token) public { constructor(ERC20PresetMinterPauser token) {
_token = token; _token = token;
} }
...@@ -92,7 +92,7 @@ Adding to the supply mechanism from previous sections, we can use this hook to m ...@@ -92,7 +92,7 @@ Adding to the supply mechanism from previous sections, we can use this hook to m
[source,solidity] [source,solidity]
---- ----
contract ERC20WithAutoMinerReward is ERC20 { contract ERC20WithAutoMinerReward is ERC20 {
constructor() public ERC20("Reward", "RWD") {} constructor() ERC20("Reward", "RWD") {}
function _mintMinerReward() internal { function _mintMinerReward() internal {
_mint(block.coinbase, 1000); _mint(block.coinbase, 1000);
......
...@@ -15,12 +15,12 @@ Here's what our GLD token might look like. ...@@ -15,12 +15,12 @@ Here's what our GLD token might look like.
---- ----
// contracts/GLDToken.sol // contracts/GLDToken.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GLDToken is ERC20 { contract GLDToken is ERC20 {
constructor(uint256 initialSupply) public ERC20("Gold", "GLD") { constructor(uint256 initialSupply) ERC20("Gold", "GLD") {
_mint(msg.sender, initialSupply); _mint(msg.sender, initialSupply);
} }
} }
......
...@@ -14,7 +14,7 @@ Here's what a contract for tokenized items might look like: ...@@ -14,7 +14,7 @@ Here's what a contract for tokenized items might look like:
---- ----
// contracts/GameItem.sol // contracts/GameItem.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/utils/Counters.sol";
...@@ -23,7 +23,7 @@ contract GameItem is ERC721 { ...@@ -23,7 +23,7 @@ contract GameItem is ERC721 {
using Counters for Counters.Counter; using Counters for Counters.Counter;
Counters.Counter private _tokenIds; Counters.Counter private _tokenIds;
constructor() public ERC721("GameItem", "ITM") {} constructor() ERC721("GameItem", "ITM") {}
function awardItem(address player, string memory tokenURI) function awardItem(address player, string memory tokenURI)
public public
......
...@@ -20,13 +20,12 @@ We will replicate the `GLD` example of the xref:erc20.adoc#constructing-an-erc20 ...@@ -20,13 +20,12 @@ We will replicate the `GLD` example of the xref:erc20.adoc#constructing-an-erc20
---- ----
// contracts/GLDToken.sol // contracts/GLDToken.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC777/ERC777.sol"; import "@openzeppelin/contracts/token/ERC777/ERC777.sol";
contract GLDToken is ERC777 { contract GLDToken is ERC777 {
constructor(uint256 initialSupply, address[] memory defaultOperators) constructor(uint256 initialSupply, address[] memory defaultOperators)
public
ERC777("Gold", "GLD", defaultOperators) ERC777("Gold", "GLD", defaultOperators)
{ {
_mint(msg.sender, initialSupply, "", ""); _mint(msg.sender, initialSupply, "", "");
......
...@@ -20,7 +20,7 @@ For example, imagine you want to change xref:api:access.adoc#AccessControl[`Acce ...@@ -20,7 +20,7 @@ For example, imagine you want to change xref:api:access.adoc#AccessControl[`Acce
```solidity ```solidity
// contracts/ModifiedAccessControl.sol // contracts/ModifiedAccessControl.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
...@@ -48,7 +48,7 @@ Here is a modified version of xref:api:access.adoc#AccessControl[`AccessControl` ...@@ -48,7 +48,7 @@ Here is a modified version of xref:api:access.adoc#AccessControl[`AccessControl`
```solidity ```solidity
// contracts/ModifiedAccessControl.sol // contracts/ModifiedAccessControl.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
...@@ -80,7 +80,7 @@ Hooks are simply functions that are called before or after some action takes pla ...@@ -80,7 +80,7 @@ Hooks are simply functions that are called before or after some action takes pla
Here's how you would implement the `IERC721Receiver` pattern in `ERC20`, using the xref:api:token/ERC20.adoc#ERC20-_beforeTokenTransfer-address-address-uint256-[`_beforeTokenTransfer`] hook: Here's how you would implement the `IERC721Receiver` pattern in `ERC20`, using the xref:api:token/ERC20.adoc#ERC20-_beforeTokenTransfer-address-address-uint256-[`_beforeTokenTransfer`] hook:
```solidity ```solidity
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
......
...@@ -62,7 +62,7 @@ Instead of using `GSNRecipient` directly, your GSN recipient contract will inste ...@@ -62,7 +62,7 @@ Instead of using `GSNRecipient` directly, your GSN recipient contract will inste
import "@openzeppelin/contracts/GSN/GSNRecipientSignature.sol"; import "@openzeppelin/contracts/GSN/GSNRecipientSignature.sol";
contract MyContract is GSNRecipientSignature { contract MyContract is GSNRecipientSignature {
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) { constructor(address trustedSigner) GSNRecipientSignature(trustedSigner) {
} }
} }
---- ----
...@@ -108,7 +108,7 @@ Your GSN recipient contract needs to inherit from `GSNRecipientERC20Fee` along w ...@@ -108,7 +108,7 @@ Your GSN recipient contract needs to inherit from `GSNRecipientERC20Fee` along w
---- ----
// contracts/MyContract.sol // contracts/MyContract.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/GSN/GSNRecipientERC20Fee.sol"; import "@openzeppelin/contracts/GSN/GSNRecipientERC20Fee.sol";
import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
...@@ -116,11 +116,11 @@ import "@openzeppelin/contracts/access/AccessControl.sol"; ...@@ -116,11 +116,11 @@ import "@openzeppelin/contracts/access/AccessControl.sol";
contract MyContract is GSNRecipientERC20Fee, AccessControl { contract MyContract is GSNRecipientERC20Fee, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
constructor() public GSNRecipientERC20Fee("FeeToken", "FEE") { constructor() GSNRecipientERC20Fee("FeeToken", "FEE") {
_setupRole(MINTER_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender());
} }
function _msgSender() internal view override(Context, GSNRecipient) returns (address payable) { function _msgSender() internal view override(Context, GSNRecipient) returns (address) {
return GSNRecipient._msgSender(); return GSNRecipient._msgSender();
} }
...@@ -154,7 +154,7 @@ Once your strategy is ready, all your GSN recipient needs to do is inherit from ...@@ -154,7 +154,7 @@ Once your strategy is ready, all your GSN recipient needs to do is inherit from
[source,solidity] [source,solidity]
---- ----
contract MyContract is MyCustomGSNStrategy { contract MyContract is MyCustomGSNStrategy {
constructor() public MyCustomGSNStrategy() { constructor() MyCustomGSNStrategy() {
} }
} }
---- ----
...@@ -28,12 +28,12 @@ Once installed, you can use the contracts in the library by importing them: ...@@ -28,12 +28,12 @@ Once installed, you can use the contracts in the library by importing them:
---- ----
// contracts/MyNFT.sol // contracts/MyNFT.sol
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.6.0; pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyNFT is ERC721 { contract MyNFT is ERC721 {
constructor() ERC721("MyNFT", "MNFT") public { constructor() ERC721("MyNFT", "MNFT") {
} }
} }
---- ----
......
const fs = require('fs');
const path = require('path');
require('@nomiclabs/hardhat-truffle5');
require('@nomiclabs/hardhat-solhint');
require('solidity-coverage');
for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) {
require(path.join(__dirname, 'hardhat', f));
}
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: '0.8.0',
settings: {
optimizer: {
enabled: false,
runs: 200,
},
},
networks: {
hardhat: {
blockGasLimit: 10000000,
},
},
};
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
"/test/behaviors" "/test/behaviors"
], ],
"scripts": { "scripts": {
"compile": "buidler compile", "compile": "hardhat compile",
"coverage": "buidler coverage", "coverage": "hardhat coverage",
"docs": "oz-docs", "docs": "oz-docs",
"docs:watch": "npm run docs watch contracts 'docs/*.hbs'", "docs:watch": "npm run docs watch contracts 'docs/*.hbs'",
"prepare-docs": "scripts/prepare-docs.sh", "prepare-docs": "scripts/prepare-docs.sh",
...@@ -18,13 +18,13 @@ ...@@ -18,13 +18,13 @@
"lint:fix": "npm run lint:js:fix", "lint:fix": "npm run lint:js:fix",
"lint:js": "eslint --ignore-path .gitignore .", "lint:js": "eslint --ignore-path .gitignore .",
"lint:js:fix": "eslint --ignore-path .gitignore . --fix", "lint:js:fix": "eslint --ignore-path .gitignore . --fix",
"lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"", "lint:sol": "echo 'solidity linter currently disabled' # solhint --max-warnings 0 \"contracts/**/*.sol\"",
"prepublish": "rimraf build contracts/build artifacts cache", "prepublish": "rimraf build contracts/build artifacts cache",
"prepare": "npm run compile", "prepare": "npm run compile",
"prepack": "scripts/prepack.sh", "prepack": "scripts/prepack.sh",
"release": "scripts/release/release.sh", "release": "scripts/release/release.sh",
"version": "scripts/release/version.sh", "version": "scripts/release/version.sh",
"test": "buidler test" "test": "hardhat test"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
...@@ -45,9 +45,9 @@ ...@@ -45,9 +45,9 @@
}, },
"homepage": "https://openzeppelin.com/contracts/", "homepage": "https://openzeppelin.com/contracts/",
"devDependencies": { "devDependencies": {
"@nomiclabs/buidler": "^1.4.8", "@nomiclabs/hardhat-solhint": "^2.0.0",
"@nomiclabs/buidler-truffle5": "^1.3.4", "@nomiclabs/hardhat-truffle5": "^2.0.0",
"@nomiclabs/buidler-web3": "^1.3.4", "@nomiclabs/hardhat-web3": "^2.0.0",
"@openzeppelin/docs-utils": "^0.1.0", "@openzeppelin/docs-utils": "^0.1.0",
"@openzeppelin/gsn-helpers": "^0.2.3", "@openzeppelin/gsn-helpers": "^0.2.3",
"@openzeppelin/gsn-provider": "^0.1.10", "@openzeppelin/gsn-provider": "^0.1.10",
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
"eth-sig-util": "^3.0.0", "eth-sig-util": "^3.0.0",
"ethereumjs-util": "^7.0.7", "ethereumjs-util": "^7.0.7",
"ethereumjs-wallet": "^1.0.1", "ethereumjs-wallet": "^1.0.1",
"hardhat": "^2.0.6",
"lodash.startcase": "^4.4.0", "lodash.startcase": "^4.4.0",
"lodash.zip": "^4.2.0", "lodash.zip": "^4.2.0",
"micromatch": "^4.0.2", "micromatch": "^4.0.2",
......
...@@ -3,6 +3,7 @@ require('@openzeppelin/test-helpers'); ...@@ -3,6 +3,7 @@ require('@openzeppelin/test-helpers');
const { expect } = require('chai'); const { expect } = require('chai');
const ERC165CheckerMock = artifacts.require('ERC165CheckerMock'); const ERC165CheckerMock = artifacts.require('ERC165CheckerMock');
const ERC165MissingData = artifacts.require('ERC165MissingData');
const ERC165NotSupported = artifacts.require('ERC165NotSupported'); const ERC165NotSupported = artifacts.require('ERC165NotSupported');
const ERC165InterfacesSupported = artifacts.require('ERC165InterfacesSupported'); const ERC165InterfacesSupported = artifacts.require('ERC165InterfacesSupported');
...@@ -18,6 +19,33 @@ contract('ERC165Checker', function (accounts) { ...@@ -18,6 +19,33 @@ contract('ERC165Checker', function (accounts) {
this.mock = await ERC165CheckerMock.new(); this.mock = await ERC165CheckerMock.new();
}); });
context('ERC165 missing return data', function () {
beforeEach(async function () {
this.target = await ERC165MissingData.new();
});
it('does not support ERC165', async function () {
const supported = await this.mock.supportsERC165(this.target.address);
expect(supported).to.equal(false);
});
it('does not support mock interface via supportsInterface', async function () {
const supported = await this.mock.supportsInterface(this.target.address, DUMMY_ID);
expect(supported).to.equal(false);
});
it('does not support mock interface via supportsAllInterfaces', async function () {
const supported = await this.mock.supportsAllInterfaces(this.target.address, [DUMMY_ID]);
expect(supported).to.equal(false);
});
it('does not support mock interface via getSupportedInterfaces', async function () {
const supported = await this.mock.getSupportedInterfaces(this.target.address, [DUMMY_ID]);
expect(supported.length).to.equal(1);
expect(supported[0]).to.equal(false);
});
});
context('ERC165 not supported', function () { context('ERC165 not supported', function () {
beforeEach(async function () { beforeEach(async function () {
this.target = await ERC165NotSupported.new(); this.target = await ERC165NotSupported.new();
......
...@@ -26,9 +26,14 @@ contract('SafeMath', function (accounts) { ...@@ -26,9 +26,14 @@ contract('SafeMath', function (accounts) {
} }
async function testFailsCommutative (fn, lhs, rhs, reason, ...extra) { async function testFailsCommutative (fn, lhs, rhs, reason, ...extra) {
if (reason === undefined) {
await expectRevert.unspecified(fn(lhs, rhs, ...extra));
await expectRevert.unspecified(fn(rhs, lhs, ...extra));
} else {
await expectRevert(fn(lhs, rhs, ...extra), reason); await expectRevert(fn(lhs, rhs, ...extra), reason);
await expectRevert(fn(rhs, lhs, ...extra), reason); await expectRevert(fn(rhs, lhs, ...extra), reason);
} }
}
async function testCommutativeIterable (fn, lhs, rhs, expected, ...extra) { async function testCommutativeIterable (fn, lhs, rhs, expected, ...extra) {
expectStruct(await fn(lhs, rhs, ...extra), expected); expectStruct(await fn(lhs, rhs, ...extra), expected);
...@@ -174,7 +179,7 @@ contract('SafeMath', function (accounts) { ...@@ -174,7 +179,7 @@ contract('SafeMath', function (accounts) {
const a = MAX_UINT256; const a = MAX_UINT256;
const b = new BN('1'); const b = new BN('1');
await testFailsCommutative(this.safeMath.doAdd, a, b, 'SafeMath: addition overflow'); await testFailsCommutative(this.safeMath.doAdd, a, b, undefined);
}); });
}); });
...@@ -190,7 +195,7 @@ contract('SafeMath', function (accounts) { ...@@ -190,7 +195,7 @@ contract('SafeMath', function (accounts) {
const a = new BN('1234'); const a = new BN('1234');
const b = new BN('5678'); const b = new BN('5678');
await expectRevert(this.safeMath.doSub(a, b), 'SafeMath: subtraction overflow'); await expectRevert.unspecified(this.safeMath.doSub(a, b));
}); });
}); });
...@@ -213,7 +218,7 @@ contract('SafeMath', function (accounts) { ...@@ -213,7 +218,7 @@ contract('SafeMath', function (accounts) {
const a = MAX_UINT256; const a = MAX_UINT256;
const b = new BN('2'); const b = new BN('2');
await testFailsCommutative(this.safeMath.doMul, a, b, 'SafeMath: multiplication overflow'); await testFailsCommutative(this.safeMath.doMul, a, b, undefined);
}); });
}); });
...@@ -243,7 +248,7 @@ contract('SafeMath', function (accounts) { ...@@ -243,7 +248,7 @@ contract('SafeMath', function (accounts) {
const a = new BN('5678'); const a = new BN('5678');
const b = new BN('0'); const b = new BN('0');
await expectRevert(this.safeMath.doDiv(a, b), 'SafeMath: division by zero'); await expectRevert.unspecified(this.safeMath.doDiv(a, b));
}); });
}); });
...@@ -282,7 +287,7 @@ contract('SafeMath', function (accounts) { ...@@ -282,7 +287,7 @@ contract('SafeMath', function (accounts) {
const a = new BN('5678'); const a = new BN('5678');
const b = new BN('0'); const b = new BN('0');
await expectRevert(this.safeMath.doMod(a, b), 'SafeMath: modulo by zero'); await expectRevert.unspecified(this.safeMath.doMod(a, b));
}); });
}); });
}); });
......
...@@ -15,9 +15,9 @@ contract('SignedSafeMath', function (accounts) { ...@@ -15,9 +15,9 @@ contract('SignedSafeMath', function (accounts) {
expect(await fn(rhs, lhs)).to.be.bignumber.equal(expected); expect(await fn(rhs, lhs)).to.be.bignumber.equal(expected);
} }
async function testFailsCommutative (fn, lhs, rhs, reason) { async function testFailsCommutative (fn, lhs, rhs) {
await expectRevert(fn(lhs, rhs), reason); await expectRevert.unspecified(fn(lhs, rhs));
await expectRevert(fn(rhs, lhs), reason); await expectRevert.unspecified(fn(rhs, lhs));
} }
describe('add', function () { describe('add', function () {
...@@ -39,14 +39,14 @@ contract('SignedSafeMath', function (accounts) { ...@@ -39,14 +39,14 @@ contract('SignedSafeMath', function (accounts) {
const a = MAX_INT256; const a = MAX_INT256;
const b = new BN('1'); const b = new BN('1');
await testFailsCommutative(this.safeMath.add, a, b, 'SignedSafeMath: addition overflow'); await testFailsCommutative(this.safeMath.add, a, b);
}); });
it('reverts on negative addition overflow', async function () { it('reverts on negative addition overflow', async function () {
const a = MIN_INT256; const a = MIN_INT256;
const b = new BN('-1'); const b = new BN('-1');
await testFailsCommutative(this.safeMath.add, a, b, 'SignedSafeMath: addition overflow'); await testFailsCommutative(this.safeMath.add, a, b);
}); });
}); });
...@@ -71,14 +71,14 @@ contract('SignedSafeMath', function (accounts) { ...@@ -71,14 +71,14 @@ contract('SignedSafeMath', function (accounts) {
const a = MAX_INT256; const a = MAX_INT256;
const b = new BN('-1'); const b = new BN('-1');
await expectRevert(this.safeMath.sub(a, b), 'SignedSafeMath: subtraction overflow'); await expectRevert.unspecified(this.safeMath.sub(a, b));
}); });
it('reverts on negative subtraction overflow', async function () { it('reverts on negative subtraction overflow', async function () {
const a = MIN_INT256; const a = MIN_INT256;
const b = new BN('1'); const b = new BN('1');
await expectRevert(this.safeMath.sub(a, b), 'SignedSafeMath: subtraction overflow'); await expectRevert.unspecified(this.safeMath.sub(a, b));
}); });
}); });
...@@ -101,14 +101,14 @@ contract('SignedSafeMath', function (accounts) { ...@@ -101,14 +101,14 @@ contract('SignedSafeMath', function (accounts) {
const a = MAX_INT256; const a = MAX_INT256;
const b = new BN('2'); const b = new BN('2');
await testFailsCommutative(this.safeMath.mul, a, b, 'SignedSafeMath: multiplication overflow'); await testFailsCommutative(this.safeMath.mul, a, b);
}); });
it('reverts when minimum integer is multiplied by -1', async function () { it('reverts when minimum integer is multiplied by -1', async function () {
const a = MIN_INT256; const a = MIN_INT256;
const b = new BN('-1'); const b = new BN('-1');
await testFailsCommutative(this.safeMath.mul, a, b, 'SignedSafeMath: multiplication overflow'); await testFailsCommutative(this.safeMath.mul, a, b);
}); });
}); });
...@@ -139,14 +139,14 @@ contract('SignedSafeMath', function (accounts) { ...@@ -139,14 +139,14 @@ contract('SignedSafeMath', function (accounts) {
const a = new BN('-5678'); const a = new BN('-5678');
const b = new BN('0'); const b = new BN('0');
await expectRevert(this.safeMath.div(a, b), 'SignedSafeMath: division by zero'); await expectRevert.unspecified(this.safeMath.div(a, b));
}); });
it('reverts on overflow, negative second', async function () { it('reverts on overflow, negative second', async function () {
const a = new BN(MIN_INT256); const a = new BN(MIN_INT256);
const b = new BN('-1'); const b = new BN('-1');
await expectRevert(this.safeMath.div(a, b), 'SignedSafeMath: division overflow'); await expectRevert.unspecified(this.safeMath.div(a, b));
}); });
}); });
}); });
...@@ -12,7 +12,7 @@ const BadBeaconNoImpl = artifacts.require('BadBeaconNoImpl'); ...@@ -12,7 +12,7 @@ const BadBeaconNoImpl = artifacts.require('BadBeaconNoImpl');
const BadBeaconNotContract = artifacts.require('BadBeaconNotContract'); const BadBeaconNotContract = artifacts.require('BadBeaconNotContract');
function toChecksumAddress (address) { function toChecksumAddress (address) {
return ethereumjsUtil.toChecksumAddress('0x' + address.replace(/^0x/, '').padStart(40, '0')); return ethereumjsUtil.toChecksumAddress('0x' + address.replace(/^0x/, '').padStart(40, '0').substr(-40));
} }
const BEACON_LABEL = 'eip1967.proxy.beacon'; const BEACON_LABEL = 'eip1967.proxy.beacon';
......
...@@ -20,7 +20,7 @@ const IMPLEMENTATION_LABEL = 'eip1967.proxy.implementation'; ...@@ -20,7 +20,7 @@ const IMPLEMENTATION_LABEL = 'eip1967.proxy.implementation';
const ADMIN_LABEL = 'eip1967.proxy.admin'; const ADMIN_LABEL = 'eip1967.proxy.admin';
function toChecksumAddress (address) { function toChecksumAddress (address) {
return ethereumjsUtil.toChecksumAddress('0x' + address.replace(/^0x/, '').padStart(40, '0')); return ethereumjsUtil.toChecksumAddress('0x' + address.replace(/^0x/, '').padStart(40, '0').substr(-40));
} }
module.exports = function shouldBehaveLikeTransparentUpgradeableProxy (createProxy, accounts) { module.exports = function shouldBehaveLikeTransparentUpgradeableProxy (createProxy, accounts) {
......
...@@ -29,7 +29,7 @@ module.exports = function shouldBehaveLikeUpgradeableProxy (createProxy, proxyAd ...@@ -29,7 +29,7 @@ module.exports = function shouldBehaveLikeUpgradeableProxy (createProxy, proxyAd
const assertProxyInitialization = function ({ value, balance }) { const assertProxyInitialization = function ({ value, balance }) {
it('sets the implementation address', async function () { it('sets the implementation address', async function () {
const slot = '0x' + new BN(ethereumjsUtil.keccak256(Buffer.from(IMPLEMENTATION_LABEL))).subn(1).toString(16); const slot = '0x' + new BN(ethereumjsUtil.keccak256(Buffer.from(IMPLEMENTATION_LABEL))).subn(1).toString(16);
const implementation = toChecksumAddress(await web3.eth.getStorageAt(this.proxy, slot)); const implementation = toChecksumAddress((await web3.eth.getStorageAt(this.proxy, slot)).substr(-40));
expect(implementation).to.be.equal(this.implementation); expect(implementation).to.be.equal(this.implementation);
}); });
......
...@@ -8,6 +8,9 @@ const { shouldSupportInterfaces } = require('../../introspection/SupportsInterfa ...@@ -8,6 +8,9 @@ const { shouldSupportInterfaces } = require('../../introspection/SupportsInterfa
const ERC721Mock = artifacts.require('ERC721Mock'); const ERC721Mock = artifacts.require('ERC721Mock');
const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock'); const ERC721ReceiverMock = artifacts.require('ERC721ReceiverMock');
const Error = [ 'None', 'RevertWithMessage', 'RevertWithoutMessage', 'Panic' ]
.reduce((acc, entry, idx) => Object.assign({ [entry]: idx }, acc), {});
contract('ERC721', function (accounts) { contract('ERC721', function (accounts) {
const [owner, newOwner, approved, anotherApproved, operator, other] = accounts; const [owner, newOwner, approved, anotherApproved, operator, other] = accounts;
...@@ -324,7 +327,7 @@ contract('ERC721', function (accounts) { ...@@ -324,7 +327,7 @@ contract('ERC721', function (accounts) {
describe('to a valid receiver contract', function () { describe('to a valid receiver contract', function () {
beforeEach(async function () { beforeEach(async function () {
this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, false); this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None);
this.toWhom = this.receiver.address; this.toWhom = this.receiver.address;
}); });
...@@ -379,7 +382,7 @@ contract('ERC721', function (accounts) { ...@@ -379,7 +382,7 @@ contract('ERC721', function (accounts) {
describe('to a receiver contract returning unexpected value', function () { describe('to a receiver contract returning unexpected value', function () {
it('reverts', async function () { it('reverts', async function () {
const invalidReceiver = await ERC721ReceiverMock.new('0x42', false); const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None);
await expectRevert( await expectRevert(
this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }), this.token.safeTransferFrom(owner, invalidReceiver.address, tokenId, { from: owner }),
'ERC721: transfer to non ERC721Receiver implementer', 'ERC721: transfer to non ERC721Receiver implementer',
...@@ -387,9 +390,9 @@ contract('ERC721', function (accounts) { ...@@ -387,9 +390,9 @@ contract('ERC721', function (accounts) {
}); });
}); });
describe('to a receiver contract that throws', function () { describe('to a receiver contract that reverts with message', function () {
it('reverts', async function () { it('reverts', async function () {
const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, true); const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage);
await expectRevert( await expectRevert(
this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }), this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }),
'ERC721ReceiverMock: reverting', 'ERC721ReceiverMock: reverting',
...@@ -397,6 +400,25 @@ contract('ERC721', function (accounts) { ...@@ -397,6 +400,25 @@ contract('ERC721', function (accounts) {
}); });
}); });
describe('to a receiver contract that reverts without message', function () {
it('reverts', async function () {
const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage);
await expectRevert(
this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }),
'ERC721: transfer to non ERC721Receiver implementer',
);
});
});
describe('to a receiver contract that panics', function () {
it('reverts', async function () {
const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic);
await expectRevert.unspecified(
this.token.safeTransferFrom(owner, revertingReceiver.address, tokenId, { from: owner }),
);
});
});
describe('to a contract that does not implement the required function', function () { describe('to a contract that does not implement the required function', function () {
it('reverts', async function () { it('reverts', async function () {
const nonReceiver = this.token; const nonReceiver = this.token;
...@@ -416,7 +438,7 @@ contract('ERC721', function (accounts) { ...@@ -416,7 +438,7 @@ contract('ERC721', function (accounts) {
describe('via safeMint', function () { // regular minting is tested in ERC721Mintable.test.js and others describe('via safeMint', function () { // regular minting is tested in ERC721Mintable.test.js and others
it('calls onERC721Received — with data', async function () { it('calls onERC721Received — with data', async function () {
this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, false); this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None);
const receipt = await this.token.safeMint(this.receiver.address, tokenId, data); const receipt = await this.token.safeMint(this.receiver.address, tokenId, data);
await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
...@@ -427,7 +449,7 @@ contract('ERC721', function (accounts) { ...@@ -427,7 +449,7 @@ contract('ERC721', function (accounts) {
}); });
it('calls onERC721Received — without data', async function () { it('calls onERC721Received — without data', async function () {
this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, false); this.receiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.None);
const receipt = await this.token.safeMint(this.receiver.address, tokenId); const receipt = await this.token.safeMint(this.receiver.address, tokenId);
await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', { await expectEvent.inTransaction(receipt.tx, ERC721ReceiverMock, 'Received', {
...@@ -438,7 +460,7 @@ contract('ERC721', function (accounts) { ...@@ -438,7 +460,7 @@ contract('ERC721', function (accounts) {
context('to a receiver contract returning unexpected value', function () { context('to a receiver contract returning unexpected value', function () {
it('reverts', async function () { it('reverts', async function () {
const invalidReceiver = await ERC721ReceiverMock.new('0x42', false); const invalidReceiver = await ERC721ReceiverMock.new('0x42', Error.None);
await expectRevert( await expectRevert(
this.token.safeMint(invalidReceiver.address, tokenId), this.token.safeMint(invalidReceiver.address, tokenId),
'ERC721: transfer to non ERC721Receiver implementer', 'ERC721: transfer to non ERC721Receiver implementer',
...@@ -446,9 +468,9 @@ contract('ERC721', function (accounts) { ...@@ -446,9 +468,9 @@ contract('ERC721', function (accounts) {
}); });
}); });
context('to a receiver contract that throws', function () { context('to a receiver contract that reverts with message', function () {
it('reverts', async function () { it('reverts', async function () {
const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, true); const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithMessage);
await expectRevert( await expectRevert(
this.token.safeMint(revertingReceiver.address, tokenId), this.token.safeMint(revertingReceiver.address, tokenId),
'ERC721ReceiverMock: reverting', 'ERC721ReceiverMock: reverting',
...@@ -456,6 +478,25 @@ contract('ERC721', function (accounts) { ...@@ -456,6 +478,25 @@ contract('ERC721', function (accounts) {
}); });
}); });
context('to a receiver contract that reverts without message', function () {
it('reverts', async function () {
const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.RevertWithoutMessage);
await expectRevert(
this.token.safeMint(revertingReceiver.address, tokenId),
'ERC721: transfer to non ERC721Receiver implementer',
);
});
});
context('to a receiver contract that panics', function () {
it('reverts', async function () {
const revertingReceiver = await ERC721ReceiverMock.new(RECEIVER_MAGIC_VALUE, Error.Panic);
await expectRevert.unspecified(
this.token.safeMint(revertingReceiver.address, tokenId),
);
});
});
context('to a contract that does not implement the required function', function () { context('to a contract that does not implement the required function', function () {
it('reverts', async function () { it('reverts', async function () {
const nonReceiver = this.token; const nonReceiver = this.token;
......
...@@ -143,7 +143,7 @@ contract('Address', function (accounts) { ...@@ -143,7 +143,7 @@ contract('Address', function (accounts) {
}, []); }, []);
await expectRevert( await expectRevert(
this.mock.functionCall(this.contractRecipient.address, abiEncodedCall, { gas: '90000' }), this.mock.functionCall(this.contractRecipient.address, abiEncodedCall, { gas: '100000' }),
'Address: low-level call failed', 'Address: low-level call failed',
); );
}); });
...@@ -155,9 +155,8 @@ contract('Address', function (accounts) { ...@@ -155,9 +155,8 @@ contract('Address', function (accounts) {
inputs: [], inputs: [],
}, []); }, []);
await expectRevert( await expectRevert.unspecified(
this.mock.functionCall(this.contractRecipient.address, abiEncodedCall), this.mock.functionCall(this.contractRecipient.address, abiEncodedCall),
'Address: low-level call failed',
); );
}); });
......
...@@ -43,7 +43,7 @@ contract('Counters', function (accounts) { ...@@ -43,7 +43,7 @@ contract('Counters', function (accounts) {
it('reverts if the current value is 0', async function () { it('reverts if the current value is 0', async function () {
await this.counter.decrement(); await this.counter.decrement();
await expectRevert(this.counter.decrement(), 'SafeMath: subtraction overflow'); await expectRevert.unspecified(this.counter.decrement());
}); });
}); });
context('after incremented to 3', function () { context('after incremented to 3', function () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment