-
Notifications
You must be signed in to change notification settings - Fork 12.1k
Update FV specs and script #5786
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
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
} else if ( | ||
selector == to_bytes4(sig:labelRole(uint64,string).selector) || | ||
selector == to_bytes4(sig:setRoleAdmin(uint64,uint64).selector) || | ||
selector == to_bytes4(sig:setRoleGuardian(uint64,uint64).selector) || | ||
selector == to_bytes4(sig:setGrantDelay(uint64,uint32).selector) || | ||
selector == to_bytes4(sig:setTargetAdminDelay(address,uint32).selector) | ||
) { | ||
assert restricted == true; | ||
assert roleId == ADMIN_ROLE(); | ||
assert delay == 0; | ||
} else if ( | ||
selector == to_bytes4(sig:updateAuthority(address,address).selector) || | ||
selector == to_bytes4(sig:setTargetClosed(address,bool).selector) || | ||
selector == to_bytes4(sig:setTargetFunctionRole(address,bytes4[],uint64).selector) | ||
) { | ||
assert restricted == true; | ||
assert roleId == ADMIN_ROLE(); | ||
assert delay == getTargetAdminDelay(e, getFirstArgumentAsAddress(data)); | ||
} else if ( | ||
selector == to_bytes4(sig:grantRole(uint64,address,uint32).selector) || | ||
selector == to_bytes4(sig:revokeRole(uint64,address).selector) | ||
) { | ||
assert restricted == true; | ||
assert roleId == getRoleAdmin(getFirstArgumentAsUint64(data)); | ||
assert delay == 0; | ||
} else { | ||
assert restricted == | ||
isOnlyAuthorized(selector); | ||
|
||
assert roleId == ( | ||
(restricted && selector == to_bytes4(sig:grantRole(uint64,address,uint32).selector)) || | ||
(restricted && selector == to_bytes4(sig:revokeRole(uint64,address).selector )) | ||
? getRoleAdmin(getFirstArgumentAsUint64(data)) | ||
: ADMIN_ROLE() | ||
); | ||
|
||
assert delay == ( | ||
(restricted && selector == to_bytes4(sig:updateAuthority(address,address).selector )) || | ||
(restricted && selector == to_bytes4(sig:setTargetClosed(address,bool).selector )) || | ||
(restricted && selector == to_bytes4(sig:setTargetFunctionRole(address,bytes4[],uint64).selector)) | ||
? getTargetAdminDelay(e, getFirstArgumentAsAddress(data)) | ||
: 0 | ||
); | ||
assert restricted == false; | ||
assert roleId == getTargetFunctionRole(currentContract, selector); | ||
assert delay == 0; |
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 this version is clearer and more succinct
} else if ( | |
selector == to_bytes4(sig:labelRole(uint64,string).selector) || | |
selector == to_bytes4(sig:setRoleAdmin(uint64,uint64).selector) || | |
selector == to_bytes4(sig:setRoleGuardian(uint64,uint64).selector) || | |
selector == to_bytes4(sig:setGrantDelay(uint64,uint32).selector) || | |
selector == to_bytes4(sig:setTargetAdminDelay(address,uint32).selector) | |
) { | |
assert restricted == true; | |
assert roleId == ADMIN_ROLE(); | |
assert delay == 0; | |
} else if ( | |
selector == to_bytes4(sig:updateAuthority(address,address).selector) || | |
selector == to_bytes4(sig:setTargetClosed(address,bool).selector) || | |
selector == to_bytes4(sig:setTargetFunctionRole(address,bytes4[],uint64).selector) | |
) { | |
assert restricted == true; | |
assert roleId == ADMIN_ROLE(); | |
assert delay == getTargetAdminDelay(e, getFirstArgumentAsAddress(data)); | |
} else if ( | |
selector == to_bytes4(sig:grantRole(uint64,address,uint32).selector) || | |
selector == to_bytes4(sig:revokeRole(uint64,address).selector) | |
) { | |
assert restricted == true; | |
assert roleId == getRoleAdmin(getFirstArgumentAsUint64(data)); | |
assert delay == 0; | |
} else { | |
assert restricted == | |
isOnlyAuthorized(selector); | |
assert roleId == ( | |
(restricted && selector == to_bytes4(sig:grantRole(uint64,address,uint32).selector)) || | |
(restricted && selector == to_bytes4(sig:revokeRole(uint64,address).selector )) | |
? getRoleAdmin(getFirstArgumentAsUint64(data)) | |
: ADMIN_ROLE() | |
); | |
assert delay == ( | |
(restricted && selector == to_bytes4(sig:updateAuthority(address,address).selector )) || | |
(restricted && selector == to_bytes4(sig:setTargetClosed(address,bool).selector )) || | |
(restricted && selector == to_bytes4(sig:setTargetFunctionRole(address,bytes4[],uint64).selector)) | |
? getTargetAdminDelay(e, getFirstArgumentAsAddress(data)) | |
: 0 | |
); | |
assert restricted == false; | |
assert roleId == getTargetFunctionRole(currentContract, selector); | |
assert delay == 0; | |
assert restricted == isOnlyAuthorized(selector); | |
assert roleId == ( | |
(restricted && selector == to_bytes4(sig:grantRole(uint64,address,uint32).selector)) || | |
(restricted && selector == to_bytes4(sig:revokeRole(uint64,address).selector )) | |
? getRoleAdmin(getFirstArgumentAsUint64(data)) | |
: (restricted ? ADMIN_ROLE() : getTargetFunctionRole(currentContract, selector)) | |
); | |
assert delay == ( | |
(restricted && selector == to_bytes4(sig:updateAuthority(address,address).selector )) || | |
(restricted && selector == to_bytes4(sig:setTargetClosed(address,bool).selector )) || | |
(restricted && selector == to_bytes4(sig:setTargetFunctionRole(address,bytes4[],uint64).selector)) | |
? getTargetAdminDelay(e, getFirstArgumentAsAddress(data)) | |
: 0 | |
); |
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 this is a matter of personal preference. They express the same thing in different ways.
One is saying:
Let take all the possible function selector and group them in categories. For each category we verify that the output (restricted, roleId, delay) is what we expect.
The other is saying "here is a rule for what the roleId should be, depending on a combination of factor (including but not limited to the function selector).
The second option is indeed shorter, but I don't think its clearer or more readable. There is more intricated logic, with nested ternary operators. Option one is longer, but IMO the logic is more clearly segmented.
@james-toussaint How do you feel, given that you are "new" to FV with certora, is there one syntax you find clearer / more readable ?
_positionOf(key) <= length() && | ||
key_at(require_uint256(_positionOf(key) - 1)) == key | ||
) | ||
(contains(key) <=> key_at(require_uint256(_positionOf(key) - 1)) == key) && _positionOf(key) <= length() | ||
{ | ||
preserved remove(bytes32 otherKey) { |
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 is vacuous too for key
arguments out of bounds, so we need the following:
preserved remove(bytes32 otherKey) { | |
preserved { | |
require lengthSanity(); | |
} | |
preserved remove(bytes32 key) { |
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 don't observe that. I've been running without that preserve and the prover did not find any issue with this property
Merged this PR into #5844. We need the branch of the changes to belong to the repository in order to run the Formal Verification CI properly with access to the CERTORAKEY in secrets |
Co-authored-by: Ernesto García <[email protected]>
Co-authored-by: Ernesto García <[email protected]>
Closed in favor of #5844 |
Fixes:
Todo:
CERTORAKEY
wait_for_results