Skip to content

Conversation

Amxx
Copy link
Collaborator

@Amxx Amxx commented Jul 7, 2025

Fixes:

Todo:

  • CERTORAKEY
  • wait_for_results

@Amxx Amxx requested a review from a team as a code owner July 7, 2025 10:03
Copy link

changeset-bot bot commented Jul 7, 2025

⚠️ No Changeset found

Latest commit: d9c9397

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@Amxx Amxx added ignore-changeset formal-verification Enable FV run in a PR. labels Jul 7, 2025
Copy link

socket-security bot commented Jul 7, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedpypi/​certora-cli@​4.13.1 ⏵ 8.1.089 -510010010070 -30

View full report

@Amxx Amxx mentioned this pull request Jul 9, 2025
1 task
@Amxx Amxx mentioned this pull request Aug 18, 2025
1 task
Comment on lines +133 to +161
} 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;
Copy link
Member

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

Suggested change
} 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
);

Copy link
Collaborator Author

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) {
Copy link
Member

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:

Suggested change
preserved remove(bytes32 otherKey) {
preserved {
require lengthSanity();
}
preserved remove(bytes32 key) {

Copy link
Collaborator Author

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

@ernestognw
Copy link
Member

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

@Amxx
Copy link
Collaborator Author

Amxx commented Aug 19, 2025

Closed in favor of #5844

@Amxx Amxx closed this Aug 19, 2025
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