-
Notifications
You must be signed in to change notification settings - Fork 113
/
TransferAndCallToken.sol
51 lines (46 loc) · 1.78 KB
/
TransferAndCallToken.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-version
pragma solidity >0.6.0 <0.9.0;
import "./ERC20Upgradeable.sol";
import "./ITransferAndCall.sol";
// Implementation from https://github.com/smartcontractkit/LinkToken/blob/master/contracts/v0.6/TransferAndCallToken.sol
/**
* @notice based on Implementation from https://github.com/smartcontractkit/LinkToken/blob/master/contracts/v0.6/ERC677Token.sol
* The implementation doesn't return a bool on onTokenTransfer. This is similar to the proposed 677 standard, but still incompatible - thus we don't refer to it as such.
*/
abstract contract TransferAndCallToken is ERC20Upgradeable, ITransferAndCall {
/**
* @dev transfer token to a contract address with additional data if the recipient is a contact.
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
* @param _data The extra data to be passed to the receiving contract.
*/
function transferAndCall(
address _to,
uint256 _value,
bytes memory _data
) public virtual override returns (bool success) {
super.transfer(_to, _value);
emit Transfer(msg.sender, _to, _value, _data);
if (isContract(_to)) {
contractFallback(_to, _value, _data);
}
return true;
}
// PRIVATE
function contractFallback(
address _to,
uint256 _value,
bytes memory _data
) private {
ITransferAndCallReceiver receiver = ITransferAndCallReceiver(_to);
receiver.onTokenTransfer(msg.sender, _value, _data);
}
function isContract(address _addr) private view returns (bool hasCode) {
uint256 length;
assembly {
length := extcodesize(_addr)
}
return length > 0;
}
}