add feature on token transfer invoke contractFallback silently

This commit is contained in:
Roman Storm 2018-07-06 16:50:27 -07:00
parent aeb2e1dd7e
commit 3e7560d08e
No known key found for this signature in database
GPG Key ID: E3282F1F2CE28E55
4 changed files with 50 additions and 8 deletions

View File

@ -26,11 +26,24 @@ contract ERC677BridgeToken is
function transferAndCall(address _to, uint _value, bytes _data)
external validRecipient(_to) returns (bool)
{
require(transfer(_to, _value));
emit Transfer(msg.sender, _to, _value, _data);
require(_value <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
if (isContract(_to)) {
require(contractFallback(_to, _value, _data));
}
emit Transfer(msg.sender, _to, _value);
emit Transfer(msg.sender, _to, _value, _data);
return true;
}
function transfer(address _to, uint256 _value) public returns (bool)
{
require(super.transfer(_to, _value));
if (isContract(_to)) {
contractFallback(_to, _value, new bytes(0));
}
return true;
}
@ -38,8 +51,7 @@ contract ERC677BridgeToken is
private
returns(bool)
{
ERC677Receiver receiver = ERC677Receiver(_to);
return receiver.onTokenTransfer(msg.sender, _value, _data);
return _to.call(abi.encodeWithSignature("onTokenTransfer(address,uint256,bytes)", msg.sender, _value, _data));
}
function isContract(address _addr)

View File

@ -10,8 +10,8 @@
"flatten": "bash flatten.sh",
"watch-tests": "./node_modules/.bin/nodemon ./node_modules/.bin/truffle test --network test"
},
"author": "",
"license": "ISC",
"author": "POA network",
"license": "GPLv3",
"dependencies": {
"ganache-cli": "^6.1.0",
"openzeppelin-solidity": "^1.10.0",

View File

@ -115,4 +115,34 @@ contract('ERC677BridgeToken', async (accounts) => {
})
})
describe('#transfer', async () => {
it('if transfer called on contract, onTokenTransfer is also invoked', async () => {
const receiver = await ERC677ReceiverTest.new();
(await receiver.from()).should.be.equal('0x0000000000000000000000000000000000000000');
(await receiver.value()).should.be.bignumber.equal('0');
(await receiver.data()).should.be.equal('0x');
(await receiver.someVar()).should.be.bignumber.equal('0');
await token.mint(user, 1, {from: owner }).should.be.fulfilled;
const {logs} = await token.transfer(receiver.address, 1, {from: user}).should.be.fulfilled;
(await token.balanceOf(receiver.address)).should.be.bignumber.equal(1);
(await token.balanceOf(user)).should.be.bignumber.equal(0);
(await receiver.from()).should.be.equal(user);
(await receiver.value()).should.be.bignumber.equal(1);
(await receiver.data()).should.be.equal('0x');
logs[0].event.should.be.equal("Transfer")
})
it('if transfer called on contract, still works even if onTokenTransfer doesnot exist', async () => {
const someContract = await POA20.new("Some", "Token", 18);
await token.mint(user, 2, {from: owner }).should.be.fulfilled;
const tokenTransfer = await token.transfer(someContract.address, 1, {from: user}).should.be.fulfilled;
const tokenTransfer2 = await token.transfer(accounts[0], 1, {from: user}).should.be.fulfilled;
(await token.balanceOf(someContract.address)).should.be.bignumber.equal(1);
(await token.balanceOf(user)).should.be.bignumber.equal(0);
tokenTransfer.logs[0].event.should.be.equal("Transfer")
tokenTransfer2.logs[0].event.should.be.equal("Transfer")
})
})
})

View File

@ -9,11 +9,11 @@ contract ERC677ReceiverTest is ERC677Receiver {
bytes public data;
uint public someVar = 0;
function onTokenTransfer(address _from, uint _value, bytes _data) external returns(bool) {
function onTokenTransfer(address _from, uint256 _value, bytes _data) external returns(bool) {
from = _from;
value = _value;
data = _data;
require(address(this).call(_data));
address(this).call(_data);
return true;
}