Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ERC827 Token #518

Merged
merged 14 commits into from Jan 17, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 44 additions & 0 deletions contracts/token/ERC827.sol
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
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