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

Issue #1727: Improve revert reason when assuming interface compliance contracts. #1943

Closed
wants to merge 11 commits into from

Conversation

NoopurShinde
Copy link

  • Solved issue Improve revert reason when assuming interface compliance #1727: Improve revert reason when assuming interface compliance contracts.

  • Fixes

    • Added the below code in ERC721.sol

        bytes memory payload = abi.encodeWithSignature(
         "onERC721Received(address,address,uint256,bytes)",
         msg.sender,
         from,
         tokenId,
         _data
         );
         
         (bool success, bytes memory returndata) = to.call(payload);
      
         if (!success) {
             if(returndata.length > 0){
                 revert(string (returndata));
             }
             else
                 revert("ERC721: to address does not implement ERC721Received interface");
         } else {
                 return true;
                }
      
    • Added 2 dummy contracts in /contracts/mocks; one which does not implement ERC721Received and one which implements it but reverts as the contract rejects the transaction.

    • Updated the test cases in ERC721.behavior.js to test the code added in ERC721.sol

@frangio frangio requested a review from nventuro October 15, 2019 16:32
@NoopurShinde
Copy link
Author

Hi @nventuro @frangio

Any update on the PR?

Copy link
Contributor

@frangio frangio left a comment

Choose a reason for hiding this comment

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

Thank you @NoopurShinde! Sorry for the delay.

package.json Outdated
@@ -53,9 +53,9 @@
"eslint-config-standard": "^11.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-mocha-no-only": "^1.1.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-node": "^10.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please undo the changes in package.json? We prefer to have PRs that focus on separate issues.

return (retval == _ERC721_RECEIVED);
bytes memory payload = abi.encodeWithSignature(
"onERC721Received(address,address,uint256,bytes)",
msg.sender,
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use _msgSender() instead, for compatibility with Context. This is used for integration with the GSN.

Suggested change
msg.sender,
_msgSender(),

Comment on lines +334 to +335
bytes memory payload = abi.encodeWithSignature(
"onERC721Received(address,address,uint256,bytes)",
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use abi.encodeWithSelector with IERC721Receiver(to).onERC721Received.selector as the first argument. This ensures that we don't mess up the string constant.


contract ERC721ReceiverNotImplementedMock{
bytes4 private _retval;
bool private _reverts;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove these two variables since they're not used.

function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public returns (bytes4)
{
require(!_reverts, "ERC721ReceiverMock: Transaction rejected by receiver");
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
require(!_reverts, "ERC721ReceiverMock: Transaction rejected by receiver");
require(!_reverts, "ERC721ReceiverRevertsMock: Transaction rejected by receiver");

(bool success, bytes memory returndata) = to.call(payload);
if (!success) {
if (returndata.length > 0){
revert(string(returndata));
Copy link
Contributor

Choose a reason for hiding this comment

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

From reading the Solidity documentation, it seems that both revert and require abi-encode their arguments as if they were a call to an Error(string) function.

If I understand correctly, this means that we're "wrapping" the revert reason twice, since returndata is already encoded here. I think we have to drop to assembly and use the revert opcode directly to avoid this re-encoding and to bubble up the value as-is.

Let me know if this was clear @NoopurShinde.

Comment on lines +344 to +351
if (!success) {
if (returndata.length > 0){
revert(string(returndata));
}else
revert("ERC721: to address does not implement ERC721Received interface");
} else {return true;}
// bytes4 retval = IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data);
// return (retval == _ERC721_RECEIVED);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please tidy up the whitespace here to conform to our usual style and remove the commented out lines. 🙂

@frangio frangio removed the request for review from nventuro October 17, 2019 17:54
@stale
Copy link

stale bot commented Nov 2, 2019

Hi all!
This Pull Request has not had any recent activity, is it still relevant? If so, what is blocking it? Is there anything we can do to help move it forward?
Thanks!

@stale stale bot added the stale label Nov 2, 2019
@stale
Copy link

stale bot commented Nov 21, 2019

Hi all!
This Pull Request has not had any recent activity, is it still relevant? If so, what is blocking it? Is there anything we can do to help move it forward?
Thanks!

@stale stale bot added the stale label Nov 21, 2019
@stale
Copy link

stale bot commented Dec 6, 2019

Hi folks!
This Pull Request is being closed as there was no response to the previous prompt. However, please leave a comment whenever you're ready to resume, so it can be reopened.
Thanks again!

@stale stale bot closed this Dec 6, 2019
alant added a commit to alant/openzeppelin-solidity that referenced this pull request Dec 8, 2019
nventuro added a commit that referenced this pull request Jan 23, 2020
* adding mock contacts, test code

* adding changes to ERC721.sol per @frangio's comments on original PR #1943

* fix solhint warnings

* Update contracts/token/ERC721/ERC721.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* same revert wording per @frangio's review suggestion

* per @frangio's feedback, changing the inline assembly to accomplish: we want to ignore the first 4 bytes of content, so we should read the length and decrease it by 4, then take the memory location and add 4 to it, then store the new length at the new memory location, then that is the new byte array that we want.

* change revert msg assembly per PR comment by @frangio

* unify revert msg in test code

* fix some failed tests, wording change

* Update contracts/token/ERC721/ERC721.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* Update contracts/token/ERC721/ERC721.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* fix test case, revert without reason

* fix 'ERC721ReceiverRevertsMock: Transaction rejected by receiver'

* style change per review by @frangio

* fix revert reason forwarding

* remove duplicate contracts/mocks/ERC721ReceiverRevertsMock.sol per review https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2018\#issuecomment-574381034

* Add changelog entry

* Fix tests

* Make tests more clear

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com>
KaiRo-at pushed a commit to KaiRo-at/openzeppelin-contracts that referenced this pull request Mar 16, 2020
* adding mock contacts, test code

* adding changes to ERC721.sol per @frangio's comments on original PR OpenZeppelin#1943

* fix solhint warnings

* Update contracts/token/ERC721/ERC721.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* same revert wording per @frangio's review suggestion

* per @frangio's feedback, changing the inline assembly to accomplish: we want to ignore the first 4 bytes of content, so we should read the length and decrease it by 4, then take the memory location and add 4 to it, then store the new length at the new memory location, then that is the new byte array that we want.

* change revert msg assembly per PR comment by @frangio

* unify revert msg in test code

* fix some failed tests, wording change

* Update contracts/token/ERC721/ERC721.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* Update contracts/token/ERC721/ERC721.sol

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* fix test case, revert without reason

* fix 'ERC721ReceiverRevertsMock: Transaction rejected by receiver'

* style change per review by @frangio

* fix revert reason forwarding

* remove duplicate contracts/mocks/ERC721ReceiverRevertsMock.sol per review https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2018\#issuecomment-574381034

* Add changelog entry

* Fix tests

* Make tests more clear

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
Co-authored-by: Nicolás Venturo <nicolas.venturo@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants