Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add increase and decrease approval functions to ERC827 with tests
  • Loading branch information
AugustoL committed Jan 15, 2018
commit 685d2087caeb52e6d1f868b9bcce404cae3e315f
44 changes: 44 additions & 0 deletions contracts/token/ERC827.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be super.increaseApproval, not approve

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit worried that the tests did not catch this one. Maybe make sure that the increase approval test works on a spender that already has a certain approval set?


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;
}

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't believe how simple the code for this contract ended up. Congrats for the awesome work. 👏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to community and maintainers 🎉

58 changes: 57 additions & 1 deletion test/ERC827Token.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 () {
Expand Down