Skip to content

Commit

Permalink
feat: check transfer or approval reverts instead of returning boolean
Browse files Browse the repository at this point in the history
  • Loading branch information
vittominacori committed Sep 21, 2023
1 parent dccb4b1 commit bb709e9
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 78 deletions.
6 changes: 3 additions & 3 deletions analysis/description-table/ERC1363.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

| File Name | SHA-1 Hash |
|-------------|--------------|
| flat/ERC1363.flat.sol | 9cbaa5967d433176696921607014870e19a253d0 |
| flat/ERC1363.flat.sol | ca8de52513b8ac954c3a7d0cd4a4aafb6bf4331e |


### Contracts Description Table
Expand Down Expand Up @@ -81,8 +81,8 @@
|| transferFromAndCall | Public ❗️ | 🛑 |NO❗️ |
|| approveAndCall | Public ❗️ | 🛑 |NO❗️ |
|| approveAndCall | Public ❗️ | 🛑 |NO❗️ |
|| _checkOnTransferReceived | Internal 🔒 | 🛑 | |
|| _checkOnApprovalReceived | Internal 🔒 | 🛑 | |
|| _checkOnTransferReceived | Private 🔐 | 🛑 | |
|| _checkOnApprovalReceived | Private 🔐 | 🛑 | |


### Legend
Expand Down
56 changes: 28 additions & 28 deletions analysis/uml/ERC1363.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
33 changes: 11 additions & 22 deletions contracts/token/ERC1363/ERC1363.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
*/
function transferAndCall(address to, uint256 amount, bytes memory data) public virtual override returns (bool) {
transfer(to, amount);
require(_checkOnTransferReceived(_msgSender(), to, amount, data), "ERC1363: receiver returned wrong data");
_checkOnTransferReceived(_msgSender(), to, amount, data);
return true;
}

Expand Down Expand Up @@ -71,7 +71,7 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
bytes memory data
) public virtual override returns (bool) {
transferFrom(from, to, amount);
require(_checkOnTransferReceived(from, to, amount, data), "ERC1363: receiver returned wrong data");
_checkOnTransferReceived(from, to, amount, data);
return true;
}

Expand All @@ -94,31 +94,25 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
*/
function approveAndCall(address spender, uint256 amount, bytes memory data) public virtual override returns (bool) {
approve(spender, amount);
require(_checkOnApprovalReceived(spender, amount, data), "ERC1363: spender returned wrong data");
_checkOnApprovalReceived(spender, amount, data);
return true;
}

/**
* @dev Internal function to invoke {IERC1363Receiver-onTransferReceived} on a target address.
* The call is not executed if the target address is not a contract.
* @dev Private function to invoke {IERC1363Receiver-onTransferReceived} on a target address.
* This will revert if the recipient doesn't accept the token transfer or if the target address is not a contract.
* @param sender address Representing the previous owner of the given token amount
* @param recipient address Target address that will receive the tokens
* @param amount uint256 The amount mount of tokens to be transferred
* @param data bytes Optional data to send along with the call
* @return whether the call correctly returned the expected magic value
*/
function _checkOnTransferReceived(
address sender,
address recipient,
uint256 amount,
bytes memory data
) internal virtual returns (bool) {
function _checkOnTransferReceived(address sender, address recipient, uint256 amount, bytes memory data) private {
if (recipient.code.length == 0) {
revert("ERC1363: transfer to non contract address");
}

try IERC1363Receiver(recipient).onTransferReceived(_msgSender(), sender, amount, data) returns (bytes4 retval) {
return retval == IERC1363Receiver.onTransferReceived.selector;
require(retval == IERC1363Receiver.onTransferReceived.selector, "ERC1363: receiver returned wrong data");
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC1363: transfer to non ERC1363Receiver implementer");
Expand All @@ -132,24 +126,19 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
}

/**
* @dev Internal function to invoke {IERC1363Receiver-onApprovalReceived} on a target address.
* The call is not executed if the target address is not a contract.
* @dev Private function to invoke {IERC1363Receiver-onApprovalReceived} on a target address.
* This will revert if the recipient doesn't accept the token approval or if the target address is not a contract.
* @param spender address The address which will spend the funds
* @param amount uint256 The amount of tokens to be spent
* @param data bytes Optional data to send along with the call
* @return whether the call correctly returned the expected magic value
*/
function _checkOnApprovalReceived(
address spender,
uint256 amount,
bytes memory data
) internal virtual returns (bool) {
function _checkOnApprovalReceived(address spender, uint256 amount, bytes memory data) private {
if (spender.code.length == 0) {
revert("ERC1363: approve a non contract address");
}

try IERC1363Spender(spender).onApprovalReceived(_msgSender(), amount, data) returns (bytes4 retval) {
return retval == IERC1363Spender.onApprovalReceived.selector;
require(retval == IERC1363Spender.onApprovalReceived.selector, "ERC1363: spender returned wrong data");
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC1363: approve a non ERC1363Spender implementer");
Expand Down
33 changes: 11 additions & 22 deletions flat/ERC1363.flat.sol
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
*/
function transferAndCall(address to, uint256 amount, bytes memory data) public virtual override returns (bool) {
transfer(to, amount);
require(_checkOnTransferReceived(_msgSender(), to, amount, data), "ERC1363: receiver returned wrong data");
_checkOnTransferReceived(_msgSender(), to, amount, data);
return true;
}

Expand Down Expand Up @@ -785,7 +785,7 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
bytes memory data
) public virtual override returns (bool) {
transferFrom(from, to, amount);
require(_checkOnTransferReceived(from, to, amount, data), "ERC1363: receiver returned wrong data");
_checkOnTransferReceived(from, to, amount, data);
return true;
}

Expand All @@ -808,31 +808,25 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
*/
function approveAndCall(address spender, uint256 amount, bytes memory data) public virtual override returns (bool) {
approve(spender, amount);
require(_checkOnApprovalReceived(spender, amount, data), "ERC1363: spender returned wrong data");
_checkOnApprovalReceived(spender, amount, data);
return true;
}

/**
* @dev Internal function to invoke {IERC1363Receiver-onTransferReceived} on a target address.
* The call is not executed if the target address is not a contract.
* @dev Private function to invoke {IERC1363Receiver-onTransferReceived} on a target address.
* This will revert if the recipient doesn't accept the token transfer or if the target address is not a contract.
* @param sender address Representing the previous owner of the given token amount
* @param recipient address Target address that will receive the tokens
* @param amount uint256 The amount mount of tokens to be transferred
* @param data bytes Optional data to send along with the call
* @return whether the call correctly returned the expected magic value
*/
function _checkOnTransferReceived(
address sender,
address recipient,
uint256 amount,
bytes memory data
) internal virtual returns (bool) {
function _checkOnTransferReceived(address sender, address recipient, uint256 amount, bytes memory data) private {
if (recipient.code.length == 0) {
revert("ERC1363: transfer to non contract address");
}

try IERC1363Receiver(recipient).onTransferReceived(_msgSender(), sender, amount, data) returns (bytes4 retval) {
return retval == IERC1363Receiver.onTransferReceived.selector;
require(retval == IERC1363Receiver.onTransferReceived.selector, "ERC1363: receiver returned wrong data");
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC1363: transfer to non ERC1363Receiver implementer");
Expand All @@ -846,24 +840,19 @@ abstract contract ERC1363 is ERC20, IERC1363, ERC165 {
}

/**
* @dev Internal function to invoke {IERC1363Receiver-onApprovalReceived} on a target address.
* The call is not executed if the target address is not a contract.
* @dev Private function to invoke {IERC1363Receiver-onApprovalReceived} on a target address.
* This will revert if the recipient doesn't accept the token approval or if the target address is not a contract.
* @param spender address The address which will spend the funds
* @param amount uint256 The amount of tokens to be spent
* @param data bytes Optional data to send along with the call
* @return whether the call correctly returned the expected magic value
*/
function _checkOnApprovalReceived(
address spender,
uint256 amount,
bytes memory data
) internal virtual returns (bool) {
function _checkOnApprovalReceived(address spender, uint256 amount, bytes memory data) private {
if (spender.code.length == 0) {
revert("ERC1363: approve a non contract address");
}

try IERC1363Spender(spender).onApprovalReceived(_msgSender(), amount, data) returns (bytes4 retval) {
return retval == IERC1363Spender.onApprovalReceived.selector;
require(retval == IERC1363Spender.onApprovalReceived.selector, "ERC1363: spender returned wrong data");
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC1363: approve a non ERC1363Spender implementer");
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "erc-payable-token",
"version": "4.9.6",
"version": "4.9.7",
"description": "ERC-1363 Payable Token Implementation",
"files": [
"contracts",
Expand Down

0 comments on commit bb709e9

Please sign in to comment.