From 685d2087caeb52e6d1f868b9bcce404cae3e315f Mon Sep 17 00:00:00 2001 From: AugustoL Date: Mon, 15 Jan 2018 20:56:25 -0300 Subject: [PATCH] Add increase and decrease approval functions to ERC827 with tests --- contracts/token/ERC827.sol | 44 +++++++++++++++++++++++++++++ test/ERC827Token.js | 58 +++++++++++++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/contracts/token/ERC827.sol b/contracts/token/ERC827.sol index d07f65e83..472b82b07 100644 --- a/contracts/token/ERC827.sol +++ b/contracts/token/ERC827.sol @@ -78,4 +78,48 @@ contract ERC827 is StandardToken { 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 increaseApproval(address _spender, uint _addedValue, bytes _data) public returns (bool) { + require(_spender != address(this)); + + super.approve(_spender, _addedValue); + + require(_spender.call(_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 decreaseApproval(address _spender, uint _subtractedValue, bytes _data) public returns (bool) { + require(_spender != address(this)); + + super.decreaseApproval(_spender, _subtractedValue); + + require(_spender.call(_data)); + + return true; + } + } diff --git a/test/ERC827Token.js b/test/ERC827Token.js index 08902f449..7cb4ed26c 100644 --- a/test/ERC827Token.js +++ b/test/ERC827Token.js @@ -94,7 +94,13 @@ contract('ERC827 Token', function (accounts) { }); it('should increase by 50 then decrease by 10', async function () { - await token.increaseApproval(accounts[1], 50); + const abiMethod = findMethod(token.abi, 'increaseApproval', 'address,uint256'); + const increaseApprovalData = ethjsABI.encodeMethod(abiMethod, + [accounts[1], 50] + ); + await token.sendTransaction( + { from: accounts[0], data: increaseApprovalData } + ); let postIncrease = await token.allowance(accounts[0], accounts[1]); preApproved.plus(50).should.be.bignumber.equal(postIncrease); await token.decreaseApproval(accounts[1], 10); @@ -168,6 +174,56 @@ contract('ERC827 Token', function (accounts) { ); }); + 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' + ); + + const abiMethod = findMethod(token.abi, 'increaseApproval', 'address,uint256,bytes'); + const increaseApprovalData = ethjsABI.encodeMethod(abiMethod, + [message.contract.address, 50, extraData] + ); + const transaction = await token.sendTransaction( + { from: accounts[0], data: increaseApprovalData } + ); + + assert.equal(2, transaction.receipt.logs.length); + + new BigNumber(50).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); + + const extraData = message.contract.showMessage.getData( + web3.toHex(123456), 666, 'Transfer Done' + ); + + const abiMethod = findMethod(token.abi, 'decreaseApproval', 'address,uint256,bytes'); + const decreaseApprovalData = ethjsABI.encodeMethod(abiMethod, + [message.contract.address, 60, extraData] + ); + const transaction = await token.sendTransaction( + { from: accounts[0], data: decreaseApprovalData } + ); + + 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 () {