Rename ERC interfaces to I prefix (#1252)

* rename ERC20 to IERC20

* move ERC20.sol to IERC20.sol

* rename StandardToken to ERC20

* rename StandardTokenMock to ERC20Mock

* move StandardToken.sol to ERC20.sol, likewise test and mock files

* rename MintableToken to ERC20Mintable

* move MintableToken.sol to ERC20Mintable.sol, likewise test and mock files

* rename BurnableToken to ERC20Burnable

* move BurnableToken.sol to ERC20Burnable.sol, likewise for related files

* rename CappedToken to ERC20Capped

* move CappedToken.sol to ERC20Capped.sol, likewise for related files

* rename PausableToken to ERC20Pausable

* move PausableToken.sol to ERC20Pausable.sol, likewise for related files

* rename DetailedERC20 to ERC20Detailed

* move DetailedERC20.sol to ERC20Detailed.sol, likewise for related files

* rename ERC721 to IERC721, and likewise for other related interfaces

* move ERC721.sol to IERC721.sol, likewise for other 721 interfaces

* rename ERC721Token to ERC721

* move ERC721Token.sol to ERC721.sol, likewise for related files

* rename ERC721BasicToken to ERC721Basic

* move ERC721BasicToken.sol to ERC721Basic.sol, likewise for related files

* rename ERC721PausableToken to ERC721Pausable

* move ERC721PausableToken.sol to ERC721Pausable.sol

* rename ERC165 to IERC165

* move ERC165.sol to IERC165.sol

* amend comment that ERC20 is based on FirstBlood

* fix comments mentioning IERC721Receiver
pull/1261/head^2
Francisco Giordano 7 years ago committed by GitHub
parent b6943263d2
commit 2e0713becb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      contracts/AutoIncrementing.sol
  2. 10
      contracts/crowdsale/Crowdsale.sol
  3. 2
      contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol
  4. 4
      contracts/crowdsale/emission/AllowanceCrowdsale.sol
  5. 4
      contracts/crowdsale/emission/MintedCrowdsale.sol
  6. 6
      contracts/examples/SampleCrowdsale.sol
  7. 6
      contracts/examples/SimpleToken.sol
  8. 4
      contracts/introspection/IERC165.sol
  9. 4
      contracts/introspection/SupportsInterfaceWithLookup.sol
  10. 4
      contracts/lifecycle/TokenDestructible.sol
  11. 4
      contracts/mocks/AllowanceCrowdsaleImpl.sol
  12. 4
      contracts/mocks/CappedCrowdsaleImpl.sol
  13. 8
      contracts/mocks/DetailedERC20Mock.sol
  14. 4
      contracts/mocks/ERC165/ERC165InterfacesSupported.sol
  15. 4
      contracts/mocks/ERC20BurnableMock.sol
  16. 6
      contracts/mocks/ERC20Mock.sol
  17. 6
      contracts/mocks/ERC20PausableMock.sol
  18. 4
      contracts/mocks/ERC20WithMetadataMock.sol
  19. 4
      contracts/mocks/ERC223TokenMock.sol
  20. 6
      contracts/mocks/ERC721BasicMock.sol
  21. 8
      contracts/mocks/ERC721Mock.sol
  22. 6
      contracts/mocks/ERC721PausableMock.sol
  23. 4
      contracts/mocks/ERC721ReceiverMock.sol
  24. 4
      contracts/mocks/FinalizableCrowdsaleImpl.sol
  25. 2
      contracts/mocks/IncreasingPriceCrowdsaleImpl.sol
  26. 4
      contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol
  27. 4
      contracts/mocks/MintedCrowdsaleImpl.sol
  28. 4
      contracts/mocks/PostDeliveryCrowdsaleImpl.sol
  29. 6
      contracts/mocks/RBACCappedTokenMock.sol
  30. 4
      contracts/mocks/RefundableCrowdsaleImpl.sol
  31. 12
      contracts/mocks/SafeERC20Helper.sol
  32. 4
      contracts/mocks/TimedCrowdsaleImpl.sol
  33. 4
      contracts/mocks/WhitelistedCrowdsaleImpl.sol
  34. 6
      contracts/ownership/CanReclaimToken.sol
  35. 6
      contracts/proposals/ERC1046/TokenMetadata.sol
  36. 213
      contracts/token/ERC20/ERC20.sol
  37. 6
      contracts/token/ERC20/ERC20Burnable.sol
  38. 4
      contracts/token/ERC20/ERC20Capped.sol
  39. 6
      contracts/token/ERC20/ERC20Detailed.sol
  40. 4
      contracts/token/ERC20/ERC20Mintable.sol
  41. 6
      contracts/token/ERC20/ERC20Pausable.sol
  42. 35
      contracts/token/ERC20/IERC20.sol
  43. 4
      contracts/token/ERC20/RBACMintableToken.sol
  44. 8
      contracts/token/ERC20/SafeERC20.sol
  45. 204
      contracts/token/ERC20/StandardToken.sol
  46. 6
      contracts/token/ERC20/TokenTimelock.sol
  47. 10
      contracts/token/ERC20/TokenVesting.sol
  48. 203
      contracts/token/ERC721/ERC721.sol
  49. 344
      contracts/token/ERC721/ERC721Basic.sol
  50. 310
      contracts/token/ERC721/ERC721BasicToken.sol
  51. 4
      contracts/token/ERC721/ERC721Holder.sol
  52. 6
      contracts/token/ERC721/ERC721Pausable.sol
  53. 201
      contracts/token/ERC721/ERC721Token.sol
  54. 4
      contracts/token/ERC721/IDeprecatedERC721.sol
  55. 40
      contracts/token/ERC721/IERC721.sol
  56. 80
      contracts/token/ERC721/IERC721Basic.sol
  57. 4
      contracts/token/ERC721/IERC721Receiver.sol
  58. 4
      test/crowdsale/FinalizableCrowdsale.test.js
  59. 10
      test/crowdsale/MintedCrowdsale.test.js
  60. 4
      test/lifecycle/TokenDestructible.test.js
  61. 4
      test/ownership/CanReclaimToken.test.js
  62. 12
      test/token/ERC20/BurnableToken.test.js
  63. 25
      test/token/ERC20/CappedToken.test.js
  64. 6
      test/token/ERC20/DetailedERC20.test.js
  65. 6
      test/token/ERC20/ERC20.test.js
  66. 4
      test/token/ERC20/ERC20Burnable.behavior.js
  67. 12
      test/token/ERC20/ERC20Burnable.test.js
  68. 4
      test/token/ERC20/ERC20Capped.behavior.js
  69. 25
      test/token/ERC20/ERC20Capped.test.js
  70. 4
      test/token/ERC20/ERC20Mintable.behavior.js
  71. 10
      test/token/ERC20/ERC20Mintable.test.js
  72. 6
      test/token/ERC20/ERC20Pausable.test.js
  73. 10
      test/token/ERC20/MintableToken.test.js
  74. 8
      test/token/ERC20/RBACCappedToken.test.js
  75. 4
      test/token/ERC20/RBACMintableToken.test.js
  76. 4
      test/token/ERC20/TokenTimelock.test.js
  77. 4
      test/token/ERC20/TokenVesting.test.js
  78. 14
      test/token/ERC721/ERC721.test.js
  79. 6
      test/token/ERC721/ERC721Basic.behavior.js
  80. 18
      test/token/ERC721/ERC721Basic.test.js
  81. 18
      test/token/ERC721/ERC721BasicToken.test.js
  82. 6
      test/token/ERC721/ERC721MintBurn.behavior.js
  83. 12
      test/token/ERC721/ERC721Pausable.test.js
  84. 2
      test/token/ERC721/ERC721PausedToken.behavior.js

@ -5,7 +5,7 @@ pragma solidity ^0.4.24;
* @title AutoIncrementing
* @author Matt Condon (@shrugs)
* @dev Provides an auto-incrementing uint256 id acquired by the `Counter#nextId` getter.
* Use this for issuing ERC721Token ids or keeping track of request ids, anything you want, really.
* Use this for issuing ERC721 ids or keeping track of request ids, anything you want, really.
*
* Include with `using AutoIncrementing for AutoIncrementing.Counter;`
* @notice Does not allow an Id of 0, which is popularly used to signify a null state in solidity.

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../math/SafeMath.sol";
import "../token/ERC20/SafeERC20.sol";
@ -19,17 +19,17 @@ import "../token/ERC20/SafeERC20.sol";
*/
contract Crowdsale {
using SafeMath for uint256;
using SafeERC20 for ERC20;
using SafeERC20 for IERC20;
// The token being sold
ERC20 public token;
IERC20 public token;
// Address where funds are collected
address public wallet;
// How many token units a buyer gets per wei.
// The rate is the conversion between wei and the smallest and indivisible token unit.
// So, if you are using a rate of 1 with a DetailedERC20 token with 3 decimals called TOK
// So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
// 1 wei will give you 1 unit, or 0.001 TOK.
uint256 public rate;
@ -55,7 +55,7 @@ contract Crowdsale {
* @param _wallet Address where collected funds will be forwarded to
* @param _token Address of the token being sold
*/
constructor(uint256 _rate, address _wallet, ERC20 _token) public {
constructor(uint256 _rate, address _wallet, IERC20 _token) public {
require(_rate > 0);
require(_wallet != address(0));
require(_token != address(0));

@ -1,7 +1,7 @@
pragma solidity ^0.4.24;
import "../validation/TimedCrowdsale.sol";
import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/IERC20.sol";
import "../../math/SafeMath.sol";

@ -1,7 +1,7 @@
pragma solidity ^0.4.24;
import "../Crowdsale.sol";
import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/IERC20.sol";
import "../../token/ERC20/SafeERC20.sol";
import "../../math/SafeMath.sol";
@ -12,7 +12,7 @@ import "../../math/SafeMath.sol";
*/
contract AllowanceCrowdsale is Crowdsale {
using SafeMath for uint256;
using SafeERC20 for ERC20;
using SafeERC20 for IERC20;
address public tokenWallet;

@ -1,7 +1,7 @@
pragma solidity ^0.4.24;
import "../Crowdsale.sol";
import "../../token/ERC20/MintableToken.sol";
import "../../token/ERC20/ERC20Mintable.sol";
/**
@ -23,6 +23,6 @@ contract MintedCrowdsale is Crowdsale {
internal
{
// Potentially dangerous assumption about the type of the token.
require(MintableToken(address(token)).mint(_beneficiary, _tokenAmount));
require(ERC20Mintable(address(token)).mint(_beneficiary, _tokenAmount));
}
}

@ -3,7 +3,7 @@ pragma solidity ^0.4.24;
import "../crowdsale/validation/CappedCrowdsale.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol";
import "../crowdsale/emission/MintedCrowdsale.sol";
import "../token/ERC20/MintableToken.sol";
import "../token/ERC20/ERC20Mintable.sol";
/**
@ -11,7 +11,7 @@ import "../token/ERC20/MintableToken.sol";
* @dev Very simple ERC20 Token that can be minted.
* It is meant to be used in a crowdsale contract.
*/
contract SampleCrowdsaleToken is MintableToken {
contract SampleCrowdsaleToken is ERC20Mintable {
string public constant name = "Sample Crowdsale Token";
string public constant symbol = "SCT";
@ -44,7 +44,7 @@ contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsal
uint256 _rate,
address _wallet,
uint256 _cap,
MintableToken _token,
ERC20Mintable _token,
uint256 _goal
)
public

@ -1,16 +1,16 @@
pragma solidity ^0.4.24;
import "../token/ERC20/StandardToken.sol";
import "../token/ERC20/ERC20.sol";
/**
* @title SimpleToken
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
* Note they can later distribute these tokens as they wish using `transfer` and other
* `StandardToken` functions.
* `ERC20` functions.
*/
contract SimpleToken is StandardToken {
contract SimpleToken is ERC20 {
string public constant name = "SimpleToken";
string public constant symbol = "SIM";

@ -2,10 +2,10 @@ pragma solidity ^0.4.24;
/**
* @title ERC165
* @title IERC165
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
*/
interface ERC165 {
interface IERC165 {
/**
* @notice Query if a contract implements an interface

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "./ERC165.sol";
import "./IERC165.sol";
/**
@ -8,7 +8,7 @@ import "./ERC165.sol";
* @author Matt Condon (@shrugs)
* @dev Implements ERC165 using a lookup table.
*/
contract SupportsInterfaceWithLookup is ERC165 {
contract SupportsInterfaceWithLookup is IERC165 {
bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
/**

@ -1,7 +1,7 @@
pragma solidity ^0.4.24;
import "../ownership/Ownable.sol";
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
/**
@ -25,7 +25,7 @@ contract TokenDestructible is Ownable {
// Transfer tokens to owner
for (uint256 i = 0; i < _tokens.length; i++) {
ERC20 token = ERC20(_tokens[i]);
IERC20 token = IERC20(_tokens[i]);
uint256 balance = token.balanceOf(this);
token.transfer(owner, balance);
}

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../crowdsale/emission/AllowanceCrowdsale.sol";
@ -9,7 +9,7 @@ contract AllowanceCrowdsaleImpl is AllowanceCrowdsale {
constructor (
uint256 _rate,
address _wallet,
ERC20 _token,
IERC20 _token,
address _tokenWallet
)
public

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/CappedCrowdsale.sol";
@ -9,7 +9,7 @@ contract CappedCrowdsaleImpl is CappedCrowdsale {
constructor (
uint256 _rate,
address _wallet,
ERC20 _token,
IERC20 _token,
uint256 _cap
)
public

@ -1,16 +1,16 @@
pragma solidity ^0.4.24;
import "../token/ERC20/StandardToken.sol";
import "../token/ERC20/DetailedERC20.sol";
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/ERC20Detailed.sol";
contract DetailedERC20Mock is StandardToken, DetailedERC20 {
contract ERC20DetailedMock is ERC20, ERC20Detailed {
constructor(
string _name,
string _symbol,
uint8 _decimals
)
DetailedERC20(_name, _symbol, _decimals)
ERC20Detailed(_name, _symbol, _decimals)
public
{}
}

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../../introspection/ERC165.sol";
import "../../introspection/IERC165.sol";
/**
@ -11,7 +11,7 @@ import "../../introspection/ERC165.sol";
* therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works)
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
*/
contract SupportsInterfaceWithLookupMock is ERC165 {
contract SupportsInterfaceWithLookupMock is IERC165 {
bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
/**

@ -1,9 +1,9 @@
pragma solidity ^0.4.24;
import "../token/ERC20/BurnableToken.sol";
import "../token/ERC20/ERC20Burnable.sol";
contract BurnableTokenMock is BurnableToken {
contract ERC20BurnableMock is ERC20Burnable {
constructor(address _initialAccount, uint256 _initialBalance) public {
_mint(_initialAccount, _initialBalance);

@ -1,10 +1,10 @@
pragma solidity ^0.4.24;
import "../token/ERC20/StandardToken.sol";
import "../token/ERC20/ERC20.sol";
// mock class using StandardToken
contract StandardTokenMock is StandardToken {
// mock class using ERC20
contract ERC20Mock is ERC20 {
constructor(address _initialAccount, uint256 _initialBalance) public {
_mint(_initialAccount, _initialBalance);

@ -1,10 +1,10 @@
pragma solidity ^0.4.24;
import "../token/ERC20/PausableToken.sol";
import "../token/ERC20/ERC20Pausable.sol";
// mock class using PausableToken
contract PausableTokenMock is PausableToken {
// mock class using ERC20Pausable
contract ERC20PausableMock is ERC20Pausable {
constructor(address _initialAccount, uint _initialBalance) public {
_mint(_initialAccount, _initialBalance);

@ -1,10 +1,10 @@
pragma solidity ^0.4.21;
import "../token/ERC20/StandardToken.sol";
import "../token/ERC20/ERC20.sol";
import "../proposals/ERC1046/TokenMetadata.sol";
contract ERC20WithMetadataMock is StandardToken, ERC20WithMetadata {
contract ERC20WithMetadataMock is ERC20, ERC20WithMetadata {
constructor(string _tokenURI) public
ERC20WithMetadata(_tokenURI)
{

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/StandardToken.sol";
import "../token/ERC20/ERC20.sol";
contract ERC223ContractInterface {
@ -8,7 +8,7 @@ contract ERC223ContractInterface {
}
contract ERC223TokenMock is StandardToken {
contract ERC223TokenMock is ERC20 {
constructor(address _initialAccount, uint256 _initialBalance) public {
_mint(_initialAccount, _initialBalance);

@ -1,13 +1,13 @@
pragma solidity ^0.4.24;
import "../token/ERC721/ERC721BasicToken.sol";
import "../token/ERC721/ERC721Basic.sol";
/**
* @title ERC721BasicTokenMock
* @title ERC721BasicMock
* This mock just provides a public mint and burn functions for testing purposes
*/
contract ERC721BasicTokenMock is ERC721BasicToken {
contract ERC721BasicMock is ERC721Basic {
function mint(address _to, uint256 _tokenId) public {
super._mint(_to, _tokenId);
}

@ -1,16 +1,16 @@
pragma solidity ^0.4.24;
import "../token/ERC721/ERC721Token.sol";
import "../token/ERC721/ERC721.sol";
/**
* @title ERC721TokenMock
* @title ERC721Mock
* This mock just provides a public mint and burn functions for testing purposes,
* and a public setter for metadata URI
*/
contract ERC721TokenMock is ERC721Token {
contract ERC721Mock is ERC721 {
constructor(string name, string symbol) public
ERC721Token(name, symbol)
ERC721(name, symbol)
{ }
function mint(address _to, uint256 _tokenId) public {

@ -1,13 +1,13 @@
pragma solidity ^0.4.24;
import "../token/ERC721/ERC721PausableToken.sol";
import "../token/ERC721/ERC721Pausable.sol";
/**
* @title ERC721PausableTokenMock
* @title ERC721PausableMock
* This mock just provides a public mint, burn and exists functions for testing purposes
*/
contract ERC721PausableTokenMock is ERC721PausableToken {
contract ERC721PausableMock is ERC721Pausable {
function mint(address _to, uint256 _tokenId) public {
super._mint(_to, _tokenId);
}

@ -1,9 +1,9 @@
pragma solidity ^0.4.24;
import "../token/ERC721/ERC721Receiver.sol";
import "../token/ERC721/IERC721Receiver.sol";
contract ERC721ReceiverMock is ERC721Receiver {
contract ERC721ReceiverMock is IERC721Receiver {
bytes4 retval_;
bool reverts_;

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/MintableToken.sol";
import "../token/ERC20/ERC20Mintable.sol";
import "../crowdsale/distribution/FinalizableCrowdsale.sol";
@ -11,7 +11,7 @@ contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
uint256 _closingTime,
uint256 _rate,
address _wallet,
MintableToken _token
ERC20Mintable _token
)
public
Crowdsale(_rate, _wallet, _token)

@ -10,7 +10,7 @@ contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
uint256 _openingTime,
uint256 _closingTime,
address _wallet,
ERC20 _token,
IERC20 _token,
uint256 _initialRate,
uint256 _finalRate
)

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol";
@ -9,7 +9,7 @@ contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale {
constructor (
uint256 _rate,
address _wallet,
ERC20 _token
IERC20 _token
)
public
Crowdsale(_rate, _wallet, _token)

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/MintableToken.sol";
import "../token/ERC20/ERC20Mintable.sol";
import "../crowdsale/emission/MintedCrowdsale.sol";
@ -9,7 +9,7 @@ contract MintedCrowdsaleImpl is MintedCrowdsale {
constructor (
uint256 _rate,
address _wallet,
MintableToken _token
ERC20Mintable _token
)
public
Crowdsale(_rate, _wallet, _token)

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../crowdsale/distribution/PostDeliveryCrowdsale.sol";
@ -11,7 +11,7 @@ contract PostDeliveryCrowdsaleImpl is PostDeliveryCrowdsale {
uint256 _closingTime,
uint256 _rate,
address _wallet,
ERC20 _token
IERC20 _token
)
public
TimedCrowdsale(_openingTime, _closingTime)

@ -1,12 +1,12 @@
pragma solidity ^0.4.24;
import "../token/ERC20/RBACMintableToken.sol";
import "../token/ERC20/CappedToken.sol";
import "../token/ERC20/ERC20Capped.sol";
contract RBACCappedTokenMock is CappedToken, RBACMintableToken {
contract RBACCappedTokenMock is ERC20Capped, RBACMintableToken {
constructor(uint256 _cap)
CappedToken(_cap)
ERC20Capped(_cap)
public
{}
}

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/MintableToken.sol";
import "../token/ERC20/ERC20Mintable.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol";
@ -11,7 +11,7 @@ contract RefundableCrowdsaleImpl is RefundableCrowdsale {
uint256 _closingTime,
uint256 _rate,
address _wallet,
MintableToken _token,
ERC20Mintable _token,
uint256 _goal
)
public

@ -1,10 +1,10 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/SafeERC20.sol";
contract ERC20FailingMock is ERC20 {
contract ERC20FailingMock is IERC20 {
function totalSupply() public view returns (uint256) {
return 0;
}
@ -31,7 +31,7 @@ contract ERC20FailingMock is ERC20 {
}
contract ERC20SucceedingMock is ERC20 {
contract ERC20SucceedingMock is IERC20 {
function totalSupply() public view returns (uint256) {
return 0;
}
@ -59,10 +59,10 @@ contract ERC20SucceedingMock is ERC20 {
contract SafeERC20Helper {
using SafeERC20 for ERC20;
using SafeERC20 for IERC20;
ERC20 failing;
ERC20 succeeding;
IERC20 failing;
IERC20 succeeding;
constructor() public {
failing = new ERC20FailingMock();

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/TimedCrowdsale.sol";
@ -11,7 +11,7 @@ contract TimedCrowdsaleImpl is TimedCrowdsale {
uint256 _closingTime,
uint256 _rate,
address _wallet,
ERC20 _token
IERC20 _token
)
public
Crowdsale(_rate, _wallet, _token)

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/WhitelistedCrowdsale.sol";
import "../crowdsale/Crowdsale.sol";
@ -10,7 +10,7 @@ contract WhitelistedCrowdsaleImpl is Crowdsale, WhitelistedCrowdsale {
constructor (
uint256 _rate,
address _wallet,
ERC20 _token
IERC20 _token
)
Crowdsale(_rate, _wallet, _token)
public

@ -1,7 +1,7 @@
pragma solidity ^0.4.24;
import "./Ownable.sol";
import "../token/ERC20/ERC20.sol";
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/SafeERC20.sol";
@ -12,13 +12,13 @@ import "../token/ERC20/SafeERC20.sol";
* This will prevent any accidental loss of tokens.
*/
contract CanReclaimToken is Ownable {
using SafeERC20 for ERC20;
using SafeERC20 for IERC20;
/**
* @dev Reclaim all ERC20 compatible tokens
* @param _token ERC20 The address of the token contract
*/
function reclaimToken(ERC20 _token) external onlyOwner {
function reclaimToken(IERC20 _token) external onlyOwner {
uint256 balance = _token.balanceOf(this);
_token.safeTransfer(owner, balance);
}

@ -1,15 +1,15 @@
pragma solidity ^0.4.21;
import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/IERC20.sol";
/**
* @title ERC-1047 Token Metadata
* @dev See https://eips.ethereum.org/EIPS/eip-1046
* @dev tokenURI must respond with a URI that implements https://eips.ethereum.org/EIPS/eip-1047
* @dev TODO - update https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721.sol#L17 when 1046 is finalized
* @dev TODO - update https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721.sol#L17 when 1046 is finalized
*/
contract ERC20TokenMetadata is ERC20 {
contract ERC20TokenMetadata is IERC20 {
function tokenURI() external view returns (string);
}

@ -1,35 +1,204 @@
pragma solidity ^0.4.24;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
* Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract ERC20 {
function totalSupply() public view returns (uint256);
contract ERC20 is IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private balances_;
mapping (address => mapping (address => uint256)) private allowed_;
uint256 private totalSupply_;
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256) {
return balances_[_owner];
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(
address _owner,
address _spender
)
public
view
returns (uint256)
{
return allowed_[_owner][_spender];
}
/**
* @dev Transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_value <= balances_[msg.sender]);
require(_to != address(0));
balances_[msg.sender] = balances_[msg.sender].sub(_value);
balances_[_to] = balances_[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed_[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(
address _from,
address _to,
uint256 _value
)
public
returns (bool)
{
require(_value <= balances_[_from]);
require(_value <= allowed_[_from][msg.sender]);
require(_to != address(0));
balances_[_from] = balances_[_from].sub(_value);
balances_[_to] = balances_[_to].add(_value);
allowed_[_from][msg.sender] = allowed_[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
function balanceOf(address _who) public view returns (uint256);
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed_[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
*/
function increaseApproval(
address _spender,
uint256 _addedValue
)
public
returns (bool)
{
allowed_[msg.sender][_spender] = (
allowed_[msg.sender][_spender].add(_addedValue));
emit Approval(msg.sender, _spender, allowed_[msg.sender][_spender]);
return true;
}
function allowance(address _owner, address _spender)
public view returns (uint256);
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed_[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseApproval(
address _spender,
uint256 _subtractedValue
)
public
returns (bool)
{
uint256 oldValue = allowed_[msg.sender][_spender];
if (_subtractedValue >= oldValue) {
allowed_[msg.sender][_spender] = 0;
} else {
allowed_[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed_[msg.sender][_spender]);
return true;
}
function transfer(address _to, uint256 _value) public returns (bool);
/**
* @dev Internal function that mints an amount of the token and assigns it to
* an account. This encapsulates the modification of balances such that the
* proper events are emitted.
* @param _account The account that will receive the created tokens.
* @param _amount The amount that will be created.
*/
function _mint(address _account, uint256 _amount) internal {
require(_account != 0);
totalSupply_ = totalSupply_.add(_amount);
balances_[_account] = balances_[_account].add(_amount);
emit Transfer(address(0), _account, _amount);
}
function approve(address _spender, uint256 _value)
public returns (bool);
/**
* @dev Internal function that burns an amount of the token of a given
* account.
* @param _account The account whose tokens will be burnt.
* @param _amount The amount that will be burnt.
*/
function _burn(address _account, uint256 _amount) internal {
require(_account != 0);
require(_amount <= balances_[_account]);
function transferFrom(address _from, address _to, uint256 _value)
public returns (bool);
totalSupply_ = totalSupply_.sub(_amount);
balances_[_account] = balances_[_account].sub(_amount);
emit Transfer(_account, address(0), _amount);
}
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
/**
* @dev Internal function that burns an amount of the token of a given
* account, deducting from the sender's allowance for said account. Uses the
* internal _burn function.
* @param _account The account whose tokens will be burnt.
* @param _amount The amount that will be burnt.
*/
function _burnFrom(address _account, uint256 _amount) internal {
require(_amount <= allowed_[_account][msg.sender]);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
// Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted,
// this function needs to emit an event with the updated approval.
allowed_[_account][msg.sender] = allowed_[_account][msg.sender].sub(
_amount);
_burn(_account, _amount);
}
}

@ -1,13 +1,13 @@
pragma solidity ^0.4.24;
import "./StandardToken.sol";
import "./ERC20.sol";
/**
* @title Burnable Token
* @dev Token that can be irreversibly burned (destroyed).
*/
contract BurnableToken is StandardToken {
contract ERC20Burnable is ERC20 {
event TokensBurned(address indexed burner, uint256 value);
@ -29,7 +29,7 @@ contract BurnableToken is StandardToken {
}
/**
* @dev Overrides StandardToken._burn in order for burn and burnFrom to emit
* @dev Overrides ERC20._burn in order for burn and burnFrom to emit
* an additional Burn event.
*/
function _burn(address _who, uint256 _value) internal {

@ -1,13 +1,13 @@
pragma solidity ^0.4.24;
import "./MintableToken.sol";
import "./ERC20Mintable.sol";
/**
* @title Capped token
* @dev Mintable token with a token cap.
*/
contract CappedToken is MintableToken {
contract ERC20Capped is ERC20Mintable {
uint256 public cap;

@ -1,15 +1,15 @@
pragma solidity ^0.4.24;
import "./ERC20.sol";
import "./IERC20.sol";
/**
* @title DetailedERC20 token
* @title ERC20Detailed token
* @dev The decimals are only for visualization purposes.
* All the operations are done using the smallest and indivisible token unit,
* just as on Ethereum all the operations are done in wei.
*/
contract DetailedERC20 is ERC20 {
contract ERC20Detailed is IERC20 {
string public name;
string public symbol;
uint8 public decimals;

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "./StandardToken.sol";
import "./ERC20.sol";
import "../../ownership/Ownable.sol";
@ -9,7 +9,7 @@ import "../../ownership/Ownable.sol";
* @dev Simple ERC20 Token example, with mintable token creation
* Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
*/
contract MintableToken is StandardToken, Ownable {
contract ERC20Mintable is ERC20, Ownable {
event Mint(address indexed to, uint256 amount);
event MintFinished();

@ -1,14 +1,14 @@
pragma solidity ^0.4.24;
import "./StandardToken.sol";
import "./ERC20.sol";
import "../../lifecycle/Pausable.sol";
/**
* @title Pausable token
* @dev StandardToken modified with pausable transfers.
* @dev ERC20 modified with pausable transfers.
**/
contract PausableToken is StandardToken, Pausable {
contract ERC20Pausable is ERC20, Pausable {
function transfer(
address _to,

@ -0,0 +1,35 @@
pragma solidity ^0.4.24;
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
interface IERC20 {
function totalSupply() public view returns (uint256);
function balanceOf(address _who) public view returns (uint256);
function allowance(address _owner, address _spender)
public view returns (uint256);
function transfer(address _to, uint256 _value) public returns (bool);
function approve(address _spender, uint256 _value)
public returns (bool);
function transferFrom(address _from, address _to, uint256 _value)
public returns (bool);
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "./MintableToken.sol";
import "./ERC20Mintable.sol";
import "../../access/rbac/RBAC.sol";
@ -9,7 +9,7 @@ import "../../access/rbac/RBAC.sol";
* @author Vittorio Minacori (@vittominacori)
* @dev Mintable Token, with RBAC minter permissions
*/
contract RBACMintableToken is MintableToken, RBAC {
contract RBACMintableToken is ERC20Mintable, RBAC {
/**
* A constant role name for indicating minters.
*/

@ -1,7 +1,7 @@
pragma solidity ^0.4.24;
import "./StandardToken.sol";
import "./ERC20.sol";
import "./IERC20.sol";
/**
@ -12,7 +12,7 @@ import "./ERC20.sol";
*/
library SafeERC20 {
function safeTransfer(
ERC20 _token,
IERC20 _token,
address _to,
uint256 _value
)
@ -22,7 +22,7 @@ library SafeERC20 {
}
function safeTransferFrom(
ERC20 _token,
IERC20 _token,
address _from,
address _to,
uint256 _value
@ -33,7 +33,7 @@ library SafeERC20 {
}
function safeApprove(
ERC20 _token,
IERC20 _token,
address _spender,
uint256 _value
)

@ -1,204 +0,0 @@
pragma solidity ^0.4.24;
import "./ERC20.sol";
import "../../math/SafeMath.sol";
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
* Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20 {
using SafeMath for uint256;
mapping (address => uint256) private balances_;
mapping (address => mapping (address => uint256)) private allowed_;
uint256 private totalSupply_;
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256) {
return balances_[_owner];
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(
address _owner,
address _spender
)
public
view
returns (uint256)
{
return allowed_[_owner][_spender];
}
/**
* @dev Transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_value <= balances_[msg.sender]);
require(_to != address(0));
balances_[msg.sender] = balances_[msg.sender].sub(_value);
balances_[_to] = balances_[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed_[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(
address _from,
address _to,
uint256 _value
)
public
returns (bool)
{
require(_value <= balances_[_from]);
require(_value <= allowed_[_from][msg.sender]);
require(_to != address(0));
balances_[_from] = balances_[_from].sub(_value);
balances_[_to] = balances_[_to].add(_value);
allowed_[_from][msg.sender] = allowed_[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed_[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
*/
function increaseApproval(
address _spender,
uint256 _addedValue
)
public
returns (bool)
{
allowed_[msg.sender][_spender] = (
allowed_[msg.sender][_spender].add(_addedValue));
emit Approval(msg.sender, _spender, allowed_[msg.sender][_spender]);
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed_[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseApproval(
address _spender,
uint256 _subtractedValue
)
public
returns (bool)
{
uint256 oldValue = allowed_[msg.sender][_spender];
if (_subtractedValue >= oldValue) {
allowed_[msg.sender][_spender] = 0;
} else {
allowed_[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed_[msg.sender][_spender]);
return true;
}
/**
* @dev Internal function that mints an amount of the token and assigns it to
* an account. This encapsulates the modification of balances such that the
* proper events are emitted.
* @param _account The account that will receive the created tokens.
* @param _amount The amount that will be created.
*/
function _mint(address _account, uint256 _amount) internal {
require(_account != 0);
totalSupply_ = totalSupply_.add(_amount);
balances_[_account] = balances_[_account].add(_amount);
emit Transfer(address(0), _account, _amount);
}
/**
* @dev Internal function that burns an amount of the token of a given
* account.
* @param _account The account whose tokens will be burnt.
* @param _amount The amount that will be burnt.
*/
function _burn(address _account, uint256 _amount) internal {
require(_account != 0);
require(_amount <= balances_[_account]);
totalSupply_ = totalSupply_.sub(_amount);
balances_[_account] = balances_[_account].sub(_amount);
emit Transfer(_account, address(0), _amount);
}
/**
* @dev Internal function that burns an amount of the token of a given
* account, deducting from the sender's allowance for said account. Uses the
* internal _burn function.
* @param _account The account whose tokens will be burnt.
* @param _amount The amount that will be burnt.
*/
function _burnFrom(address _account, uint256 _amount) internal {
require(_amount <= allowed_[_account][msg.sender]);
// Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted,
// this function needs to emit an event with the updated approval.
allowed_[_account][msg.sender] = allowed_[_account][msg.sender].sub(
_amount);
_burn(_account, _amount);
}
}

@ -9,10 +9,10 @@ import "./SafeERC20.sol";
* beneficiary to extract the tokens after a given release time
*/
contract TokenTimelock {
using SafeERC20 for ERC20;
using SafeERC20 for IERC20;
// ERC20 basic token contract being held
ERC20 public token;
IERC20 public token;
// beneficiary of tokens after they are released
address public beneficiary;
@ -21,7 +21,7 @@ contract TokenTimelock {
uint256 public releaseTime;
constructor(
ERC20 _token,
IERC20 _token,
address _beneficiary,
uint256 _releaseTime
)

@ -15,7 +15,7 @@ import "../../math/SafeMath.sol";
*/
contract TokenVesting is Ownable {
using SafeMath for uint256;
using SafeERC20 for ERC20;
using SafeERC20 for IERC20;
event Released(uint256 amount);
event Revoked();
@ -65,7 +65,7 @@ contract TokenVesting is Ownable {
* @notice Transfers vested tokens to beneficiary.
* @param _token ERC20 token which is being vested
*/
function release(ERC20 _token) public {
function release(IERC20 _token) public {
uint256 unreleased = releasableAmount(_token);
require(unreleased > 0);
@ -82,7 +82,7 @@ contract TokenVesting is Ownable {
* remain in the contract, the rest are returned to the owner.
* @param _token ERC20 token which is being vested
*/
function revoke(ERC20 _token) public onlyOwner {
function revoke(IERC20 _token) public onlyOwner {
require(revocable);
require(!revoked[_token]);
@ -102,7 +102,7 @@ contract TokenVesting is Ownable {
* @dev Calculates the amount that has already vested but hasn't been released yet.
* @param _token ERC20 token which is being vested
*/
function releasableAmount(ERC20 _token) public view returns (uint256) {
function releasableAmount(IERC20 _token) public view returns (uint256) {
return vestedAmount(_token).sub(released[_token]);
}
@ -110,7 +110,7 @@ contract TokenVesting is Ownable {
* @dev Calculates the amount that has already vested.
* @param _token ERC20 token which is being vested
*/
function vestedAmount(ERC20 _token) public view returns (uint256) {
function vestedAmount(IERC20 _token) public view returns (uint256) {
uint256 currentBalance = _token.balanceOf(this);
uint256 totalBalance = currentBalance.add(released[_token]);

@ -1,40 +1,201 @@
pragma solidity ^0.4.24;
import "./IERC721.sol";
import "./ERC721Basic.sol";
import "../../introspection/SupportsInterfaceWithLookup.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
* @title Full ERC721 Token
* This implementation includes all the required and some optional functionality of the ERC721 standard
* Moreover, it includes approve all functionality using operator terminology
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721Enumerable is ERC721Basic {
function totalSupply() public view returns (uint256);
contract ERC721 is SupportsInterfaceWithLookup, ERC721Basic, IERC721 {
// Token name
string internal name_;
// Token symbol
string internal symbol_;
// Mapping from owner to list of owned token IDs
mapping(address => uint256[]) internal ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) internal ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] internal allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) internal allTokensIndex;
// Optional mapping for token URIs
mapping(uint256 => string) internal tokenURIs;
/**
* @dev Constructor function
*/
constructor(string _name, string _symbol) public {
name_ = _name;
symbol_ = _symbol;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(InterfaceId_ERC721Enumerable);
_registerInterface(InterfaceId_ERC721Metadata);
}
/**
* @dev Gets the token name
* @return string representing the token name
*/
function name() external view returns (string) {
return name_;
}
/**
* @dev Gets the token symbol
* @return string representing the token symbol
*/
function symbol() external view returns (string) {
return symbol_;
}
/**
* @dev Returns an URI for a given token ID
* Throws if the token ID does not exist. May return an empty string.
* @param _tokenId uint256 ID of the token to query
*/
function tokenURI(uint256 _tokenId) public view returns (string) {
require(_exists(_tokenId));
return tokenURIs[_tokenId];
}
/**
* @dev Gets the token ID at a given index of the tokens list of the requested owner
* @param _owner address owning the tokens list to be accessed
* @param _index uint256 representing the index to be accessed of the requested tokens list
* @return uint256 token ID at the given index of the tokens list owned by the requested address
*/
function tokenOfOwnerByIndex(
address _owner,
uint256 _index
)
public
view
returns (uint256 _tokenId);
returns (uint256)
{
require(_index < balanceOf(_owner));
return ownedTokens[_owner][_index];
}
function tokenByIndex(uint256 _index) public view returns (uint256);
}
/**
* @dev Gets the total amount of tokens stored by the contract
* @return uint256 representing the total amount of tokens
*/
function totalSupply() public view returns (uint256) {
return allTokens.length;
}
/**
* @dev Gets the token ID at a given index of all the tokens in this contract
* Reverts if the index is greater or equal to the total number of tokens
* @param _index uint256 representing the index to be accessed of the tokens list
* @return uint256 token ID at the given index of the tokens list
*/
function tokenByIndex(uint256 _index) public view returns (uint256) {
require(_index < totalSupply());
return allTokens[_index];
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721Metadata is ERC721Basic {
function name() external view returns (string _name);
function symbol() external view returns (string _symbol);
function tokenURI(uint256 _tokenId) public view returns (string);
}
/**
* @dev Internal function to set the token URI for a given token
* Reverts if the token ID does not exist
* @param _tokenId uint256 ID of the token to set its URI
* @param _uri string URI to assign
*/
function _setTokenURI(uint256 _tokenId, string _uri) internal {
require(_exists(_tokenId));
tokenURIs[_tokenId] = _uri;
}
/**
* @dev Internal function to add a token ID to the list of a given address
* @param _to address representing the new owner of the given token ID
* @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function addTokenTo(address _to, uint256 _tokenId) internal {
super.addTokenTo(_to, _tokenId);
uint256 length = ownedTokens[_to].length;
ownedTokens[_to].push(_tokenId);
ownedTokensIndex[_tokenId] = length;
}
/**
* @dev Internal function to remove a token ID from the list of a given address
* @param _from address representing the previous owner of the given token ID
* @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function removeTokenFrom(address _from, uint256 _tokenId) internal {
super.removeTokenFrom(_from, _tokenId);
// To prevent a gap in the array, we store the last token in the index of the token to delete, and
// then delete the last slot.
uint256 tokenIndex = ownedTokensIndex[_tokenId];
uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
uint256 lastToken = ownedTokens[_from][lastTokenIndex];
ownedTokens[_from][tokenIndex] = lastToken;
// This also deletes the contents at the last position of the array
ownedTokens[_from].length--;
// Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
// be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
// the lastToken to the first position, and then dropping the element placed in the last position of the list
ownedTokensIndex[_tokenId] = 0;
ownedTokensIndex[lastToken] = tokenIndex;
}
/**
* @dev Internal function to mint a new token
* Reverts if the given token ID already exists
* @param _to address the beneficiary that will own the minted token
* @param _tokenId uint256 ID of the token to be minted by the msg.sender
*/
function _mint(address _to, uint256 _tokenId) internal {
super._mint(_to, _tokenId);
allTokensIndex[_tokenId] = allTokens.length;
allTokens.push(_tokenId);
}
/**
* @dev Internal function to burn a specific token
* Reverts if the token does not exist
* @param _owner owner of the token to burn
* @param _tokenId uint256 ID of the token being burned by the msg.sender
*/
function _burn(address _owner, uint256 _tokenId) internal {
super._burn(_owner, _tokenId);
// Clear metadata (if any)
if (bytes(tokenURIs[_tokenId]).length != 0) {
delete tokenURIs[_tokenId];
}
// Reorg all tokens array
uint256 tokenIndex = allTokensIndex[_tokenId];
uint256 lastTokenIndex = allTokens.length.sub(1);
uint256 lastToken = allTokens[lastTokenIndex];
allTokens[tokenIndex] = lastToken;
allTokens[lastTokenIndex] = 0;
allTokens.length--;
allTokensIndex[_tokenId] = 0;
allTokensIndex[lastToken] = tokenIndex;
}
/**
* @title ERC-721 Non-Fungible Token Standard, full implementation interface
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
}

@ -1,80 +1,310 @@
pragma solidity ^0.4.24;
import "../../introspection/ERC165.sol";
import "./IERC721Basic.sol";
import "./IERC721Receiver.sol";
import "../../math/SafeMath.sol";
import "../../AddressUtils.sol";
import "../../introspection/SupportsInterfaceWithLookup.sol";
/**
* @title ERC721 Non-Fungible Token Standard basic interface
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721Basic is ERC165 {
bytes4 internal constant InterfaceId_ERC721 = 0x80ac58cd;
/*
* 0x80ac58cd ===
* bytes4(keccak256('balanceOf(address)')) ^
* bytes4(keccak256('ownerOf(uint256)')) ^
* bytes4(keccak256('approve(address,uint256)')) ^
* bytes4(keccak256('getApproved(uint256)')) ^
* bytes4(keccak256('setApprovalForAll(address,bool)')) ^
* bytes4(keccak256('isApprovedForAll(address,address)')) ^
* bytes4(keccak256('transferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
contract ERC721Basic is SupportsInterfaceWithLookup, IERC721Basic {
using SafeMath for uint256;
using AddressUtils for address;
// 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 token ID to owner
mapping (uint256 => address) internal tokenOwner;
// Mapping from token ID to approved address
mapping (uint256 => address) internal tokenApprovals;
// Mapping from owner to number of owned token
mapping (address => uint256) internal ownedTokensCount;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) internal operatorApprovals;
constructor()
public
{
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(InterfaceId_ERC721);
}
/**
* @dev Gets the balance of the specified address
* @param _owner address to query the balance of
* @return uint256 representing the amount owned by the passed address
*/
function balanceOf(address _owner) public view returns (uint256) {
require(_owner != address(0));
return ownedTokensCount[_owner];
}
/**
* @dev Gets the owner of the specified token ID
* @param _tokenId uint256 ID of the token to query the owner of
* @return owner address currently marked as the owner of the given token ID
*/
function ownerOf(uint256 _tokenId) public view returns (address) {
address owner = tokenOwner[_tokenId];
require(owner != address(0));
return owner;
}
/**
* @dev Approves another address to transfer the given token ID
* The zero address indicates there is no approved address.
* There can only be one approved address per token at a given time.
* Can only be called by the token owner or an approved operator.
* @param _to address to be approved for the given token ID
* @param _tokenId uint256 ID of the token to be approved
*/
function approve(address _to, uint256 _tokenId) public {
address owner = ownerOf(_tokenId);
require(_to != owner);
require(msg.sender == owner || isApprovedForAll(owner, msg.sender));
tokenApprovals[_tokenId] = _to;
emit Approval(owner, _to, _tokenId);
}
/**
* @dev Gets the approved address for a token ID, or zero if no address set
* @param _tokenId uint256 ID of the token to query the approval of
* @return address currently approved for the given token ID
*/
function getApproved(uint256 _tokenId) public view returns (address) {
return tokenApprovals[_tokenId];
}
bytes4 internal constant InterfaceId_ERC721Enumerable = 0x780e9d63;
/**
* 0x780e9d63 ===
* bytes4(keccak256('totalSupply()')) ^
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
* bytes4(keccak256('tokenByIndex(uint256)'))
* @dev Sets or unsets the approval of a given operator
* An operator is allowed to transfer all tokens of the sender on their behalf
* @param _to operator address to set the approval
* @param _approved representing the status of the approval to be set
*/
function setApprovalForAll(address _to, bool _approved) public {
require(_to != msg.sender);
operatorApprovals[msg.sender][_to] = _approved;
emit ApprovalForAll(msg.sender, _to, _approved);
}
bytes4 internal constant InterfaceId_ERC721Metadata = 0x5b5e139f;
/**
* 0x5b5e139f ===
* bytes4(keccak256('name()')) ^
* bytes4(keccak256('symbol()')) ^
* bytes4(keccak256('tokenURI(uint256)'))
* @dev Tells whether an operator is approved by a given owner
* @param _owner owner address which you want to query the approval of
* @param _operator operator address which you want to query the approval of
* @return bool whether the given operator is approved by the given owner
*/
function isApprovedForAll(
address _owner,
address _operator
)
public
view
returns (bool)
{
return operatorApprovals[_owner][_operator];
}
/**
* @dev Transfers the ownership of a given token ID to another address
* Usage of this method is discouraged, use `safeTransferFrom` whenever possible
* Requires the msg sender to be the owner, approved, or operator
* @param _from current owner of the token
* @param _to address to receive the ownership of the given token ID
* @param _tokenId uint256 ID of the token to be transferred
*/
function transferFrom(
address _from,
address _to,
uint256 _tokenId
)
public
{
require(isApprovedOrOwner(msg.sender, _tokenId));
require(_to != address(0));
clearApproval(_from, _tokenId);
removeTokenFrom(_from, _tokenId);
addTokenTo(_to, _tokenId);
event Transfer(
address indexed _from,
address indexed _to,
uint256 indexed _tokenId
);
event Approval(
address indexed _owner,
address indexed _approved,
uint256 indexed _tokenId
);
event ApprovalForAll(
address indexed _owner,
address indexed _operator,
bool _approved
);
function balanceOf(address _owner) public view returns (uint256 _balance);
function ownerOf(uint256 _tokenId) public view returns (address _owner);
function approve(address _to, uint256 _tokenId) public;
function getApproved(uint256 _tokenId)
public view returns (address _operator);
function setApprovalForAll(address _operator, bool _approved) public;
function isApprovedForAll(address _owner, address _operator)
public view returns (bool);
function transferFrom(address _from, address _to, uint256 _tokenId) public;
function safeTransferFrom(address _from, address _to, uint256 _tokenId)
public;
emit Transfer(_from, _to, _tokenId);
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
*
* Requires the msg sender to be the owner, approved, or operator
* @param _from current owner of the token
* @param _to address to receive the ownership of the given token ID
* @param _tokenId uint256 ID of the token to be transferred
*/
function safeTransferFrom(
address _from,
address _to,
uint256 _tokenId
)
public
{
// solium-disable-next-line arg-overflow
safeTransferFrom(_from, _to, _tokenId, "");
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* Requires the msg sender to be the owner, approved, or operator
* @param _from current owner of the token
* @param _to address to receive the ownership of the given token ID
* @param _tokenId uint256 ID of the token to be transferred
* @param _data bytes data to send along with a safe transfer check
*/
function safeTransferFrom(
address _from,
address _to,
uint256 _tokenId,
bytes _data
)
public;
public
{
transferFrom(_from, _to, _tokenId);
// solium-disable-next-line arg-overflow
require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
}
/**
* @dev Returns whether the specified token exists
* @param _tokenId uint256 ID of the token to query the existence of
* @return whether the token exists
*/
function _exists(uint256 _tokenId) internal view returns (bool) {
address owner = tokenOwner[_tokenId];
return owner != address(0);
}
/**
* @dev Returns whether the given spender can transfer a given token ID
* @param _spender address of the spender to query
* @param _tokenId uint256 ID of the token to be transferred
* @return bool whether the msg.sender is approved for the given token ID,
* is an operator of the owner, or is the owner of the token
*/
function isApprovedOrOwner(
address _spender,
uint256 _tokenId
)
internal
view
returns (bool)
{
address owner = ownerOf(_tokenId);
// Disable solium check because of
// https://github.com/duaraghav8/Solium/issues/175
// solium-disable-next-line operator-whitespace
return (
_spender == owner ||
getApproved(_tokenId) == _spender ||
isApprovedForAll(owner, _spender)
);
}
/**
* @dev Internal function to mint a new token
* Reverts if the given token ID already exists
* @param _to The address that will own the minted token
* @param _tokenId uint256 ID of the token to be minted by the msg.sender
*/
function _mint(address _to, uint256 _tokenId) internal {
require(_to != address(0));
addTokenTo(_to, _tokenId);
emit Transfer(address(0), _to, _tokenId);
}
/**
* @dev Internal function to burn a specific token
* Reverts if the token does not exist
* @param _tokenId uint256 ID of the token being burned by the msg.sender
*/
function _burn(address _owner, uint256 _tokenId) internal {
clearApproval(_owner, _tokenId);
removeTokenFrom(_owner, _tokenId);
emit Transfer(_owner, address(0), _tokenId);
}
/**
* @dev Internal function to clear current approval of a given token ID
* Reverts if the given address is not indeed the owner of the token
* @param _owner owner of the token
* @param _tokenId uint256 ID of the token to be transferred
*/
function clearApproval(address _owner, uint256 _tokenId) internal {
require(ownerOf(_tokenId) == _owner);
if (tokenApprovals[_tokenId] != address(0)) {
tokenApprovals[_tokenId] = address(0);
}
}
/**
* @dev Internal function to add a token ID to the list of a given address
* @param _to address representing the new owner of the given token ID
* @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function addTokenTo(address _to, uint256 _tokenId) internal {
require(tokenOwner[_tokenId] == address(0));
tokenOwner[_tokenId] = _to;
ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
}
/**
* @dev Internal function to remove a token ID from the list of a given address
* @param _from address representing the previous owner of the given token ID
* @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function removeTokenFrom(address _from, uint256 _tokenId) internal {
require(ownerOf(_tokenId) == _from);
ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
tokenOwner[_tokenId] = address(0);
}
/**
* @dev Internal function to invoke `onERC721Received` on a target address
* The call is not executed if the target address is not a contract
* @param _from address representing the previous owner of the given token ID
* @param _to target address that will receive the tokens
* @param _tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return whether the call correctly returned the expected magic value
*/
function checkAndCallSafeTransfer(
address _from,
address _to,
uint256 _tokenId,
bytes _data
)
internal
returns (bool)
{
if (!_to.isContract()) {
return true;
}
bytes4 retval = IERC721Receiver(_to).onERC721Received(
msg.sender, _from, _tokenId, _data);
return (retval == ERC721_RECEIVED);
}
}

@ -1,310 +0,0 @@
pragma solidity ^0.4.24;
import "./ERC721Basic.sol";
import "./ERC721Receiver.sol";
import "../../math/SafeMath.sol";
import "../../AddressUtils.sol";
import "../../introspection/SupportsInterfaceWithLookup.sol";
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721BasicToken is SupportsInterfaceWithLookup, ERC721Basic {
using SafeMath for uint256;
using AddressUtils for address;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
bytes4 private constant ERC721_RECEIVED = 0x150b7a02;
// Mapping from token ID to owner
mapping (uint256 => address) internal tokenOwner;
// Mapping from token ID to approved address
mapping (uint256 => address) internal tokenApprovals;
// Mapping from owner to number of owned token
mapping (address => uint256) internal ownedTokensCount;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) internal operatorApprovals;
constructor()
public
{
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(InterfaceId_ERC721);
}
/**
* @dev Gets the balance of the specified address
* @param _owner address to query the balance of
* @return uint256 representing the amount owned by the passed address
*/
function balanceOf(address _owner) public view returns (uint256) {
require(_owner != address(0));
return ownedTokensCount[_owner];
}
/**
* @dev Gets the owner of the specified token ID
* @param _tokenId uint256 ID of the token to query the owner of
* @return owner address currently marked as the owner of the given token ID
*/
function ownerOf(uint256 _tokenId) public view returns (address) {
address owner = tokenOwner[_tokenId];
require(owner != address(0));
return owner;
}
/**
* @dev Approves another address to transfer the given token ID
* The zero address indicates there is no approved address.
* There can only be one approved address per token at a given time.
* Can only be called by the token owner or an approved operator.
* @param _to address to be approved for the given token ID
* @param _tokenId uint256 ID of the token to be approved
*/
function approve(address _to, uint256 _tokenId) public {
address owner = ownerOf(_tokenId);
require(_to != owner);
require(msg.sender == owner || isApprovedForAll(owner, msg.sender));
tokenApprovals[_tokenId] = _to;
emit Approval(owner, _to, _tokenId);
}
/**
* @dev Gets the approved address for a token ID, or zero if no address set
* @param _tokenId uint256 ID of the token to query the approval of
* @return address currently approved for the given token ID
*/
function getApproved(uint256 _tokenId) public view returns (address) {
return tokenApprovals[_tokenId];
}
/**
* @dev Sets or unsets the approval of a given operator
* An operator is allowed to transfer all tokens of the sender on their behalf
* @param _to operator address to set the approval
* @param _approved representing the status of the approval to be set
*/
function setApprovalForAll(address _to, bool _approved) public {
require(_to != msg.sender);
operatorApprovals[msg.sender][_to] = _approved;
emit ApprovalForAll(msg.sender, _to, _approved);
}
/**
* @dev Tells whether an operator is approved by a given owner
* @param _owner owner address which you want to query the approval of
* @param _operator operator address which you want to query the approval of
* @return bool whether the given operator is approved by the given owner
*/
function isApprovedForAll(
address _owner,
address _operator
)
public
view
returns (bool)
{
return operatorApprovals[_owner][_operator];
}
/**
* @dev Transfers the ownership of a given token ID to another address
* Usage of this method is discouraged, use `safeTransferFrom` whenever possible
* Requires the msg sender to be the owner, approved, or operator
* @param _from current owner of the token
* @param _to address to receive the ownership of the given token ID
* @param _tokenId uint256 ID of the token to be transferred
*/
function transferFrom(
address _from,
address _to,
uint256 _tokenId
)
public
{
require(isApprovedOrOwner(msg.sender, _tokenId));
require(_to != address(0));
clearApproval(_from, _tokenId);
removeTokenFrom(_from, _tokenId);
addTokenTo(_to, _tokenId);
emit Transfer(_from, _to, _tokenId);
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
*
* Requires the msg sender to be the owner, approved, or operator
* @param _from current owner of the token
* @param _to address to receive the ownership of the given token ID
* @param _tokenId uint256 ID of the token to be transferred
*/
function safeTransferFrom(
address _from,
address _to,
uint256 _tokenId
)
public
{
// solium-disable-next-line arg-overflow
safeTransferFrom(_from, _to, _tokenId, "");
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* Requires the msg sender to be the owner, approved, or operator
* @param _from current owner of the token
* @param _to address to receive the ownership of the given token ID
* @param _tokenId uint256 ID of the token to be transferred
* @param _data bytes data to send along with a safe transfer check
*/
function safeTransferFrom(
address _from,
address _to,
uint256 _tokenId,
bytes _data
)
public
{
transferFrom(_from, _to, _tokenId);
// solium-disable-next-line arg-overflow
require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
}
/**
* @dev Returns whether the specified token exists
* @param _tokenId uint256 ID of the token to query the existence of
* @return whether the token exists
*/
function _exists(uint256 _tokenId) internal view returns (bool) {
address owner = tokenOwner[_tokenId];
return owner != address(0);
}
/**
* @dev Returns whether the given spender can transfer a given token ID
* @param _spender address of the spender to query
* @param _tokenId uint256 ID of the token to be transferred
* @return bool whether the msg.sender is approved for the given token ID,
* is an operator of the owner, or is the owner of the token
*/
function isApprovedOrOwner(
address _spender,
uint256 _tokenId
)
internal
view
returns (bool)
{
address owner = ownerOf(_tokenId);
// Disable solium check because of
// https://github.com/duaraghav8/Solium/issues/175
// solium-disable-next-line operator-whitespace
return (
_spender == owner ||
getApproved(_tokenId) == _spender ||
isApprovedForAll(owner, _spender)
);
}
/**
* @dev Internal function to mint a new token
* Reverts if the given token ID already exists
* @param _to The address that will own the minted token
* @param _tokenId uint256 ID of the token to be minted by the msg.sender
*/
function _mint(address _to, uint256 _tokenId) internal {
require(_to != address(0));
addTokenTo(_to, _tokenId);
emit Transfer(address(0), _to, _tokenId);
}
/**
* @dev Internal function to burn a specific token
* Reverts if the token does not exist
* @param _tokenId uint256 ID of the token being burned by the msg.sender
*/
function _burn(address _owner, uint256 _tokenId) internal {
clearApproval(_owner, _tokenId);
removeTokenFrom(_owner, _tokenId);
emit Transfer(_owner, address(0), _tokenId);
}
/**
* @dev Internal function to clear current approval of a given token ID
* Reverts if the given address is not indeed the owner of the token
* @param _owner owner of the token
* @param _tokenId uint256 ID of the token to be transferred
*/
function clearApproval(address _owner, uint256 _tokenId) internal {
require(ownerOf(_tokenId) == _owner);
if (tokenApprovals[_tokenId] != address(0)) {
tokenApprovals[_tokenId] = address(0);
}
}
/**
* @dev Internal function to add a token ID to the list of a given address
* @param _to address representing the new owner of the given token ID
* @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function addTokenTo(address _to, uint256 _tokenId) internal {
require(tokenOwner[_tokenId] == address(0));
tokenOwner[_tokenId] = _to;
ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
}
/**
* @dev Internal function to remove a token ID from the list of a given address
* @param _from address representing the previous owner of the given token ID
* @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function removeTokenFrom(address _from, uint256 _tokenId) internal {
require(ownerOf(_tokenId) == _from);
ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
tokenOwner[_tokenId] = address(0);
}
/**
* @dev Internal function to invoke `onERC721Received` on a target address
* The call is not executed if the target address is not a contract
* @param _from address representing the previous owner of the given token ID
* @param _to target address that will receive the tokens
* @param _tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return whether the call correctly returned the expected magic value
*/
function checkAndCallSafeTransfer(
address _from,
address _to,
uint256 _tokenId,
bytes _data
)
internal
returns (bool)
{
if (!_to.isContract()) {
return true;
}
bytes4 retval = ERC721Receiver(_to).onERC721Received(
msg.sender, _from, _tokenId, _data);
return (retval == ERC721_RECEIVED);
}
}

@ -1,9 +1,9 @@
pragma solidity ^0.4.24;
import "./ERC721Receiver.sol";
import "./IERC721Receiver.sol";
contract ERC721Holder is ERC721Receiver {
contract ERC721Holder is IERC721Receiver {
function onERC721Received(
address,
address,

@ -1,14 +1,14 @@
pragma solidity ^0.4.24;
import "./ERC721BasicToken.sol";
import "./ERC721Basic.sol";
import "../../lifecycle/Pausable.sol";
/**
* @title ERC721 Non-Fungible Pausable token
* @dev ERC721BasicToken modified with pausable transfers.
* @dev ERC721Basic modified with pausable transfers.
**/
contract ERC721PausableToken is ERC721BasicToken, Pausable {
contract ERC721Pausable is ERC721Basic, Pausable {
function approve(
address _to,
uint256 _tokenId

@ -1,201 +0,0 @@
pragma solidity ^0.4.24;
import "./ERC721.sol";
import "./ERC721BasicToken.sol";
import "../../introspection/SupportsInterfaceWithLookup.sol";
/**
* @title Full ERC721 Token
* This implementation includes all the required and some optional functionality of the ERC721 standard
* Moreover, it includes approve all functionality using operator terminology
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 {
// Token name
string internal name_;
// Token symbol
string internal symbol_;
// Mapping from owner to list of owned token IDs
mapping(address => uint256[]) internal ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) internal ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] internal allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) internal allTokensIndex;
// Optional mapping for token URIs
mapping(uint256 => string) internal tokenURIs;
/**
* @dev Constructor function
*/
constructor(string _name, string _symbol) public {
name_ = _name;
symbol_ = _symbol;
// register the supported interfaces to conform to ERC721 via ERC165
_registerInterface(InterfaceId_ERC721Enumerable);
_registerInterface(InterfaceId_ERC721Metadata);
}
/**
* @dev Gets the token name
* @return string representing the token name
*/
function name() external view returns (string) {
return name_;
}
/**
* @dev Gets the token symbol
* @return string representing the token symbol
*/
function symbol() external view returns (string) {
return symbol_;
}
/**
* @dev Returns an URI for a given token ID
* Throws if the token ID does not exist. May return an empty string.
* @param _tokenId uint256 ID of the token to query
*/
function tokenURI(uint256 _tokenId) public view returns (string) {
require(_exists(_tokenId));
return tokenURIs[_tokenId];
}
/**
* @dev Gets the token ID at a given index of the tokens list of the requested owner
* @param _owner address owning the tokens list to be accessed
* @param _index uint256 representing the index to be accessed of the requested tokens list
* @return uint256 token ID at the given index of the tokens list owned by the requested address
*/
function tokenOfOwnerByIndex(
address _owner,
uint256 _index
)
public
view
returns (uint256)
{
require(_index < balanceOf(_owner));
return ownedTokens[_owner][_index];
}
/**
* @dev Gets the total amount of tokens stored by the contract
* @return uint256 representing the total amount of tokens
*/
function totalSupply() public view returns (uint256) {
return allTokens.length;
}
/**
* @dev Gets the token ID at a given index of all the tokens in this contract
* Reverts if the index is greater or equal to the total number of tokens
* @param _index uint256 representing the index to be accessed of the tokens list
* @return uint256 token ID at the given index of the tokens list
*/
function tokenByIndex(uint256 _index) public view returns (uint256) {
require(_index < totalSupply());
return allTokens[_index];
}
/**
* @dev Internal function to set the token URI for a given token
* Reverts if the token ID does not exist
* @param _tokenId uint256 ID of the token to set its URI
* @param _uri string URI to assign
*/
function _setTokenURI(uint256 _tokenId, string _uri) internal {
require(_exists(_tokenId));
tokenURIs[_tokenId] = _uri;
}
/**
* @dev Internal function to add a token ID to the list of a given address
* @param _to address representing the new owner of the given token ID
* @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
function addTokenTo(address _to, uint256 _tokenId) internal {
super.addTokenTo(_to, _tokenId);
uint256 length = ownedTokens[_to].length;
ownedTokens[_to].push(_tokenId);
ownedTokensIndex[_tokenId] = length;
}
/**
* @dev Internal function to remove a token ID from the list of a given address
* @param _from address representing the previous owner of the given token ID
* @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
function removeTokenFrom(address _from, uint256 _tokenId) internal {
super.removeTokenFrom(_from, _tokenId);
// To prevent a gap in the array, we store the last token in the index of the token to delete, and
// then delete the last slot.
uint256 tokenIndex = ownedTokensIndex[_tokenId];
uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
uint256 lastToken = ownedTokens[_from][lastTokenIndex];
ownedTokens[_from][tokenIndex] = lastToken;
// This also deletes the contents at the last position of the array
ownedTokens[_from].length--;
// Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
// be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
// the lastToken to the first position, and then dropping the element placed in the last position of the list
ownedTokensIndex[_tokenId] = 0;
ownedTokensIndex[lastToken] = tokenIndex;
}
/**
* @dev Internal function to mint a new token
* Reverts if the given token ID already exists
* @param _to address the beneficiary that will own the minted token
* @param _tokenId uint256 ID of the token to be minted by the msg.sender
*/
function _mint(address _to, uint256 _tokenId) internal {
super._mint(_to, _tokenId);
allTokensIndex[_tokenId] = allTokens.length;
allTokens.push(_tokenId);
}
/**
* @dev Internal function to burn a specific token
* Reverts if the token does not exist
* @param _owner owner of the token to burn
* @param _tokenId uint256 ID of the token being burned by the msg.sender
*/
function _burn(address _owner, uint256 _tokenId) internal {
super._burn(_owner, _tokenId);
// Clear metadata (if any)
if (bytes(tokenURIs[_tokenId]).length != 0) {
delete tokenURIs[_tokenId];
}
// Reorg all tokens array
uint256 tokenIndex = allTokensIndex[_tokenId];
uint256 lastTokenIndex = allTokens.length.sub(1);
uint256 lastToken = allTokens[lastTokenIndex];
allTokens[tokenIndex] = lastToken;
allTokens[lastTokenIndex] = 0;
allTokens.length--;
allTokensIndex[_tokenId] = 0;
allTokensIndex[lastToken] = tokenIndex;
}
}

@ -1,6 +1,6 @@
pragma solidity ^0.4.24;
import "./ERC721.sol";
import "./IERC721.sol";
/**
@ -8,7 +8,7 @@ import "./ERC721.sol";
* @dev Only use this interface for compatibility with previously deployed contracts
* Use ERC721 for interacting with new contracts which are standard-compliant
*/
contract DeprecatedERC721 is ERC721 {
contract IDeprecatedERC721 is IERC721 {
function takeOwnership(uint256 _tokenId) public;
function transfer(address _to, uint256 _tokenId) public;
function tokensOf(address _owner) public view returns (uint256[]);

@ -0,0 +1,40 @@
pragma solidity ^0.4.24;
import "./IERC721Basic.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract IERC721Enumerable is IERC721Basic {
function totalSupply() public view returns (uint256);
function tokenOfOwnerByIndex(
address _owner,
uint256 _index
)
public
view
returns (uint256 _tokenId);
function tokenByIndex(uint256 _index) public view returns (uint256);
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract IERC721Metadata is IERC721Basic {
function name() external view returns (string _name);
function symbol() external view returns (string _symbol);
function tokenURI(uint256 _tokenId) public view returns (string);
}
/**
* @title ERC-721 Non-Fungible Token Standard, full implementation interface
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract IERC721 is IERC721Basic, IERC721Enumerable, IERC721Metadata {
}

@ -0,0 +1,80 @@
pragma solidity ^0.4.24;
import "../../introspection/IERC165.sol";
/**
* @title ERC721 Non-Fungible Token Standard basic interface
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract IERC721Basic is IERC165 {
bytes4 internal constant InterfaceId_ERC721 = 0x80ac58cd;
/*
* 0x80ac58cd ===
* bytes4(keccak256('balanceOf(address)')) ^
* bytes4(keccak256('ownerOf(uint256)')) ^
* bytes4(keccak256('approve(address,uint256)')) ^
* bytes4(keccak256('getApproved(uint256)')) ^
* bytes4(keccak256('setApprovalForAll(address,bool)')) ^
* bytes4(keccak256('isApprovedForAll(address,address)')) ^
* bytes4(keccak256('transferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
*/
bytes4 internal constant InterfaceId_ERC721Enumerable = 0x780e9d63;
/**
* 0x780e9d63 ===
* bytes4(keccak256('totalSupply()')) ^
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
* bytes4(keccak256('tokenByIndex(uint256)'))
*/
bytes4 internal constant InterfaceId_ERC721Metadata = 0x5b5e139f;
/**
* 0x5b5e139f ===
* bytes4(keccak256('name()')) ^
* bytes4(keccak256('symbol()')) ^
* bytes4(keccak256('tokenURI(uint256)'))
*/
event Transfer(
address indexed _from,
address indexed _to,
uint256 indexed _tokenId
);
event Approval(
address indexed _owner,
address indexed _approved,
uint256 indexed _tokenId
);
event ApprovalForAll(
address indexed _owner,
address indexed _operator,
bool _approved
);
function balanceOf(address _owner) public view returns (uint256 _balance);
function ownerOf(uint256 _tokenId) public view returns (address _owner);
function approve(address _to, uint256 _tokenId) public;
function getApproved(uint256 _tokenId)
public view returns (address _operator);
function setApprovalForAll(address _operator, bool _approved) public;
function isApprovedForAll(address _owner, address _operator)
public view returns (bool);
function transferFrom(address _from, address _to, uint256 _tokenId) public;
function safeTransferFrom(address _from, address _to, uint256 _tokenId)
public;
function safeTransferFrom(
address _from,
address _to,
uint256 _tokenId,
bytes _data
)
public;
}

@ -6,11 +6,11 @@ pragma solidity ^0.4.24;
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
contract ERC721Receiver {
contract IERC721Receiver {
/**
* @dev Magic value to be returned upon successful reception of an NFT
* Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`,
* which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
* which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
*/
bytes4 internal constant ERC721_RECEIVED = 0x150b7a02;

@ -11,7 +11,7 @@ const should = require('chai')
.should();
const FinalizableCrowdsale = artifacts.require('FinalizableCrowdsaleImpl');
const MintableToken = artifacts.require('MintableToken');
const ERC20Mintable = artifacts.require('ERC20Mintable');
contract('FinalizableCrowdsale', function ([_, owner, wallet, thirdparty]) {
const rate = new BigNumber(1000);
@ -26,7 +26,7 @@ contract('FinalizableCrowdsale', function ([_, owner, wallet, thirdparty]) {
this.closingTime = this.openingTime + duration.weeks(1);
this.afterClosingTime = this.closingTime + duration.seconds(1);
this.token = await MintableToken.new();
this.token = await ERC20Mintable.new();
this.crowdsale = await FinalizableCrowdsale.new(
this.openingTime, this.closingTime, rate, wallet, this.token.address, { from: owner }
);

@ -5,17 +5,17 @@ const { assertRevert } = require('../helpers/assertRevert');
const BigNumber = web3.BigNumber;
const MintedCrowdsale = artifacts.require('MintedCrowdsaleImpl');
const MintableToken = artifacts.require('MintableToken');
const ERC20Mintable = artifacts.require('ERC20Mintable');
const RBACMintableToken = artifacts.require('RBACMintableToken');
const StandardToken = artifacts.require('StandardToken');
const ERC20 = artifacts.require('ERC20');
contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) {
const rate = new BigNumber(1000);
const value = ether(5);
describe('using MintableToken', function () {
describe('using ERC20Mintable', function () {
beforeEach(async function () {
this.token = await MintableToken.new();
this.token = await ERC20Mintable.new();
this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address);
await this.token.transferOwnership(this.crowdsale.address);
});
@ -45,7 +45,7 @@ contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) {
describe('using non-mintable token', function () {
beforeEach(async function () {
this.token = await StandardToken.new();
this.token = await ERC20.new();
this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address);
});

@ -1,7 +1,7 @@
const { ethGetBalance } = require('../helpers/web3');
const TokenDestructible = artifacts.require('TokenDestructible');
const StandardTokenMock = artifacts.require('StandardTokenMock');
const ERC20Mock = artifacts.require('ERC20Mock');
const BigNumber = web3.BigNumber;
@ -28,7 +28,7 @@ contract('TokenDestructible', function ([_, owner]) {
});
it('should send tokens to owner after destruction', async function () {
const token = await StandardTokenMock.new(tokenDestructible.address, 100);
const token = await ERC20Mock.new(tokenDestructible.address, 100);
(await token.balanceOf(tokenDestructible.address)).should.be.bignumber.equal(100);
(await token.balanceOf(owner)).should.be.bignumber.equal(0);

@ -1,7 +1,7 @@
const { expectThrow } = require('../helpers/expectThrow');
const CanReclaimToken = artifacts.require('CanReclaimToken');
const StandardTokenMock = artifacts.require('StandardTokenMock');
const ERC20Mock = artifacts.require('ERC20Mock');
const BigNumber = web3.BigNumber;
@ -15,7 +15,7 @@ contract('CanReclaimToken', function ([_, owner, anyone]) {
beforeEach(async function () {
// Create contract and token
token = await StandardTokenMock.new(owner, 100, { from: owner });
token = await ERC20Mock.new(owner, 100, { from: owner });
canReclaimToken = await CanReclaimToken.new({ from: owner });
// Force token into contract

@ -1,12 +0,0 @@
const { shouldBehaveLikeBurnableToken } = require('./BurnableToken.behavior');
const BurnableTokenMock = artifacts.require('BurnableTokenMock');
contract('BurnableToken', function ([_, owner, ...otherAccounts]) {
const initialBalance = 1000;
beforeEach(async function () {
this.token = await BurnableTokenMock.new(owner, initialBalance, { from: owner });
});
shouldBehaveLikeBurnableToken(owner, initialBalance, otherAccounts);
});

@ -1,25 +0,0 @@
const { assertRevert } = require('../../helpers/assertRevert');
const { ether } = require('../../helpers/ether');
const { shouldBehaveLikeMintableToken } = require('./MintableToken.behavior');
const { shouldBehaveLikeCappedToken } = require('./CappedToken.behavior');
const CappedToken = artifacts.require('CappedToken');
contract('Capped', function ([_, owner, ...otherAccounts]) {
const cap = ether(1000);
it('requires a non-zero cap', async function () {
await assertRevert(
CappedToken.new(0, { from: owner })
);
});
context('once deployed', async function () {
beforeEach(async function () {
this.token = await CappedToken.new(cap, { from: owner });
});
shouldBehaveLikeCappedToken(owner, otherAccounts, cap);
shouldBehaveLikeMintableToken(owner, owner, otherAccounts);
});
});

@ -4,9 +4,9 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
const DetailedERC20Mock = artifacts.require('DetailedERC20Mock');
const ERC20DetailedMock = artifacts.require('ERC20DetailedMock');
contract('DetailedERC20', function () {
contract('ERC20Detailed', function () {
let detailedERC20 = null;
const _name = 'My Detailed ERC20';
@ -14,7 +14,7 @@ contract('DetailedERC20', function () {
const _decimals = 18;
beforeEach(async function () {
detailedERC20 = await DetailedERC20Mock.new(_name, _symbol, _decimals);
detailedERC20 = await ERC20DetailedMock.new(_name, _symbol, _decimals);
});
it('has a name', async function () {

@ -1,7 +1,7 @@
const { assertRevert } = require('../../helpers/assertRevert');
const expectEvent = require('../../helpers/expectEvent');
const StandardToken = artifacts.require('StandardTokenMock');
const ERC20 = artifacts.require('ERC20Mock');
const BigNumber = web3.BigNumber;
@ -9,11 +9,11 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
contract('StandardToken', function ([_, owner, recipient, anotherAccount]) {
contract('ERC20', function ([_, owner, recipient, anotherAccount]) {
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
beforeEach(async function () {
this.token = await StandardToken.new(owner, 100);
this.token = await ERC20.new(owner, 100);
});
describe('total supply', function () {

@ -8,7 +8,7 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
function shouldBehaveLikeBurnableToken (owner, initialBalance, [burner]) {
function shouldBehaveLikeERC20Burnable (owner, initialBalance, [burner]) {
describe('burn', function () {
describe('when the given amount is not greater than balance of the sender', function () {
context('for a zero amount', function () {
@ -113,5 +113,5 @@ function shouldBehaveLikeBurnableToken (owner, initialBalance, [burner]) {
}
module.exports = {
shouldBehaveLikeBurnableToken,
shouldBehaveLikeERC20Burnable,
};

@ -0,0 +1,12 @@
const { shouldBehaveLikeERC20Burnable } = require('./ERC20Burnable.behavior');
const ERC20BurnableMock = artifacts.require('ERC20BurnableMock');
contract('ERC20Burnable', function ([_, owner, ...otherAccounts]) {
const initialBalance = 1000;
beforeEach(async function () {
this.token = await ERC20BurnableMock.new(owner, initialBalance, { from: owner });
});
shouldBehaveLikeERC20Burnable(owner, initialBalance, otherAccounts);
});

@ -7,7 +7,7 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
function shouldBehaveLikeCappedToken (minter, [anyone], cap) {
function shouldBehaveLikeERC20Capped (minter, [anyone], cap) {
describe('capped token', function () {
const from = minter;
@ -33,5 +33,5 @@ function shouldBehaveLikeCappedToken (minter, [anyone], cap) {
}
module.exports = {
shouldBehaveLikeCappedToken,
shouldBehaveLikeERC20Capped,
};

@ -0,0 +1,25 @@
const { assertRevert } = require('../../helpers/assertRevert');
const { ether } = require('../../helpers/ether');
const { shouldBehaveLikeERC20Mintable } = require('./ERC20Mintable.behavior');
const { shouldBehaveLikeERC20Capped } = require('./ERC20Capped.behavior');
const ERC20Capped = artifacts.require('ERC20Capped');
contract('ERC20Capped', function ([_, owner, ...otherAccounts]) {
const cap = ether(1000);
it('requires a non-zero cap', async function () {
await assertRevert(
ERC20Capped.new(0, { from: owner })
);
});
context('once deployed', async function () {
beforeEach(async function () {
this.token = await ERC20Capped.new(cap, { from: owner });
});
shouldBehaveLikeERC20Capped(owner, otherAccounts, cap);
shouldBehaveLikeERC20Mintable(owner, owner, otherAccounts);
});
});

@ -7,7 +7,7 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
function shouldBehaveLikeMintableToken (owner, minter, [anyone]) {
function shouldBehaveLikeERC20Mintable (owner, minter, [anyone]) {
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
describe('as a basic mintable token', function () {
@ -160,5 +160,5 @@ function shouldBehaveLikeMintableToken (owner, minter, [anyone]) {
}
module.exports = {
shouldBehaveLikeMintableToken,
shouldBehaveLikeERC20Mintable,
};

@ -0,0 +1,10 @@
const { shouldBehaveLikeERC20Mintable } = require('./ERC20Mintable.behavior');
const ERC20Mintable = artifacts.require('ERC20Mintable');
contract('ERC20Mintable', function ([_, owner, ...otherAccounts]) {
beforeEach(async function () {
this.token = await ERC20Mintable.new({ from: owner });
});
shouldBehaveLikeERC20Mintable(owner, owner, otherAccounts);
});

@ -1,9 +1,9 @@
const { assertRevert } = require('../../helpers/assertRevert');
const PausableToken = artifacts.require('PausableTokenMock');
const ERC20Pausable = artifacts.require('ERC20PausableMock');
contract('PausableToken', function ([_, owner, recipient, anotherAccount]) {
contract('ERC20Pausable', function ([_, owner, recipient, anotherAccount]) {
beforeEach(async function () {
this.token = await PausableToken.new(owner, 100, { from: owner });
this.token = await ERC20Pausable.new(owner, 100, { from: owner });
});
describe('pause', function () {

@ -1,10 +0,0 @@
const { shouldBehaveLikeMintableToken } = require('./MintableToken.behavior');
const MintableToken = artifacts.require('MintableToken');
contract('MintableToken', function ([_, owner, ...otherAccounts]) {
beforeEach(async function () {
this.token = await MintableToken.new({ from: owner });
});
shouldBehaveLikeMintableToken(owner, owner, otherAccounts);
});

@ -1,7 +1,7 @@
const { ether } = require('../../helpers/ether');
const { shouldBehaveLikeRBACMintableToken } = require('./RBACMintableToken.behavior');
const { shouldBehaveLikeMintableToken } = require('./MintableToken.behavior');
const { shouldBehaveLikeCappedToken } = require('./CappedToken.behavior');
const { shouldBehaveLikeERC20Mintable } = require('./ERC20Mintable.behavior');
const { shouldBehaveLikeERC20Capped } = require('./ERC20Capped.behavior');
const RBACCappedTokenMock = artifacts.require('RBACCappedTokenMock');
@ -13,7 +13,7 @@ contract('RBACCappedToken', function ([_, owner, minter, ...otherAccounts]) {
await this.token.addMinter(minter, { from: owner });
});
shouldBehaveLikeMintableToken(owner, minter, otherAccounts);
shouldBehaveLikeERC20Mintable(owner, minter, otherAccounts);
shouldBehaveLikeRBACMintableToken(owner, otherAccounts);
shouldBehaveLikeCappedToken(minter, otherAccounts, cap);
shouldBehaveLikeERC20Capped(minter, otherAccounts, cap);
});

@ -1,5 +1,5 @@
const { shouldBehaveLikeRBACMintableToken } = require('./RBACMintableToken.behavior');
const { shouldBehaveLikeMintableToken } = require('./MintableToken.behavior');
const { shouldBehaveLikeERC20Mintable } = require('./ERC20Mintable.behavior');
const RBACMintableToken = artifacts.require('RBACMintableToken');
@ -10,5 +10,5 @@ contract('RBACMintableToken', function ([_, owner, minter, ...otherAccounts]) {
});
shouldBehaveLikeRBACMintableToken(owner, otherAccounts);
shouldBehaveLikeMintableToken(owner, minter, otherAccounts);
shouldBehaveLikeERC20Mintable(owner, minter, otherAccounts);
});

@ -8,7 +8,7 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
const MintableToken = artifacts.require('MintableToken');
const ERC20Mintable = artifacts.require('ERC20Mintable');
const TokenTimelock = artifacts.require('TokenTimelock');
contract('TokenTimelock', function ([_, owner, beneficiary]) {
@ -16,7 +16,7 @@ contract('TokenTimelock', function ([_, owner, beneficiary]) {
context('with token', function () {
beforeEach(async function () {
this.token = await MintableToken.new({ from: owner });
this.token = await ERC20Mintable.new({ from: owner });
});
it('rejects a release time in the past', async function () {

@ -10,7 +10,7 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
const MintableToken = artifacts.require('MintableToken');
const ERC20Mintable = artifacts.require('ERC20Mintable');
const TokenVesting = artifacts.require('TokenVesting');
contract('TokenVesting', function ([_, owner, beneficiary]) {
@ -44,7 +44,7 @@ contract('TokenVesting', function ([_, owner, beneficiary]) {
beforeEach(async function () {
this.vesting = await TokenVesting.new(beneficiary, this.start, this.cliff, this.duration, true, { from: owner });
this.token = await MintableToken.new({ from: owner });
this.token = await ERC20Mintable.new({ from: owner });
await this.token.mint(this.vesting.address, amount, { from: owner });
});

@ -1,17 +1,17 @@
const { assertRevert } = require('../../helpers/assertRevert');
const { shouldBehaveLikeERC721BasicToken } = require('./ERC721BasicToken.behavior');
const { shouldBehaveLikeMintAndBurnERC721Token } = require('./ERC721MintBurn.behavior');
const { shouldBehaveLikeERC721Basic } = require('./ERC721Basic.behavior');
const { shouldBehaveLikeMintAndBurnERC721 } = require('./ERC721MintBurn.behavior');
const { shouldSupportInterfaces } = require('../../introspection/SupportsInterface.behavior');
const _ = require('lodash');
const BigNumber = web3.BigNumber;
const ERC721Token = artifacts.require('ERC721TokenMock.sol');
const ERC721 = artifacts.require('ERC721Mock.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
contract('ERC721Token', function (accounts) {
contract('ERC721', function (accounts) {
const name = 'Non Fungible Token';
const symbol = 'NFT';
const firstTokenId = 100;
@ -21,11 +21,11 @@ contract('ERC721Token', function (accounts) {
const anyone = accounts[9];
beforeEach(async function () {
this.token = await ERC721Token.new(name, symbol, { from: creator });
this.token = await ERC721.new(name, symbol, { from: creator });
});
shouldBehaveLikeERC721BasicToken(accounts);
shouldBehaveLikeMintAndBurnERC721Token(accounts);
shouldBehaveLikeERC721Basic(accounts);
shouldBehaveLikeMintAndBurnERC721(accounts);
describe('like a full ERC721', function () {
beforeEach(async function () {

@ -11,7 +11,7 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
function shouldBehaveLikeERC721BasicToken (accounts) {
function shouldBehaveLikeERC721Basic (accounts) {
const firstTokenId = 1;
const secondTokenId = 2;
const unknownTokenId = 3;
@ -19,7 +19,7 @@ function shouldBehaveLikeERC721BasicToken (accounts) {
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
const RECEIVER_MAGIC_VALUE = '0x150b7a02';
describe('like an ERC721BasicToken', function () {
describe('like an ERC721Basic', function () {
beforeEach(async function () {
await this.token.mint(creator, firstTokenId, { from: creator });
await this.token.mint(creator, secondTokenId, { from: creator });
@ -521,5 +521,5 @@ function shouldBehaveLikeERC721BasicToken (accounts) {
}
module.exports = {
shouldBehaveLikeERC721BasicToken,
shouldBehaveLikeERC721Basic,
};

@ -0,0 +1,18 @@
const { shouldBehaveLikeERC721Basic } = require('./ERC721Basic.behavior');
const { shouldBehaveLikeMintAndBurnERC721 } = require('./ERC721MintBurn.behavior');
const BigNumber = web3.BigNumber;
const ERC721Basic = artifacts.require('ERC721BasicMock.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
contract('ERC721Basic', function (accounts) {
beforeEach(async function () {
this.token = await ERC721Basic.new({ from: accounts[0] });
});
shouldBehaveLikeERC721Basic(accounts);
shouldBehaveLikeMintAndBurnERC721(accounts);
});

@ -1,18 +0,0 @@
const { shouldBehaveLikeERC721BasicToken } = require('./ERC721BasicToken.behavior');
const { shouldBehaveLikeMintAndBurnERC721Token } = require('./ERC721MintBurn.behavior');
const BigNumber = web3.BigNumber;
const ERC721BasicToken = artifacts.require('ERC721BasicTokenMock.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
contract('ERC721BasicToken', function (accounts) {
beforeEach(async function () {
this.token = await ERC721BasicToken.new({ from: accounts[0] });
});
shouldBehaveLikeERC721BasicToken(accounts);
shouldBehaveLikeMintAndBurnERC721Token(accounts);
});

@ -5,14 +5,14 @@ require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
function shouldBehaveLikeMintAndBurnERC721Token (accounts) {
function shouldBehaveLikeMintAndBurnERC721 (accounts) {
const firstTokenId = 1;
const secondTokenId = 2;
const unknownTokenId = 3;
const creator = accounts[0];
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
describe('like a mintable and burnable ERC721Token', function () {
describe('like a mintable and burnable ERC721', function () {
beforeEach(async function () {
await this.token.mint(creator, firstTokenId, { from: creator });
await this.token.mint(creator, secondTokenId, { from: creator });
@ -106,5 +106,5 @@ function shouldBehaveLikeMintAndBurnERC721Token (accounts) {
}
module.exports = {
shouldBehaveLikeMintAndBurnERC721Token,
shouldBehaveLikeMintAndBurnERC721,
};

@ -1,16 +1,16 @@
const { shouldBehaveLikeERC721PausedToken } = require('./ERC721PausedToken.behavior');
const { shouldBehaveLikeERC721BasicToken } = require('./ERC721BasicToken.behavior');
const { shouldBehaveLikeERC721Basic } = require('./ERC721Basic.behavior');
const BigNumber = web3.BigNumber;
const ERC721PausableToken = artifacts.require('ERC721PausableTokenMock.sol');
const ERC721Pausable = artifacts.require('ERC721PausableMock.sol');
require('chai')
.use(require('chai-bignumber')(BigNumber))
.should();
contract('ERC721PausableToken', function ([_, owner, recipient, operator, ...otherAccounts]) {
contract('ERC721Pausable', function ([_, owner, recipient, operator, ...otherAccounts]) {
beforeEach(async function () {
this.token = await ERC721PausableToken.new({ from: owner });
this.token = await ERC721Pausable.new({ from: owner });
});
context('when token is paused', function () {
@ -22,7 +22,7 @@ contract('ERC721PausableToken', function ([_, owner, recipient, operator, ...oth
});
context('when token is not paused yet', function () {
shouldBehaveLikeERC721BasicToken([owner, ...otherAccounts]);
shouldBehaveLikeERC721Basic([owner, ...otherAccounts]);
});
context('when token is paused and then unpaused', function () {
@ -31,6 +31,6 @@ contract('ERC721PausableToken', function ([_, owner, recipient, operator, ...oth
await this.token.unpause({ from: owner });
});
shouldBehaveLikeERC721BasicToken([owner, ...otherAccounts]);
shouldBehaveLikeERC721Basic([owner, ...otherAccounts]);
});
});

@ -13,7 +13,7 @@ function shouldBehaveLikeERC721PausedToken (owner, [recipient, operator]) {
const mockData = '0x42';
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
describe('like a paused ERC721Token', function () {
describe('like a paused ERC721', function () {
beforeEach(async function () {
await this.token.mint(owner, firstTokenId, { from: owner });
});

Loading…
Cancel
Save