diff --git a/contracts/token/StandardToken.sol b/contracts/token/StandardToken.sol index 42a5d561d..358d6f05e 100644 --- a/contracts/token/StandardToken.sol +++ b/contracts/token/StandardToken.sol @@ -63,5 +63,30 @@ contract StandardToken is ERC20, BasicToken { function allowance(address _owner, address _spender) constant returns (uint256 remaining) { return allowed[_owner][_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 + */ + function increaseApproval (address _spender, uint _addedValue) + returns (bool success) { + allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue); + Approval(msg.sender, _spender, allowed[msg.sender][_spender]); + return true; + } + + function decreaseApproval (address _spender, uint _subtractedValue) + returns (bool success) { + uint oldValue = allowed[msg.sender][_spender]; + if (_subtractedValue > oldValue) { + allowed[msg.sender][_spender] = 0; + } else { + allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); + } + Approval(msg.sender, _spender, allowed[msg.sender][_spender]); + return true; + } } diff --git a/test/StandardToken.js b/test/StandardToken.js index 3a96be81b..96a51afe5 100644 --- a/test/StandardToken.js +++ b/test/StandardToken.js @@ -70,4 +70,22 @@ contract('StandardToken', function(accounts) { } }); + 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); + }) + }); + });