Browse Source

Consolidated ERC20 Interface and Implementation Files (#1125)

* Consolidted ERC20 Interface and Implementation Files

* Fixed CanReclaimToken's tests to use StandardTokenMock instead of BasicTokenMock

* Changed token's variable type in TokenTimelock to ERC20

* Merged the StandardBurnableToken with BurnableToken since it now inherits from StandardToken; Fixed TokenTimelock so it uses SafeERC20 for ERC20

* Fixed variable type for _token in TokenTimelock constructor

* Fixed linting warning in BurnableToken

* Added back burnFrom tests.
Doug Crescenzi 7 năm trước cách đây
mục cha
commit
ef347ffccc

+ 0 - 1
contracts/crowdsale/emission/AllowanceCrowdsale.sol

@@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
 
 import "../Crowdsale.sol";
 import "../../token/ERC20/ERC20.sol";
-import "../../token/ERC20/ERC20Basic.sol";
 import "../../token/ERC20/SafeERC20.sol";
 import "../../math/SafeMath.sol";
 

+ 3 - 3
contracts/lifecycle/TokenDestructible.sol

@@ -1,7 +1,7 @@
 pragma solidity ^0.4.24;
 
 import "../ownership/Ownable.sol";
-import "../token/ERC20/ERC20Basic.sol";
+import "../token/ERC20/ERC20.sol";
 
 
 /**
@@ -16,7 +16,7 @@ contract TokenDestructible is Ownable {
 
   /**
    * @notice Terminate contract and refund to owner
-   * @param _tokens List of addresses of ERC20 or ERC20Basic token contracts to
+   * @param _tokens List of addresses of ERC20 token contracts to
    refund.
    * @notice The called token contracts could try to re-enter this contract. Only
    supply token contracts you trust.
@@ -25,7 +25,7 @@ contract TokenDestructible is Ownable {
 
     // Transfer tokens to owner
     for (uint256 i = 0; i < _tokens.length; i++) {
-      ERC20Basic token = ERC20Basic(_tokens[i]);
+      ERC20 token = ERC20(_tokens[i]);
       uint256 balance = token.balanceOf(this);
       token.transfer(owner, balance);
     }

+ 0 - 15
contracts/mocks/BasicTokenMock.sol

@@ -1,15 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-import "../token/ERC20/BasicToken.sol";
-
-
-// mock class using BasicToken
-contract BasicTokenMock is BasicToken {
-
-  constructor(address _initialAccount, uint256 _initialBalance) public {
-    balances[_initialAccount] = _initialBalance;
-    totalSupply_ = _initialBalance;
-  }
-
-}

+ 2 - 2
contracts/mocks/ERC223TokenMock.sol

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

+ 0 - 13
contracts/mocks/StandardBurnableTokenMock.sol

@@ -1,13 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "../token/ERC20/StandardBurnableToken.sol";
-
-
-contract StandardBurnableTokenMock is StandardBurnableToken {
-
-  constructor(address _initialAccount, uint _initialBalance) public {
-    balances[_initialAccount] = _initialBalance;
-    totalSupply_ = _initialBalance;
-  }
-
-}

+ 5 - 5
contracts/ownership/CanReclaimToken.sol

@@ -1,7 +1,7 @@
 pragma solidity ^0.4.24;
 
 import "./Ownable.sol";
-import "../token/ERC20/ERC20Basic.sol";
+import "../token/ERC20/ERC20.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 ERC20Basic;
+  using SafeERC20 for ERC20;
 
   /**
-   * @dev Reclaim all ERC20Basic compatible tokens
-   * @param _token ERC20Basic The address of the token contract
+   * @dev Reclaim all ERC20 compatible tokens
+   * @param _token ERC20 The address of the token contract
    */
-  function reclaimToken(ERC20Basic _token) external onlyOwner {
+  function reclaimToken(ERC20 _token) external onlyOwner {
     uint256 balance = _token.balanceOf(this);
     _token.safeTransfer(owner, balance);
   }

+ 1 - 1
contracts/ownership/HasNoTokens.sol

@@ -7,7 +7,7 @@ import "./CanReclaimToken.sol";
  * @title Contracts that should not own Tokens
  * @author Remco Bloemen <remco@2π.com>
  * @dev This blocks incoming ERC223 tokens to prevent accidental loss of tokens.
- * Should tokens (any ERC20Basic compatible) end up in the contract, it allows the
+ * Should tokens (any ERC20 compatible) end up in the contract, it allows the
  * owner to reclaim the tokens.
  */
 contract HasNoTokens is CanReclaimToken {

+ 0 - 50
contracts/token/ERC20/BasicToken.sol

@@ -1,50 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-import "./ERC20Basic.sol";
-import "../../math/SafeMath.sol";
-
-
-/**
- * @title Basic token
- * @dev Basic version of StandardToken, with no allowances.
- */
-contract BasicToken is ERC20Basic {
-  using SafeMath for uint256;
-
-  mapping(address => uint256) internal balances;
-
-  uint256 internal totalSupply_;
-
-  /**
-  * @dev Total number of tokens in existence
-  */
-  function totalSupply() public view returns (uint256) {
-    return totalSupply_;
-  }
-
-  /**
-  * @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 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];
-  }
-
-}

+ 16 - 3
contracts/token/ERC20/BurnableToken.sol

@@ -1,13 +1,13 @@
 pragma solidity ^0.4.24;
 
-import "./BasicToken.sol";
+import "./StandardToken.sol";
 
 
 /**
  * @title Burnable Token
  * @dev Token that can be irreversibly burned (destroyed).
  */
-contract BurnableToken is BasicToken {
+contract BurnableToken is StandardToken {
 
   event Burn(address indexed burner, uint256 value);
 
@@ -19,6 +19,19 @@ contract BurnableToken is BasicToken {
     _burn(msg.sender, _value);
   }
 
+  /**
+   * @dev Burns a specific amount of tokens from the target address and decrements allowance
+   * @param _from address The address which you want to send tokens from
+   * @param _value uint256 The amount of token to be burned
+   */
+  function burnFrom(address _from, uint256 _value) public {
+    require(_value <= allowed[_from][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[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
+    _burn(_from, _value);
+  }
+
   function _burn(address _who, uint256 _value) internal {
     require(_value <= balances[_who]);
     // no need to require value <= totalSupply, since that would imply the
@@ -29,4 +42,4 @@ contract BurnableToken is BasicToken {
     emit Burn(_who, _value);
     emit Transfer(_who, address(0), _value);
   }
-}
+}

+ 16 - 4
contracts/token/ERC20/ERC20.sol

@@ -1,20 +1,32 @@
 pragma solidity ^0.4.24;
 
-import "./ERC20Basic.sol";
-
 
 /**
  * @title ERC20 interface
  * @dev see https://github.com/ethereum/EIPs/issues/20
  */
-contract ERC20 is ERC20Basic {
+contract ERC20 {
+  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);
 
-  function approve(address _spender, uint256 _value) public returns (bool);
+  event Transfer(
+    address indexed from,
+    address indexed to,
+    uint256 value
+  );
+
   event Approval(
     address indexed owner,
     address indexed spender,

+ 0 - 14
contracts/token/ERC20/ERC20Basic.sol

@@ -1,14 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-/**
- * @title ERC20Basic
- * @dev Simpler version of ERC20 interface
- * See https://github.com/ethereum/EIPs/issues/179
- */
-contract ERC20Basic {
-  function totalSupply() public view returns (uint256);
-  function balanceOf(address _who) public view returns (uint256);
-  function transfer(address _to, uint256 _value) public returns (bool);
-  event Transfer(address indexed from, address indexed to, uint256 value);
-}

+ 2 - 2
contracts/token/ERC20/SafeERC20.sol

@@ -1,6 +1,6 @@
 pragma solidity ^0.4.24;
 
-import "./ERC20Basic.sol";
+import "./StandardToken.sol";
 import "./ERC20.sol";
 
 
@@ -12,7 +12,7 @@ import "./ERC20.sol";
  */
 library SafeERC20 {
   function safeTransfer(
-    ERC20Basic _token,
+    ERC20 _token,
     address _to,
     uint256 _value
   )

+ 0 - 25
contracts/token/ERC20/StandardBurnableToken.sol

@@ -1,25 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./BurnableToken.sol";
-import "./StandardToken.sol";
-
-
-/**
- * @title Standard Burnable Token
- * @dev Adds burnFrom method to ERC20 implementations
- */
-contract StandardBurnableToken is BurnableToken, StandardToken {
-
-  /**
-   * @dev Burns a specific amount of tokens from the target address and decrements allowance
-   * @param _from address The address which you want to send tokens from
-   * @param _value uint256 The amount of token to be burned
-   */
-  function burnFrom(address _from, uint256 _value) public {
-    require(_value <= allowed[_from][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[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
-    _burn(_from, _value);
-  }
-}

+ 63 - 28
contracts/token/ERC20/StandardToken.sol

@@ -1,7 +1,7 @@
 pragma solidity ^0.4.24;
 
-import "./BasicToken.sol";
 import "./ERC20.sol";
+import "../../math/SafeMath.sol";
 
 
 /**
@@ -11,33 +11,60 @@ import "./ERC20.sol";
  * https://github.com/ethereum/EIPs/issues/20
  * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
  */
-contract StandardToken is ERC20, BasicToken {
+contract StandardToken is ERC20 {
+  using SafeMath for uint256;
+
+  mapping(address => uint256) balances;
 
   mapping (address => mapping (address => uint256)) internal allowed;
 
+  uint256 totalSupply_;
 
   /**
-   * @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
+  * @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 transferFrom(
-    address _from,
-    address _to,
-    uint256 _value
-  )
+  function allowance(
+    address _owner,
+    address _spender
+   )
     public
-    returns (bool)
+    view
+    returns (uint256)
   {
-    require(_value <= balances[_from]);
-    require(_value <= allowed[_from][msg.sender]);
+    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[_from] = balances[_from].sub(_value);
+    balances[msg.sender] = balances[msg.sender].sub(_value);
     balances[_to] = balances[_to].add(_value);
-    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
-    emit Transfer(_from, _to, _value);
+    emit Transfer(msg.sender, _to, _value);
     return true;
   }
 
@@ -57,20 +84,28 @@ contract StandardToken is ERC20, BasicToken {
   }
 
   /**
-   * @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.
+   * @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 allowance(
-    address _owner,
-    address _spender
-   )
+  function transferFrom(
+    address _from,
+    address _to,
+    uint256 _value
+  )
     public
-    view
-    returns (uint256)
+    returns (bool)
   {
-    return allowed[_owner][_spender];
+    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;
   }
 
   /**

+ 3 - 3
contracts/token/ERC20/TokenTimelock.sol

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

+ 6 - 7
contracts/token/ERC20/TokenVesting.sol

@@ -2,7 +2,6 @@
 
 pragma solidity ^0.4.24;
 
-import "./ERC20Basic.sol";
 import "./SafeERC20.sol";
 import "../../ownership/Ownable.sol";
 import "../../math/SafeMath.sol";
@@ -16,7 +15,7 @@ import "../../math/SafeMath.sol";
  */
 contract TokenVesting is Ownable {
   using SafeMath for uint256;
-  using SafeERC20 for ERC20Basic;
+  using SafeERC20 for ERC20;
 
   event Released(uint256 amount);
   event Revoked();
@@ -66,7 +65,7 @@ contract TokenVesting is Ownable {
    * @notice Transfers vested tokens to beneficiary.
    * @param _token ERC20 token which is being vested
    */
-  function release(ERC20Basic _token) public {
+  function release(ERC20 _token) public {
     uint256 unreleased = releasableAmount(_token);
 
     require(unreleased > 0);
@@ -83,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(ERC20Basic _token) public onlyOwner {
+  function revoke(ERC20 _token) public onlyOwner {
     require(revocable);
     require(!revoked[_token]);
 
@@ -103,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(ERC20Basic _token) public view returns (uint256) {
+  function releasableAmount(ERC20 _token) public view returns (uint256) {
     return vestedAmount(_token).sub(released[_token]);
   }
 
@@ -111,8 +110,8 @@ contract TokenVesting is Ownable {
    * @dev Calculates the amount that has already vested.
    * @param _token ERC20 token which is being vested
    */
-  function vestedAmount(ERC20Basic _token) public view returns (uint256) {
-    uint256 currentBalance = _token.balanceOf(address(this));
+  function vestedAmount(ERC20 _token) public view returns (uint256) {
+    uint256 currentBalance = _token.balanceOf(this);
     uint256 totalBalance = currentBalance.add(released[_token]);
 
     if (block.timestamp < cliff) {

+ 3 - 2
test/ownership/CanReclaimToken.test.js

@@ -1,7 +1,7 @@
 const { expectThrow } = require('../helpers/expectThrow');
 
 const CanReclaimToken = artifacts.require('CanReclaimToken');
-const BasicTokenMock = artifacts.require('BasicTokenMock');
+const StandardTokenMock = artifacts.require('StandardTokenMock');
 
 contract('CanReclaimToken', function ([_, owner, anyone]) {
   let token = null;
@@ -9,8 +9,9 @@ contract('CanReclaimToken', function ([_, owner, anyone]) {
 
   beforeEach(async function () {
     // Create contract and token
-    token = await BasicTokenMock.new(owner, 100, { from: owner });
+    token = await StandardTokenMock.new(owner, 100, { from: owner });
     canReclaimToken = await CanReclaimToken.new({ from: owner });
+
     // Force token into contract
     await token.transfer(canReclaimToken.address, 10, { from: owner });
     const startBalance = await token.balanceOf(canReclaimToken.address);

+ 0 - 82
test/token/ERC20/BasicToken.test.js

@@ -1,82 +0,0 @@
-const { assertRevert } = require('../../helpers/assertRevert');
-const BasicToken = artifacts.require('BasicTokenMock');
-
-contract('StandardToken', function ([_, owner, recipient, anotherAccount]) {
-  const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
-
-  beforeEach(async function () {
-    this.token = await BasicToken.new(owner, 100);
-  });
-
-  describe('total supply', function () {
-    it('returns the total amount of tokens', async function () {
-      const totalSupply = await this.token.totalSupply();
-
-      assert.equal(totalSupply, 100);
-    });
-  });
-
-  describe('balanceOf', function () {
-    describe('when the requested account has no tokens', function () {
-      it('returns zero', async function () {
-        const balance = await this.token.balanceOf(anotherAccount);
-
-        assert.equal(balance, 0);
-      });
-    });
-
-    describe('when the requested account has some tokens', function () {
-      it('returns the total amount of tokens', async function () {
-        const balance = await this.token.balanceOf(owner);
-
-        assert.equal(balance, 100);
-      });
-    });
-  });
-
-  describe('transfer', function () {
-    describe('when the recipient is not the zero address', function () {
-      const to = recipient;
-
-      describe('when the sender does not have enough balance', function () {
-        const amount = 101;
-
-        it('reverts', async function () {
-          await assertRevert(this.token.transfer(to, amount, { from: owner }));
-        });
-      });
-
-      describe('when the sender has enough balance', function () {
-        const amount = 100;
-
-        it('transfers the requested amount', async function () {
-          await this.token.transfer(to, amount, { from: owner });
-
-          const senderBalance = await this.token.balanceOf(owner);
-          assert.equal(senderBalance, 0);
-
-          const recipientBalance = await this.token.balanceOf(to);
-          assert.equal(recipientBalance, amount);
-        });
-
-        it('emits a transfer event', async function () {
-          const { logs } = await this.token.transfer(to, amount, { from: owner });
-
-          assert.equal(logs.length, 1);
-          assert.equal(logs[0].event, 'Transfer');
-          assert.equal(logs[0].args.from, owner);
-          assert.equal(logs[0].args.to, to);
-          assert(logs[0].args.value.eq(amount));
-        });
-      });
-    });
-
-    describe('when the recipient is the zero address', function () {
-      const to = ZERO_ADDRESS;
-
-      it('reverts', async function () {
-        await assertRevert(this.token.transfer(to, 100, { from: owner }));
-      });
-    });
-  });
-});

+ 53 - 2
test/token/ERC20/BurnableToken.behaviour.js

@@ -8,8 +8,8 @@ require('chai')
   .use(require('chai-bignumber')(BigNumber))
   .should();
 
-function shouldBehaveLikeBurnableToken (owner, initialBalance) {
-  describe('as a basic burnable token', function () {
+function shouldBehaveLikeBurnableToken (owner, initialBalance, [burner]) {
+  describe('burn', function () {
     describe('when the given amount is not greater than balance of the sender', function () {
       const amount = 100;
 
@@ -44,6 +44,57 @@ function shouldBehaveLikeBurnableToken (owner, initialBalance) {
       });
     });
   });
+
+  describe('burnFrom', function () {
+    describe('on success', function () {
+      const amount = 100;
+
+      beforeEach(async function () {
+        await this.token.approve(burner, 300, { from: owner });
+        const { logs } = await this.token.burnFrom(owner, amount, { from: burner });
+        this.logs = logs;
+      });
+
+      it('burns the requested amount', async function () {
+        const balance = await this.token.balanceOf(owner);
+        balance.should.be.bignumber.equal(initialBalance - amount);
+      });
+
+      it('decrements allowance', async function () {
+        const allowance = await this.token.allowance(owner, burner);
+        allowance.should.be.bignumber.equal(200);
+      });
+
+      it('emits a burn event', async function () {
+        const event = await inLogs(this.logs, 'Burn');
+        event.args.burner.should.eq(owner);
+        event.args.value.should.be.bignumber.equal(amount);
+      });
+
+      it('emits a transfer event', async function () {
+        const event = await inLogs(this.logs, 'Transfer');
+        event.args.from.should.eq(owner);
+        event.args.to.should.eq(ZERO_ADDRESS);
+        event.args.value.should.be.bignumber.equal(amount);
+      });
+    });
+
+    describe('when the given amount is greater than the balance of the sender', function () {
+      const amount = initialBalance + 1;
+      it('reverts', async function () {
+        await this.token.approve(burner, amount, { from: owner });
+        await assertRevert(this.token.burnFrom(owner, amount, { from: burner }));
+      });
+    });
+
+    describe('when the given amount is greater than the allowance', function () {
+      const amount = 100;
+      it('reverts', async function () {
+        await this.token.approve(burner, amount - 1, { from: owner });
+        await assertRevert(this.token.burnFrom(owner, amount, { from: burner }));
+      });
+    });
+  });
 }
 
 module.exports = {

+ 2 - 2
test/token/ERC20/BurnableToken.test.js

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

+ 0 - 72
test/token/ERC20/StandardBurnableToken.test.js

@@ -1,72 +0,0 @@
-const { assertRevert } = require('../../helpers/assertRevert');
-const { inLogs } = require('../../helpers/expectEvent');
-const { shouldBehaveLikeBurnableToken } = require('./BurnableToken.behaviour');
-
-const StandardBurnableTokenMock = artifacts.require('StandardBurnableTokenMock');
-const BigNumber = web3.BigNumber;
-const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
-
-require('chai')
-  .use(require('chai-bignumber')(BigNumber))
-  .should();
-
-contract('StandardBurnableToken', function ([_, owner, burner]) {
-  const initialBalance = 1000;
-
-  beforeEach(async function () {
-    this.token = await StandardBurnableTokenMock.new(owner, initialBalance);
-  });
-
-  shouldBehaveLikeBurnableToken(owner, initialBalance);
-
-  describe('burnFrom', function () {
-    describe('on success', function () {
-      const amount = 100;
-
-      beforeEach(async function () {
-        await this.token.approve(burner, 300, { from: owner });
-        const { logs } = await this.token.burnFrom(owner, amount, { from: burner });
-        this.logs = logs;
-      });
-
-      it('burns the requested amount', async function () {
-        const balance = await this.token.balanceOf(owner);
-        balance.should.be.bignumber.equal(initialBalance - amount);
-      });
-
-      it('decrements allowance', async function () {
-        const allowance = await this.token.allowance(owner, burner);
-        allowance.should.be.bignumber.equal(200);
-      });
-
-      it('emits a burn event', async function () {
-        const event = await inLogs(this.logs, 'Burn');
-        event.args.burner.should.eq(owner);
-        event.args.value.should.be.bignumber.equal(amount);
-      });
-
-      it('emits a transfer event', async function () {
-        const event = await inLogs(this.logs, 'Transfer');
-        event.args.from.should.eq(owner);
-        event.args.to.should.eq(ZERO_ADDRESS);
-        event.args.value.should.be.bignumber.equal(amount);
-      });
-    });
-
-    describe('when the given amount is greater than the balance of the sender', function () {
-      const amount = initialBalance + 1;
-      it('reverts', async function () {
-        await this.token.approve(burner, amount, { from: owner });
-        await assertRevert(this.token.burnFrom(owner, amount, { from: burner }));
-      });
-    });
-
-    describe('when the given amount is greater than the allowance', function () {
-      const amount = 100;
-      it('reverts', async function () {
-        await this.token.approve(burner, amount - 1, { from: owner });
-        await assertRevert(this.token.burnFrom(owner, amount, { from: burner }));
-      });
-    });
-  });
-});

+ 2 - 2
test/token/ERC20/StandardToken.test.js

@@ -1,11 +1,11 @@
 const { assertRevert } = require('../../helpers/assertRevert');
-const StandardTokenMock = artifacts.require('StandardTokenMock');
+const StandardToken = artifacts.require('StandardTokenMock');
 
 contract('StandardToken', function ([_, owner, recipient, anotherAccount]) {
   const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
 
   beforeEach(async function () {
-    this.token = await StandardTokenMock.new(owner, 100);
+    this.token = await StandardToken.new(owner, 100);
   });
 
   describe('total supply', function () {