-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
EIP712
: _TYPE_HASH
including salt
#4318
Comments
Hello @pcaversaccio IMO most cases don't need the salt. In fact, the only use of salt I've seen in production is in some polygon contract that used chainId as the salt (and did not include chainId). I wouldn't want to force that onto any user, particularly without a good documentation explaining when/why use the salt. On the other hand, it would be better if our implementation could allow someone that want to include a salt to do so. |
I think OpenZeppelin is optimising for security, correctness and completeness (to a certain extend). Thus, I definitely believe OZ as the most common Solidity smart contract library should allow for such a customisation if someone would like to include the salt. |
We could have a version that does function _buildDomainSeparator() private view returns (bytes32) {
return _salt == bytes32(0)
? keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)))
: keccak256(abi.encode(_TYPE_HASH_WITH_SALT, _hashedName, _hashedVersion, block.chainid, address(this), _salt));
}
function eip712Domain()
public
view
virtual
override
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
)
{
return (
_salt == bytes32(0) ? hex"0f" : hex"1f", // 01111 or 11111
_name.toStringWithFallback(_nameFallback),
_version.toStringWithFallback(_versionFallback),
block.chainid,
address(this),
_salt,
new uint256[](0)
);
} If _salt is immutable, we would be breaking the constructor's argument. We could declare a function _salt() internal pure virtual returns (bytes32) { return bytes32(0); } or function _salt() internal pure virtual returns (bool enabled, bytes32 value) { return (false, bytes32(0)); } that users can overload. I'm wondering if @frangio, what do you think ? |
One more thing we need to discuss is: If we don't see any real need for a salt in the EIP712 domain, we probably shouldn't add unnecessary complexity to the code. |
absolutely - fwiw this is for instance what revoke.cash does (so apparently many use cases use the const salt = utils.hexZeroPad(utils.hexlify(chainId), 32);
// Given the potential fields of a domain, we try to find the one that matches the domain separator
const potentialDomains = [
// Expected domain separators
{ name, version, chainId, verifyingContract },
{ name, version, verifyingContract, salt },
{ name: symbol, version, chainId, verifyingContract },
{ name: symbol, version, verifyingContract, salt },
// Without version
{ name, chainId, verifyingContract },
{ name, verifyingContract, salt },
{ name: symbol, chainId, verifyingContract },
{ name: symbol, verifyingContract, salt },
// Without name
{ version, chainId, verifyingContract },
{ version, verifyingContract, salt },
// Without name or version
{ chainId, verifyingContract },
{ verifyingContract, salt },
// With both chainId and salt
{ name, version, chainId, verifyingContract, salt },
{ name: symbol, version, chainId, verifyingContract, salt },
];
const domain = potentialDomains.find((domain) => utils._TypedDataEncoder.hashDomain(domain) === domainSeparator); @rkalis sorry for tagging but you might have some input here about use cases you have seen with revoke.cash. |
I see no case when both chainId and salt are used ... and I would say that using the chainId as salt is bad design ! If that is the only real usecase, then I'd say we should stick with including the chainId for everyone and not including the salt. |
A recent example where the It's written in Vyper but I simply wanted to highlight that there are projects out there using |
I'm sure you can find example of projects using a salt ... but WHY are they doing that ? I don't want an example of project that do it. I want a good reason for projects doing it. I want a rational for our users to clearly decide if they need it of not. |
I believe the reason why people use Even if we add the salt in the way that @Amxx suggests, then people will want to remove Most of what our For supporting the more advanced use cases, we could have a set of utilities for implementing an alternative to our function toDomainSeparator(
function () view returns (bytes1, string memory, string memory, uint256, address, bytes32, uint256[] memory) eip712Domain
) internal returns (bytes32) {
...
} In this way a user that wants a different set of EIP-712 fields can just implement the EIP-5267 I would propose to consider this for 5.1, but it might make sense to look at one thing for 5.0: our
There is no reason why it should be constant in time AFAIK. |
@tayvano or @danfinlay could you confirm that MetaMask verifies the
I think that approach is indeed a good compromise and scales well. Another way would be by using a struct Domain {
bytes1 fields;
string name;
string version;
uint256 chainId;
address verifyingContract;
bytes32 salt;
uint256[] extensions;
}
function toDomainSeparator(Domain calldata domain) internal returns (bytes32) {
...
} |
Another good related argument towards adding the salt is that some hardware wallet providers may restrict signing with certain |
Good point - tbh that sounds crazy and would mean it's not anymore fully non-custodial. If this ever happens, I will fire fiercely against these providers; that would be unacceptable behaviour. |
Since
EIP-5267
got merged I wanted to raise a question. InEIP-712
's definition of thedomainSeparator
a so-calledsalt
is also listed:EIP-5267
also supports thesalt
parameters for retrieval via thefields
parameter. Now, my question: shouldn't we adjust theEIP712
to incorporate thissalt
parameter?I.e.:
and
The above are illustrations and not final code suggestions.
The text was updated successfully, but these errors were encountered: