moonwell-fi / moonwell-contracts-v2

BSD 3-Clause "New" or "Revised" License
29 stars 17 forks source link

Moonwell Protocol v2

The Moonwell Protocol is a fork of Compound v2 with features like borrow/supply caps, cross-chain governance, and multi-token emissions.

The "v2" release of the Moonwell Protocol is a major system upgrade to use solidity 0.8.19, add supply caps, and a number of improvements for user experience (things like mintWithPermit and claimAllRewards). Solidity version 0.8.20 was not used because EIP-3855 which adds the PUSH0 opcode was not be live on base at the time this system was deployed.

Table of Contents

Tests

The protocol has several layers of testing: unit testing, integration testing, invariants, fuzzing, mutation and formal verification.

Unit tests

The unit tests coverage must be kept as close to 100% as possible.

Integration tests

Invariants

Formal Verification

Moonwell uses Certora to formally verify key protocol invariants. The Certora formal specifications are located in the certora directory. To run the Certora tests, first you need to export the CERTORAKEY environment variable with the Certora API key.

Mutation Testing

Use certora gambit to generate mutations for MultichainVoteCollection and MultichainGovernor and then run each mutation against unit, integration tests and formal specification using run-vote-collection-mutation.sh and run-governor-mutation.sh script respectively. Each scripts generates a MutationTestOuput/Result_<Contract>.md file which stores following details for each mutations:

Finally at the end it logs total number of failed mutations.

The following steps needs to be followed for mutation testing:

  1. Run certora gambit to generate mutations:
gambit mutate --json certora/mutation/MultichainVoteCollectionConfig.json
gambit mutate --json certora/mutation/MultichainGovernorConfig.json
  1. Run script that runs tests against mutants and outputs results into a readme file:
sh bin/run-vote-collection-mutation.sh
sh bin/run-governor-mutation.sh

Note: Remember the script replaces original contract code with mutated code and thus both script cannot be run in parallel as the tests might fail because of mutated code of the other contract. But you can easily run scripts in parallel with just cloning the same repository and running single script in a single repository. Also remember to checkout any changes before running the mutations as they might affect the mutation output.

Running All Tests

Run run.sh to execute all the different tests