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

Remove superfluous receive() function from Proxy.sol #4434

Merged
merged 2 commits into from Jul 8, 2023

Conversation

Amxx
Copy link
Collaborator

@Amxx Amxx commented Jul 7, 2023

Following this discussion in the forum

In the past, when declaring a fallback(), solidity would trigger a warning if no receive() is implemented. That is apparently no longer the case.

In the case of Proxy, the receive function is not necessary. Any call, with or without data, with or without value, will be catched by fallback() fallback.

PR Checklist

  • Tests (nothing changes)
  • Changeset entry (run npx changeset add)

@Amxx Amxx added this to the 5.0 milestone Jul 7, 2023
@Amxx Amxx requested review from frangio and ernestognw July 7, 2023 09:44
@changeset-bot
Copy link

changeset-bot bot commented Jul 7, 2023

🦋 Changeset detected

Latest commit: 1715027

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

ernestognw
ernestognw previously approved these changes Jul 7, 2023
Copy link
Member

@ernestognw ernestognw left a comment

Choose a reason for hiding this comment

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

I'm approving but, can we try a bit more to reproduce the supposed warning with no receive function? I'm afraid this won't trigger for us but maybe will do for others importing the library. If we can make sure the warning was removed after a certain Solidity version would be better.

@Amxx
Copy link
Collaborator Author

Amxx commented Jul 7, 2023

Note: tests show that is saved 1500~1900 gas per proxy deployment (ERC1967Proxy, TransparentUpgradeableProxy & BeaconProxy)

@frangio
Copy link
Contributor

frangio commented Jul 8, 2023

The warning wasn't removed. It's just really hard to reproduce. I couldn't figure out the conditions until I found the warning in the Solidity repo12. The warning comes up when there is a payable fallback function along with other functions, but no receive function.

contract C {
    fallback() external payable { }
    function f() public pure { }
}
contract A {
    function f() external pure {}
}
contract C is A {
    fallback() external payable { }
}

The warning in both cases is:

This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.

This probably used to happen in the transparent proxy because we had a fallback and additional functions (upgradeTo, etc.), but this is no longer the case and should never be the case for us or users, for the reasons we do the manual dispatch and recommend the same.

Footnotes

  1. https://github.com/ethereum/solidity/blob/v0.8.20/test/libsolidity/syntaxTests/fallback/payable_fallback_without_receive_nonempty.sol

  2. https://github.com/ethereum/solidity/blob/v0.8.20/test/libsolidity/syntaxTests/fallback/payable_fallback_without_receive_nonempty_by_inheritance.sol

@frangio frangio requested a review from ernestognw July 8, 2023 00:57
Copy link
Member

@ernestognw ernestognw left a comment

Choose a reason for hiding this comment

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

Ulalá, references.

Thanks @frangio!

@frangio frangio merged commit 6d74b91 into OpenZeppelin:master Jul 8, 2023
14 checks passed
sambacha added a commit to manifoldfinance/mev-proxy that referenced this pull request Jul 18, 2023
https://forum.openzeppelin.com/t/proxy-sol-fallback/36951/8


The fallback alone would indeed be enough.

 Fallback is not limited to` msg.value == 0` (if its marked `payable`). Both functions can support value.

The difference between receive and fallback is in the msg.data. If the calldata is empty and if there is a receive function, it fill be used. Otherwise, fallback is used. This means that regardless of the value, fallback will be called if there is some data. `fallback` is also the one that is called if there is no data, but receive is not defined.

So why do we have a receive function that is not really needed? To silent solidity warnings that sometimes happen when you have a fallback function but no receive function.
- @Amxx 

see <OpenZeppelin/openzeppelin-contracts#4434 (comment)>
@Amxx Amxx deleted the simplification/proxy-receive branch August 29, 2023 11:41
sambacha added a commit to manifoldfinance/mev-proxy that referenced this pull request Sep 27, 2023
https://forum.openzeppelin.com/t/proxy-sol-fallback/36951/8


The fallback alone would indeed be enough.

 Fallback is not limited to` msg.value == 0` (if its marked `payable`). Both functions can support value.

The difference between receive and fallback is in the msg.data. If the calldata is empty and if there is a receive function, it fill be used. Otherwise, fallback is used. This means that regardless of the value, fallback will be called if there is some data. `fallback` is also the one that is called if there is no data, but receive is not defined.

So why do we have a receive function that is not really needed? To silent solidity warnings that sometimes happen when you have a fallback function but no receive function.
- @Amxx 

see <OpenZeppelin/openzeppelin-contracts#4434 (comment)>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants