1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- import "helpers/helpers.spec";
- import "methods/IOwnable.spec";
- methods {
- function restricted() external;
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Function correctness: transferOwnership changes ownership โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule transferOwnership(env e) {
- require nonpayable(e);
- address newOwner;
- address current = owner();
- transferOwnership@withrevert(e, newOwner);
- bool success = !lastReverted;
- assert success <=> (e.msg.sender == current && newOwner != 0), "unauthorized caller or invalid arg";
- assert success => owner() == newOwner, "current owner changed";
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Function correctness: renounceOwnership removes the owner โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule renounceOwnership(env e) {
- require nonpayable(e);
- address current = owner();
- renounceOwnership@withrevert(e);
- bool success = !lastReverted;
- assert success <=> e.msg.sender == current, "unauthorized caller";
- assert success => owner() == 0, "owner not cleared";
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Access control: only current owner can call restricted functions โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule onlyCurrentOwnerCanCallOnlyOwner(env e) {
- require nonpayable(e);
- address current = owner();
- calldataarg args;
- restricted@withrevert(e, args);
- assert !lastReverted <=> e.msg.sender == current, "access control failed";
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Rule: ownership can only change in specific ways โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule onlyOwnerOrPendingOwnerCanChangeOwnership(env e) {
- address oldCurrent = owner();
- method f; calldataarg args;
- f(e, args);
- address newCurrent = owner();
- // If owner changes, must be either transferOwnership or renounceOwnership
- assert oldCurrent != newCurrent => (
- (e.msg.sender == oldCurrent && newCurrent != 0 && f.selector == sig:transferOwnership(address).selector) ||
- (e.msg.sender == oldCurrent && newCurrent == 0 && f.selector == sig:renounceOwnership().selector)
- );
- }
|