Browse Source

Remove ERC827 token. (#1045)

Implementing this token is unsafe as per comments here:
https://github.com/ethereum/EIPs/issues/827#issuecomment-397857455
Maciej Górski 7 years ago
parent
commit
6b37ba36a1

+ 0 - 15
contracts/mocks/ERC827TokenMock.sol

@@ -1,15 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-import "../token/ERC827/ERC827Token.sol";
-
-
-// mock class using ERC827 Token
-contract ERC827TokenMock is ERC827Token {
-
-  constructor(address initialAccount, uint256 initialBalance) public {
-    balances[initialAccount] = initialBalance;
-    totalSupply_ = initialBalance;
-  }
-
-}

+ 0 - 42
contracts/token/ERC827/ERC827.sol

@@ -1,42 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-import "../ERC20/ERC20.sol";
-
-
-/**
- * @title ERC827 interface, an extension of ERC20 token standard
- *
- * @dev Interface of a ERC827 token, following the ERC20 standard with extra
- * methods to transfer value and data and execute calls in transfers and
- * approvals.
- */
-contract ERC827 is ERC20 {
-  function approveAndCall(
-    address _spender,
-    uint256 _value,
-    bytes _data
-  )
-    public
-    payable
-    returns (bool);
-
-  function transferAndCall(
-    address _to,
-    uint256 _value,
-    bytes _data
-  )
-    public
-    payable
-    returns (bool);
-
-  function transferFromAndCall(
-    address _from,
-    address _to,
-    uint256 _value,
-    bytes _data
-  )
-    public
-    payable
-    returns (bool);
-}

+ 0 - 163
contracts/token/ERC827/ERC827Token.sol

@@ -1,163 +0,0 @@
-/* solium-disable security/no-low-level-calls */
-
-pragma solidity ^0.4.24;
-
-import "./ERC827.sol";
-import "../ERC20/StandardToken.sol";
-
-
-/**
- * @title ERC827, an extension of ERC20 token standard
- *
- * @dev Implementation the ERC827, following the ERC20 standard with extra
- * methods to transfer value and data and execute calls in transfers and
- * approvals. Uses OpenZeppelin StandardToken.
- */
-contract ERC827Token is ERC827, StandardToken {
-
-  /**
-   * @dev Addition to ERC20 token methods. It allows to
-   * approve the transfer of value and execute a call with the sent data.
-   * 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 that will spend the funds.
-   * @param _value The amount of tokens to be spent.
-   * @param _data ABI-encoded contract call to call `_spender` address.
-   * @return true if the call function was executed successfully
-   */
-  function approveAndCall(
-    address _spender,
-    uint256 _value,
-    bytes _data
-  )
-    public
-    payable
-    returns (bool)
-  {
-    require(_spender != address(this));
-
-    super.approve(_spender, _value);
-
-    // solium-disable-next-line security/no-call-value
-    require(_spender.call.value(msg.value)(_data));
-
-    return true;
-  }
-
-  /**
-   * @dev Addition to ERC20 token methods. Transfer tokens to a specified
-   * address and execute a call with the sent data on the same transaction
-   * @param _to address The address which you want to transfer to
-   * @param _value uint256 the amout of tokens to be transfered
-   * @param _data ABI-encoded contract call to call `_to` address.
-   * @return true if the call function was executed successfully
-   */
-  function transferAndCall(
-    address _to,
-    uint256 _value,
-    bytes _data
-  )
-    public
-    payable
-    returns (bool)
-  {
-    require(_to != address(this));
-
-    super.transfer(_to, _value);
-
-    // solium-disable-next-line security/no-call-value
-    require(_to.call.value(msg.value)(_data));
-    return true;
-  }
-
-  /**
-   * @dev Addition to ERC20 token methods. Transfer tokens from one address to
-   * another and make a contract call on the same transaction
-   * @param _from The address which you want to send tokens from
-   * @param _to The address which you want to transfer to
-   * @param _value The amout of tokens to be transferred
-   * @param _data ABI-encoded contract call to call `_to` address.
-   * @return true if the call function was executed successfully
-   */
-  function transferFromAndCall(
-    address _from,
-    address _to,
-    uint256 _value,
-    bytes _data
-  )
-    public payable returns (bool)
-  {
-    require(_to != address(this));
-
-    super.transferFrom(_from, _to, _value);
-
-    // solium-disable-next-line security/no-call-value
-    require(_to.call.value(msg.value)(_data));
-    return true;
-  }
-
-  /**
-   * @dev Addition to StandardToken methods. Increase the amount of tokens that
-   * an owner allowed to a spender and execute a call with the sent data.
-   * 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.
-   * @param _data ABI-encoded contract call to call `_spender` address.
-   */
-  function increaseApprovalAndCall(
-    address _spender,
-    uint _addedValue,
-    bytes _data
-  )
-    public
-    payable
-    returns (bool)
-  {
-    require(_spender != address(this));
-
-    super.increaseApproval(_spender, _addedValue);
-
-    // solium-disable-next-line security/no-call-value
-    require(_spender.call.value(msg.value)(_data));
-
-    return true;
-  }
-
-  /**
-   * @dev Addition to StandardToken methods. Decrease the amount of tokens that
-   * an owner allowed to a spender and execute a call with the sent data.
-   * 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.
-   * @param _data ABI-encoded contract call to call `_spender` address.
-   */
-  function decreaseApprovalAndCall(
-    address _spender,
-    uint _subtractedValue,
-    bytes _data
-  )
-    public
-    payable
-    returns (bool)
-  {
-    require(_spender != address(this));
-
-    super.decreaseApproval(_spender, _subtractedValue);
-
-    // solium-disable-next-line security/no-call-value
-    require(_spender.call.value(msg.value)(_data));
-
-    return true;
-  }
-
-}

+ 0 - 489
test/token/ERC827/ERC827Token.js

@@ -1,489 +0,0 @@
-
-import EVMRevert from '../../helpers/EVMRevert';
-var Message = artifacts.require('MessageHelper');
-var ERC827TokenMock = artifacts.require('ERC827TokenMock');
-
-var BigNumber = web3.BigNumber;
-require('chai')
-  .use(require('chai-as-promised'))
-  .use(require('chai-bignumber')(BigNumber))
-  .should();
-
-contract('ERC827 Token', function (accounts) {
-  let token;
-
-  beforeEach(async function () {
-    token = await ERC827TokenMock.new(accounts[0], 100);
-  });
-
-  it('should return the correct totalSupply after construction', async function () {
-    let totalSupply = await token.totalSupply();
-
-    assert.equal(totalSupply, 100);
-  });
-
-  it('should return the correct allowance amount after approval', async function () {
-    let token = await ERC827TokenMock.new(accounts[0], 100);
-    await token.approve(accounts[1], 100);
-    let allowance = await token.allowance(accounts[0], accounts[1]);
-
-    assert.equal(allowance, 100);
-  });
-
-  it('should return correct balances after transfer', async function () {
-    await token.transfer(accounts[1], 100);
-    let balance0 = await token.balanceOf(accounts[0]);
-    assert.equal(balance0, 0);
-
-    let balance1 = await token.balanceOf(accounts[1]);
-    assert.equal(balance1, 100);
-  });
-
-  it('should throw an error when trying to transfer more than balance', async function () {
-    await token.transfer(accounts[1], 101).should.be.rejectedWith(EVMRevert);
-  });
-
-  it('should return correct balances after transfering from another account', async function () {
-    await token.approve(accounts[1], 100);
-    await token.transferFrom(accounts[0], accounts[2], 100, { from: accounts[1] });
-
-    let balance0 = await token.balanceOf(accounts[0]);
-    assert.equal(balance0, 0);
-
-    let balance1 = await token.balanceOf(accounts[2]);
-    assert.equal(balance1, 100);
-
-    let balance2 = await token.balanceOf(accounts[1]);
-    assert.equal(balance2, 0);
-  });
-
-  it('should throw an error when trying to transfer more than allowed', async function () {
-    await token.approve(accounts[1], 99);
-    await token.transferFrom(
-      accounts[0], accounts[2], 100,
-      { from: accounts[1] }
-    ).should.be.rejectedWith(EVMRevert);
-  });
-
-  it('should throw an error when trying to transferFrom more than _from has', async function () {
-    let balance0 = await token.balanceOf(accounts[0]);
-    await token.approve(accounts[1], 99);
-    await token.transferFrom(
-      accounts[0], accounts[2], balance0 + 1,
-      { from: accounts[1] }
-    ).should.be.rejectedWith(EVMRevert);
-  });
-
-  describe('validating allowance updates to spender', function () {
-    let preApproved;
-
-    it('should start with zero', async function () {
-      preApproved = await token.allowance(accounts[0], accounts[1]);
-      assert.equal(preApproved, 0);
-    });
-
-    it('should increase by 50 then decrease by 10', async function () {
-      await token.increaseApproval(accounts[1], 50);
-      let postIncrease = await token.allowance(accounts[0], accounts[1]);
-      preApproved.plus(50).should.be.bignumber.equal(postIncrease);
-      await token.decreaseApproval(accounts[1], 10);
-      let postDecrease = await token.allowance(accounts[0], accounts[1]);
-      postIncrease.minus(10).should.be.bignumber.equal(postDecrease);
-    });
-  });
-
-  it('should increase by 50 then set to 0 when decreasing by more than 50', async function () {
-    await token.approve(accounts[1], 50);
-    await token.decreaseApproval(accounts[1], 60);
-    let postDecrease = await token.allowance(accounts[0], accounts[1]);
-    postDecrease.should.be.bignumber.equal(0);
-  });
-
-  it('should throw an error when trying to transfer to 0x0', async function () {
-    await token.transfer(0x0, 100).should.be.rejectedWith(EVMRevert);
-  });
-
-  it('should throw an error when trying to transferFrom to 0x0', async function () {
-    await token.approve(accounts[1], 100);
-    await token.transferFrom(accounts[0], 0x0, 100, { from: accounts[1] })
-      .should.be.rejectedWith(EVMRevert);
-  });
-
-  describe('Test ERC827 methods', function () {
-    it(
-      'should allow payment through transfer'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.buyMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        const transaction = await token.transferAndCall(
-          message.contract.address, 100, extraData, { from: accounts[0], value: 1000 }
-        );
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.balanceOf(message.contract.address)
-        );
-        new BigNumber(1000).should.be.bignumber.equal(
-          await web3.eth.getBalance(message.contract.address)
-        );
-      });
-
-    it(
-      'should allow payment through approve'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.buyMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        const transaction = await token.approveAndCall(
-          message.contract.address, 100, extraData, { from: accounts[0], value: 1000 }
-        );
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-        new BigNumber(1000).should.be.bignumber.equal(
-          await web3.eth.getBalance(message.contract.address)
-        );
-      });
-
-    it(
-      'should allow payment through increaseApproval'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.buyMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        await token.approve(message.contract.address, 10);
-        new BigNumber(10).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-
-        const transaction = await token.increaseApprovalAndCall(
-          message.contract.address, 50, extraData, { from: accounts[0], value: 1000 }
-        );
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(60).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-        new BigNumber(1000).should.be.bignumber.equal(
-          await web3.eth.getBalance(message.contract.address)
-        );
-      });
-
-    it(
-      'should allow payment through decreaseApproval'
-      , async function () {
-        const message = await Message.new();
-
-        await token.approve(message.contract.address, 100);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-
-        const extraData = message.contract.buyMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        const transaction = await token.decreaseApprovalAndCall(
-          message.contract.address, 60, extraData, { from: accounts[0], value: 1000 }
-        );
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(40).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-        new BigNumber(1000).should.be.bignumber.equal(
-          await web3.eth.getBalance(message.contract.address)
-        );
-      });
-
-    it(
-      'should allow payment through transferFrom'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.buyMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        await token.approve(accounts[1], 100, { from: accounts[0] });
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.allowance(accounts[0], accounts[1])
-        );
-
-        const transaction = await token.transferFromAndCall(
-          accounts[0], message.contract.address, 100, extraData, { from: accounts[1], value: 1000 }
-        );
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.balanceOf(message.contract.address)
-        );
-        new BigNumber(1000).should.be.bignumber.equal(
-          await web3.eth.getBalance(message.contract.address)
-        );
-      });
-
-    it('should revert funds of failure inside approve (with data)', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.showMessage.getData(
-        web3.toHex(123456), 666, 'Transfer Done'
-      );
-
-      await token.approveAndCall(
-        message.contract.address, 10, extraData, { from: accounts[0], value: 1000 }
-      ).should.be.rejectedWith(EVMRevert);
-
-      // approval should not have gone through so allowance is still 0
-      new BigNumber(0).should.be.bignumber
-        .equal(await token.allowance(accounts[1], message.contract.address));
-      new BigNumber(0).should.be.bignumber
-        .equal(await web3.eth.getBalance(message.contract.address));
-    });
-
-    it('should revert funds of failure inside transfer (with data)', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.showMessage.getData(
-        web3.toHex(123456), 666, 'Transfer Done'
-      );
-
-      await token.transferAndCall(
-        message.contract.address, 10, extraData, { from: accounts[0], value: 1000 }
-      ).should.be.rejectedWith(EVMRevert);
-
-      // transfer should not have gone through, so balance is still 0
-      new BigNumber(0).should.be.bignumber
-        .equal(await token.balanceOf(message.contract.address));
-      new BigNumber(0).should.be.bignumber
-        .equal(await web3.eth.getBalance(message.contract.address));
-    });
-
-    it('should revert funds of failure inside transferFrom (with data)', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.showMessage.getData(
-        web3.toHex(123456), 666, 'Transfer Done'
-      );
-
-      await token.approve(accounts[1], 10, { from: accounts[2] });
-
-      await token.transferFromAndCall(
-        accounts[2], message.contract.address, 10, extraData, { from: accounts[2], value: 1000 }
-      ).should.be.rejectedWith(EVMRevert);
-
-      // transferFrom should have failed so balance is still 0 but allowance is 10
-      new BigNumber(10).should.be.bignumber
-        .equal(await token.allowance(accounts[2], accounts[1]));
-      new BigNumber(0).should.be.bignumber
-        .equal(await token.balanceOf(message.contract.address));
-      new BigNumber(0).should.be.bignumber
-        .equal(await web3.eth.getBalance(message.contract.address));
-    });
-
-    it(
-      'should return correct balances after transfer (with data) and show the event on receiver contract'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.showMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        const transaction = await token.transferAndCall(message.contract.address, 100, extraData);
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.balanceOf(message.contract.address)
-        );
-      });
-
-    it(
-      'should return correct allowance after approve (with data) and show the event on receiver contract'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.showMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        const transaction = await token.approveAndCall(message.contract.address, 100, extraData);
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-      });
-
-    it(
-      'should return correct allowance after increaseApproval (with data) and show the event on receiver contract'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.showMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        await token.approve(message.contract.address, 10);
-        new BigNumber(10).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-
-        const transaction = await token.increaseApprovalAndCall(message.contract.address, 50, extraData);
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(60).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-      });
-
-    it(
-      'should return correct allowance after decreaseApproval (with data) and show the event on receiver contract'
-      , async function () {
-        const message = await Message.new();
-
-        await token.approve(message.contract.address, 100);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-
-        const extraData = message.contract.showMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        const transaction = await token.decreaseApprovalAndCall(message.contract.address, 60, extraData);
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(40).should.be.bignumber.equal(
-          await token.allowance(accounts[0], message.contract.address)
-        );
-      });
-
-    it(
-      'should return correct balances after transferFrom (with data) and show the event on receiver contract'
-      , async function () {
-        const message = await Message.new();
-
-        const extraData = message.contract.showMessage.getData(
-          web3.toHex(123456), 666, 'Transfer Done'
-        );
-
-        await token.approve(accounts[1], 100, { from: accounts[0] });
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.allowance(accounts[0], accounts[1])
-        );
-
-        const transaction = await token.transferFromAndCall(accounts[0], message.contract.address, 100, extraData, {
-          from: accounts[1],
-        });
-
-        assert.equal(2, transaction.receipt.logs.length);
-
-        new BigNumber(100).should.be.bignumber.equal(
-          await token.balanceOf(message.contract.address)
-        );
-      });
-
-    it('should fail inside approve (with data)', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.fail.getData();
-
-      await token.approveAndCall(message.contract.address, 10, extraData)
-        .should.be.rejectedWith(EVMRevert);
-
-      // approval should not have gone through so allowance is still 0
-      new BigNumber(0).should.be.bignumber
-        .equal(await token.allowance(accounts[1], message.contract.address));
-    });
-
-    it('should fail inside transfer (with data)', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.fail.getData();
-
-      await token.transferAndCall(message.contract.address, 10, extraData)
-        .should.be.rejectedWith(EVMRevert);
-
-      // transfer should not have gone through, so balance is still 0
-      new BigNumber(0).should.be.bignumber
-        .equal(await token.balanceOf(message.contract.address));
-    });
-
-    it('should fail inside transferFrom (with data)', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.fail.getData();
-
-      await token.approve(accounts[1], 10, { from: accounts[2] });
-      await token.transferFromAndCall(accounts[2], message.contract.address, 10, extraData, { from: accounts[1] })
-        .should.be.rejectedWith(EVMRevert);
-
-      // transferFrom should have failed so balance is still 0 but allowance is 10
-      new BigNumber(10).should.be.bignumber
-        .equal(await token.allowance(accounts[2], accounts[1]));
-      new BigNumber(0).should.be.bignumber
-        .equal(await token.balanceOf(message.contract.address));
-    });
-
-    it('should fail approve (with data) when using token contract address as receiver', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.showMessage.getData(
-        web3.toHex(123456), 666, 'Transfer Done'
-      );
-
-      await token.approveAndCall(token.contract.address, 100, extraData, { from: accounts[0] })
-        .should.be.rejectedWith(EVMRevert);
-    });
-
-    it('should fail transfer (with data) when using token contract address as receiver', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.showMessage.getData(
-        web3.toHex(123456), 666, 'Transfer Done'
-      );
-
-      await token.transferAndCall(token.contract.address, 100, extraData)
-        .should.be.rejectedWith(EVMRevert);
-    });
-
-    it('should fail transferFrom (with data) when using token contract address as receiver', async function () {
-      const message = await Message.new();
-
-      const extraData = message.contract.showMessage.getData(
-        web3.toHex(123456), 666, 'Transfer Done'
-      );
-
-      await token.approve(accounts[1], 1, { from: accounts[0] });
-
-      await token.transferFromAndCall(accounts[0], token.contract.address, 1, extraData, { from: accounts[1] })
-        .should.be.rejectedWith(EVMRevert);
-    });
-  });
-});