Add setAuthority rule to AccessManaged

This commit is contained in:
ernestognw
2024-04-19 12:02:44 -06:00
parent 52665fd9b3
commit cd86596938
2 changed files with 32 additions and 7 deletions

View File

@ -10,27 +10,30 @@ contract AccessManagedHarness is AccessManaged {
constructor(address initialAuthority) AccessManaged(initialAuthority) {}
function someFunction() public restricted() {
function someFunction() public restricted {
// Sanity for FV: the msg.data when calling this function should be the same as the data used when checking
// the schedule. This is a reformulation of `msg.data == SOME_FUNCTION_CALLDATA` that focuses on the operation
// hash for this call.
require(
IAccessManager(authority()).hashOperation(_msgSender(), address(this), msg.data)
==
IAccessManager(authority()).hashOperation(_msgSender(), address(this), SOME_FUNCTION_CALLDATA)
IAccessManager(authority()).hashOperation(_msgSender(), address(this), msg.data) ==
IAccessManager(authority()).hashOperation(_msgSender(), address(this), SOME_FUNCTION_CALLDATA)
);
}
function authority_canCall_immediate(address caller) public view returns (bool result) {
(result,) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), this.someFunction.selector);
(result, ) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), this.someFunction.selector);
}
function authority_canCall_delay(address caller) public view returns (uint32 result) {
(,result) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), this.someFunction.selector);
(, result) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), this.someFunction.selector);
}
function authority_getSchedule(address caller) public view returns (uint48) {
IAccessManager manager = IAccessManager(authority());
return manager.getSchedule(manager.hashOperation(caller, address(this), SOME_FUNCTION_CALLDATA));
}
function _hasCode(address account) public view returns (bool) {
return account.code.length > 0;
}
}

View File

@ -7,9 +7,10 @@ methods {
function authority_canCall_immediate(address) external returns (bool);
function authority_canCall_delay(address) external returns (uint32);
function authority_getSchedule(address) external returns (uint48);
function _hasCode(address) external returns (bool) envfree;
// Summaries
function _.setAuthority(address) external => DISPATCHER(true);
function _.setAuthority(address) external => DISPATCHER(true);
}
invariant isConsumingScheduledOpClean()
@ -35,3 +36,24 @@ rule callRestrictedFunction(env e) {
)
);
}
/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
Rule: Only valid authorities can be set by the current authority
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
rule setAuthority(env e) {
require nonpayable(e);
address newAuthority;
address previousAuthority = authority();
setAuthority@withrevert(e, newAuthority);
bool success = !lastReverted;
assert (success && authority() == newAuthority) <=> (
previousAuthority == e.msg.sender &&
_hasCode(newAuthority)
);
}