CleaningAndScriptForAllAndReadme

pull/2997/head
Aleksander Kryukov 3 years ago
parent b3dd1e0386
commit 37725a0f2c
  1. 49
      certora/README.md
  2. 2
      certora/harnesses/WizardFirstPriority.sol
  3. 2
      certora/harnesses/WizardFirstTry.sol
  4. 28
      certora/scripts/AvengersAssemble.sh
  5. 6
      certora/scripts/WizardFirstPriority.sh
  6. 4
      certora/scripts/WizardFirstTry.sh
  7. 4
      certora/scripts/sanity.sh
  8. 31
      certora/specs/Privileged.spec

@ -0,0 +1,49 @@
# Running the certora verification tool
These instructions detail the process for running CVT on the OpenZeppelin (Wizard/Governor) contracts.
Documentation for CVT and the specification language are available
[here](https://certora.atlassian.net/wiki/spaces/CPD/overview)
## Running the verification
Due to current time and space limitations in the tool, many of the rules need to
be verified separately, so there are many steps required to reverify everything.
The scripts in the `certora/scripts` directory are used to submit verification
jobs to the Certora verification service. These scripts should be run from the
root directory; for example by running
```
sh certora/scripts/WizardFirstPriority.sh <arguments>
```
After the job is complete, the results will be available on
[the Certora portal](https://vaas-stg.certora.com/).
The `AvengersAssemble` script runs all spec files agains all contracts in the `certora/harness` that start with `Wizard` meaning that a contract generated in [wizard](`certora/scripts`). If you want to verify new wizard's instance you also need to harness this contract. We don't recommend to do it because a list of harnesses may go beyond wizard's contract. The main goal of this script is to run all specs written by the team against all contracts properly harnessed.
The `WizardFirstPriority` and `WizardFirstTry` scripts run one of the scripts for the corresponding contract. In order to run another spec you should change spec file name `<specName>` in the third line of a script:
```
--verify WizardFirstPriority:certora/specs/<specName>.spec \
for example:
--verify WizardFirstPriority:certora/specs/GovernorCountingSimple.spec \
```
MENTION TIMEOUTS ISSUES
## Adapting to changes
Some of our rules require the code to be simplified in various ways. Our
primary tool for performing these simplifications is to run verification on a
contract that extends the original contracts and overrides some of the methods.
These "harness" contracts can be found in the `certora/harness` directory.
This pattern does require some modifications to the original code: some methods
need to be made virtual or public, for example. These changes are handled by
applying a patch to the code before verification.

@ -15,7 +15,7 @@ ERC20Votes
TimelockCOntroller
*/
contract WizardHarness1 is Governor, GovernorProposalThreshold, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl {
contract WizardFirstPriority is Governor, GovernorProposalThreshold, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl {
constructor(ERC20Votes _token, TimelockController _timelock, string memory name, uint256 quorumFraction)
Governor(name)
GovernorVotes(_token)

@ -13,7 +13,7 @@ ERC20Votes
TimelockCompound
*/
contract GovernorBasicHarness is Governor, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockCompound {
contract WizardFirstTry is Governor, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockCompound {
constructor(ERC20Votes _token, ICompoundTimelock _timelock, string memory name, uint256 quorumFraction)
Governor(name)
GovernorVotes(_token)

@ -0,0 +1,28 @@
for contract in certora/harnesses/Wizard*.sol;
do
for spec in certora/specs/*.spec;
do
contractFile=$(basename $contract)
specFile=$(basename $spec)
echo "Processing ${contractFile%.*} with $specFile"
if [ "${contractFile%.*}" = "WizardFirstPriority" ];
then
certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/$contractFile \
--link WizardFirstPriority:token=ERC20VotesHarness \
--verify ${contractFile%.*}:certora/specs/$specFile "$@" \
--solc solc8.2 \
--staging shelly/forSasha \
--optimistic_loop \
--settings -copyLoopUnroll=4 \
--msg "checking $spec on ${contractFile%.*}"
else
certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/$contractFile \
--verify ${contractFile%.*}:certora/specs/$specFile "$@" \
--solc solc8.2 \
--staging shelly/forSasha \
--optimistic_loop \
--settings -copyLoopUnroll=4 \
--msg "checking $spec on ${contractFile%.*}"
fi
done
done

@ -1,6 +1,6 @@
certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/WizardHarness1.sol \
--link WizardHarness1:token=ERC20VotesHarness \
--verify WizardHarness1:certora/specs/GovernorCountingSimple.spec \
certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/WizardFirstPriority.sol \
--link WizardFirstPriority:token=ERC20VotesHarness \
--verify WizardFirstPriority:certora/specs/GovernorCountingSimple.spec \
--solc solc8.2 \
--staging shelly/forSasha \
--optimistic_loop \

@ -1,5 +1,5 @@
certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/GovernorBasicHarness.sol \
--verify GovernorBasicHarness:certora/specs/GovernorBase.spec \
certoraRun certora/harnesses/ERC20VotesHarness.sol certora/harnesses/WizardFirstTry.sol \
--verify WizardFirstTry:certora/specs/GovernorBase.spec \
--solc solc8.2 \
--staging shelly/forSasha \
--optimistic_loop \

@ -1,11 +1,11 @@
for f in certora/harnesses/*.sol
for f in certora/harnesses/Wizard*.sol
do
echo "Processing $f"
file=$(basename $f)
echo ${file%.*}
certoraRun certora/harnesses/$file \
--verify ${file%.*}:certora/specs/sanity.spec "$@" \
--solc solc8.0 --staging \
--solc solc8.2 --staging shelly/forSasha \
--optimistic_loop \
--msg "checking sanity on ${file%.*}"
--settings -copyLoopUnroll=4

@ -1,31 +0,0 @@
definition knownAsNonPrivileged(method f) returns bool = false
/* ( f.selector == isWhitelistedOtoken(address).selector ||
f.selector == isWhitelistedProduct(address,address,address,bool).selector ||
f.selector == owner().selector ||
f.selector == isWhitelistedCallee(address).selector ||
f.selector == whitelistOtoken(address).selector ||
f.selector == addressBook().selector ||
f.selector == isWhitelistedCollateral(address).selector )*/;
rule privilegedOperation(method f, address privileged)
description "$f can be called by more than one user without reverting"
{
env e1;
calldataarg arg;
require !knownAsNonPrivileged(f);
require e1.msg.sender == privileged;
storage initialStorage = lastStorage;
invoke f(e1, arg); // privileged succeeds executing candidate privileged operation.
bool firstSucceeded = !lastReverted;
env e2;
calldataarg arg2;
require e2.msg.sender != privileged;
invoke f(e2, arg2) at initialStorage; // unprivileged
bool secondSucceeded = !lastReverted;
assert !(firstSucceeded && secondSucceeded), "${f.selector} can be called by both ${e1.msg.sender} and ${e2.msg.sender}, so it is not privileged";
}
Loading…
Cancel
Save