-
Notifications
You must be signed in to change notification settings - Fork 89
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
Add _msgSender() trick #133
base: master
Are you sure you want to change the base?
Conversation
Fixes solidstate-network#132 Enables MetaTransaction facets and [Delegatable](https://github.com/delegatable/delegatable-sol/blob/main/contracts/diamond/README.md).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems useful. Same concept as GSN in the OZ contracts, correct? I didn't re-implement that feature because I've never used it myself.
Before merge, needs to be applied to a few more files: SafeOwnableInternal
, ERC20ExtendedInternal
, ERC20ImplicitApprovalInternal
, ERC4626BaseInternal
assembly { | ||
sender := and( | ||
mload(add(array, index)), | ||
0xffffffffffffffffffffffffffffffffffffffff | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you describe these steps in more detail?
* @notice Overrides the msgSender to enable delegation message signing. | ||
* @returns address - The account whose authority is being acted on. | ||
*/ | ||
function _msgSender() internal view virtual returns (address sender) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to define this in a library in utils/
, to improve re-usability and avoid code duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, I was thinking similarly.
Hi, thanks for the review!
That's right. They should be completely compatible. I'll verify as much and get back here. And there are a few implementations going around that should all be compatible, so we can probably choose the most readable one. I'll gather the options.
I stole this code from someone who understood it better, but it is almost identical to GSN's version (formatted differently). Their comments are this: function _getRelayedCallSender() private pure returns (address payable result) {
// We need to read 20 bytes (an address) located at array index msg.data.length - 20. In memory, the array
// is prefixed with a 32-byte length value, so we first add 32 to get the memory read index. However, doing
// so would leave the address in the upper 20 bytes of the 32-byte word, which is inconvenient and would
// require bit shifting. We therefore subtract 12 from the read index so the address lands on the lower 20
// bytes. This can always be done due to the 32-byte prefix.
// The final memory read index is msg.data.length - 20 + 32 - 12 = msg.data.length. Using inline assembly is the
// easiest/most-efficient way to perform this operation.
// These fields are not accessible from assembly
bytes memory array = msg.data;
uint256 index = msg.data.length;
// solhint-disable-next-line no-inline-assembly
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
result := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
return result;
} I'll add to the remaining files, while moving the implementation to a |
Ok, I've made a few changes:
If I were to block merge myself, I might suggest I add at least one test first to demonstrate reasonable usage of this method. |
This is similar to OZ's I have not tested it, but this could affect existing contracts using multicall function since it would change the sender. |
Oh that's interesting, does the multicall functinality rely on similarly appending to tx.data? |
I'm looking for cases where In the case of SS's Multicall, there won't be an issue since it uses delegatecall (msg.sender doesn't change to the contract address). But other versions of Multicall use |
Fixes #132 (If you'd want it!)
A more full description of the motivation is on that issue. Here is a quick pass achieving that proposal.
I did not change
msg.sender
instances in constructors, since the benefit would never apply in those scenarios.Enables MetaTransaction facets and Delegatable.