Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: halmos symbolic tests #21

Merged
merged 64 commits into from
Aug 23, 2024

Conversation

0xDiscotech
Copy link

@0xDiscotech 0xDiscotech commented Aug 14, 2024

Symbolic tests of the OptimismSuperchain20 properties that are stateless.

  • Had issues with symbolic addresses, when pranking senders and using _from and _to symbolic values. That's why I had to use concrete values for them instead.
  • Not sure if the mocked messenger is ok, or more logic can be removed from it
  • Copy-pasted the PROPERTIES.md file from Teddy's branch and marked the halmos tested boxes.
  • The test utils will be moved to the helper file used on Teddy's PR in the future

To run the symbolic tests just run just test-halmos-all on packages/contracts-bedrock .
Make sure to have the nightly version of halmos installed (halmos 0.1.15.dev2+gc3f45dd).

TODO: (maybe on a future PR) Complete the test of id 7 by using a symbolic value as x domain sender also.
Currently having issues when setting that value through a custom setter bc seems that after etching the storage slots are not being considered.
Also tried to hardcode a constant storage slot and update/get it with assembly but neither worked.

CLOSES FUZZ-25
CLOSES FUZZ-26

agusduha and others added 26 commits July 25, 2024 10:40
- used --foundry-compile-all to ensure the test contract under
  `test/properties` is compiled (otherwise it is not compiled and medusa
  crashes when it can't find it's compiled representation)
- set src,test,script to test/properties/medusa to not waste time
  compiling contracts that are not required for the medusa campaign
- used an atomic bridge, which doesnt allow for testing of several of
  the proposed invariants
* test: setup and 3 properties with symbolic tests
@0xDiscotech 0xDiscotech self-assigned this Aug 14, 2024
@0xDiscotech 0xDiscotech changed the base branch from develop to sc/superchain-erc20 August 14, 2024 05:48
@0xteddybear 0xteddybear changed the base branch from sc/superchain-erc20 to chore/setup-medusa August 16, 2024 21:06
@0xteddybear 0xteddybear changed the base branch from chore/setup-medusa to sc/superchain-erc20 August 16, 2024 21:07
@0xDiscotech 0xDiscotech changed the base branch from sc/superchain-erc20 to chore/setup-medusa August 16, 2024 23:27
Copy link

@0xteddybear 0xteddybear left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good! Didn't find any big issues and appreciated the care you put into DX

pragma solidity 0.8.25;

import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol";
import { SymTest } from "halmos-cheatcodes/src/SymTest.sol";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this wasn't added as a dependency

| id | milestone | description | halmos | medusa |
| --- | --------- | ------------------------------------------------------------------------------------------ | ------- | ------ |
| 6 | SupERC20 | calls to sendERC20 succeed as long as caller has enough balance | [x] | [ ] |
| 7 | SupERC20 | calls to relayERC20 always succeed as long as the sender and cross-domain caller are valid | **[x]** | [ ] |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it'd be hugely benefitial to prove it's enough for only the cross-domain caller to be valid, since that allows for a check to be removed

it's okay if we can't prove that, but I'd rather have the property retain its definition and be partially verified to be clear about that, perhaps with a note on what is it that we could prove

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the modifications to this file intended? seems like an artifact from a merge

FOUNDRY_PROFILE=halmos halmos {{VERBOSE}}

test-halmos TEST VERBOSE="-v":
FOUNDRY_PROFILE=halmos halmos --function {{TEST}} {{VERBOSE}}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -108,7 +109,7 @@ As another layer of defense, the following properties are defined which assume b
It’s worth noting that these properties will not hold for a live system

| id | milestone | description | halmos | medusa |
| --- | --- | --- | --- | --- |
| --- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you use to format markdown? so I can use it as well and keep things consistent 💖

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I managed to get the contract down to this:

contract MockL2ToL2Messenger {
    // Setting the current cross domain sender for the check of sender address equals the supertoken address
    address internal immutable CROSS_DOMAIN_SENDER;
    constructor(address _xDomainSender) {
        CROSS_DOMAIN_SENDER = _xDomainSender;
    }
    function sendMessage(uint256 , address , bytes calldata) external payable {
    }
    function crossDomainMessageSource() external view returns (uint256 _source) {
        _source = block.chainid + 1;
    }
    function crossDomainMessageSender() external view returns (address _sender) {
        _sender = CROSS_DOMAIN_SENDER;
    }
}

with all tests passing. I believe the extra code makes it a bit confusing for the reader

);

// Etch the mocked L2 to L2 Messenger since the messenger logic is out of scope for these test suite. Also, we
// avoid issues such as `TSTORE` opcode not being supported, or issues with `encodeVersionedNonce()`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't halmos' nightly build include support for tstore already? 🤔 or am I mixing it up with something else?

}

/// @custom:property-id 6
/// @custom:property-id Calls to sendERC20 succeed as long as caller has enough balance

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/property-id/property/
btw @drgorillamd are we using these natspec tags to generate something? do we plan to?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idea is to have the possibility, but rn no, we don't...


vm.prank(_sender);
/* Action */
optimismSuperchainERC20.sendERC20(Predeploys.CROSS_L2_INBOX, _amount, _chainId);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why send it to the cross_l2_inbox instead of to?

side question: would that revert on relay on a live system when trying to relay?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in other testing campaigns we have a file with this exact same name but with stuff that's

  • potentially reusable by other campaigns -> not coupled to the codebase under test
  • coupled to the tools we use (echidna/halmos/medusa)

so it'd be clearer if this file was named something else, such as HalmosBase (or anything else you prefer)

@0xteddybear 0xteddybear changed the base branch from chore/setup-medusa to feat/invariant-testing August 21, 2024 21:32
@0xteddybear 0xteddybear merged commit 7e6fdbc into feat/invariant-testing Aug 23, 2024
2 checks passed
0xteddybear added a commit that referenced this pull request Sep 10, 2024
* feat: introduce OptimismSuperchainERC20

* fix: contract fixes

* feat: add snapshots and semver

* test: add supports interface tests

* test: add invariant test

* feat: add parameters to the RelayERC20 event

* fix: typo

* fix: from param description

* fix: event signature and interface pragma

* feat: add initializer

* feat: use unstructured storage and OZ v5

* feat: update superchain erc20 interfaces

* fix: adapt storage to ERC7201

* test: add initializable OZ v5 test

* fix: invariant docs

* fix: ERC165 implementation

* test: improve superc20 invariant (#11)

* fix: gas snapshot

* chore: configure medusa with basic supERC20 self-bridging

- used --foundry-compile-all to ensure the test contract under
  `test/properties` is compiled (otherwise it is not compiled and medusa
  crashes when it can't find it's compiled representation)
- set src,test,script to test/properties/medusa to not waste time
  compiling contracts that are not required for the medusa campaign
- used an atomic bridge, which doesnt allow for testing of several of
  the proposed invariants

* fix: delete dead code

* test: give the fuzzer a head start

* feat: create suite for sybolic tests with halmos

* test: setup and 3 properties with symbolic tests

* chore: remove todo comment

* docs: fix properties order

* test: document & implement assertions 22, 23  and 24

* fix: fixes from self-review

* test: guide the fuzzer a little bit less

previously: initial mint, bound on transfer amount: 146625 calls in 200s
now: no initial mint, no bound on transfer amount: 176835 calls in 200s

it doesn't seem to slow the fuzzer down

* feat: add property for burn

* refactor: remove symbolic address on mint property

* refactor: order the tests based on the property id

* feat: checkpoint

* chore: set xdomain sender on failing test

* chore: enhance mocks

* Revert "Merge branch 'chore/setup-medusa' into feat/halmos-symbolic-tests"

This reverts commit 945d6b6, reversing
changes made to 5dcb3a8.

* refactor: remove symbolic addresses to make all of the test work

* chore: remove console logs

* feat: add properties file

* chore: polish

* refactor: enhance test on property 7 using direct try catch (now works)

* fix: review comments

* refactor: add symbolic addresses on test functions

* feat: create halmos toml

* chore: polish test contract and mock

* chore: update property

* refactor: move symbolic folder into properties one

* feat: create advanced tests helper contract

* refactor: enhance tests using symbolic addresses instead of concrete ones

* chore: remove 0 property natspec

* feat: add halmos profile and just script

* chore: rename symbolic folder to halmos

* feat: add halmos commands to justfile

* chore: reorder assertions on one test

* refactor: complete test property seven

* chore: mark properties as completed

* chore: add halmos-cheatcodes dependency

* chore: rename advancedtest->halmosbase

* chore: minimize mocked messenger

* chore: delete empty halmos file

* chore: revert changes to medusa.json

* docs: update changes to PROPERTIES.md from base branch

* test: sendERC20 destination fix

* chore: natspec fixes

---------

Co-authored-by: agusduha <[email protected]>
Co-authored-by: 0xng <[email protected]>
Co-authored-by: teddy <[email protected]>
0xteddybear added a commit that referenced this pull request Sep 16, 2024
* feat: introduce OptimismSuperchainERC20

* fix: contract fixes

* feat: add snapshots and semver

* test: add supports interface tests

* test: add invariant test

* feat: add parameters to the RelayERC20 event

* fix: typo

* fix: from param description

* fix: event signature and interface pragma

* feat: add initializer

* feat: use unstructured storage and OZ v5

* feat: update superchain erc20 interfaces

* fix: adapt storage to ERC7201

* test: add initializable OZ v5 test

* fix: invariant docs

* fix: ERC165 implementation

* test: improve superc20 invariant (#11)

* fix: gas snapshot

* chore: configure medusa with basic supERC20 self-bridging

- used --foundry-compile-all to ensure the test contract under
  `test/properties` is compiled (otherwise it is not compiled and medusa
  crashes when it can't find it's compiled representation)
- set src,test,script to test/properties/medusa to not waste time
  compiling contracts that are not required for the medusa campaign
- used an atomic bridge, which doesnt allow for testing of several of
  the proposed invariants

* fix: delete dead code

* test: give the fuzzer a head start

* feat: create suite for sybolic tests with halmos

* test: setup and 3 properties with symbolic tests

* chore: remove todo comment

* docs: fix properties order

* test: document & implement assertions 22, 23  and 24

* fix: fixes from self-review

* test: guide the fuzzer a little bit less

previously: initial mint, bound on transfer amount: 146625 calls in 200s
now: no initial mint, no bound on transfer amount: 176835 calls in 200s

it doesn't seem to slow the fuzzer down

* feat: add property for burn

* refactor: remove symbolic address on mint property

* refactor: order the tests based on the property id

* feat: checkpoint

* chore: set xdomain sender on failing test

* chore: enhance mocks

* Revert "Merge branch 'chore/setup-medusa' into feat/halmos-symbolic-tests"

This reverts commit 945d6b6, reversing
changes made to 5dcb3a8.

* refactor: remove symbolic addresses to make all of the test work

* chore: remove console logs

* feat: add properties file

* chore: polish

* refactor: enhance test on property 7 using direct try catch (now works)

* fix: review comments

* refactor: add symbolic addresses on test functions

* feat: create halmos toml

* chore: polish test contract and mock

* chore: update property

* refactor: move symbolic folder into properties one

* feat: create advanced tests helper contract

* refactor: enhance tests using symbolic addresses instead of concrete ones

* chore: remove 0 property natspec

* feat: add halmos profile and just script

* chore: rename symbolic folder to halmos

* feat: add halmos commands to justfile

* chore: reorder assertions on one test

* refactor: complete test property seven

* chore: mark properties as completed

* chore: add halmos-cheatcodes dependency

* chore: rename advancedtest->halmosbase

* chore: minimize mocked messenger

* chore: delete empty halmos file

* chore: revert changes to medusa.json

* docs: update changes to PROPERTIES.md from base branch

* test: sendERC20 destination fix

* chore: natspec fixes

---------

Co-authored-by: agusduha <[email protected]>
Co-authored-by: 0xng <[email protected]>
Co-authored-by: teddy <[email protected]>
0xteddybear added a commit that referenced this pull request Sep 17, 2024
* feat: introduce OptimismSuperchainERC20

* fix: contract fixes

* feat: add snapshots and semver

* test: add supports interface tests

* test: add invariant test

* feat: add parameters to the RelayERC20 event

* fix: typo

* fix: from param description

* fix: event signature and interface pragma

* feat: add initializer

* feat: use unstructured storage and OZ v5

* feat: update superchain erc20 interfaces

* fix: adapt storage to ERC7201

* test: add initializable OZ v5 test

* fix: invariant docs

* fix: ERC165 implementation

* test: improve superc20 invariant (#11)

* fix: gas snapshot

* chore: configure medusa with basic supERC20 self-bridging

- used --foundry-compile-all to ensure the test contract under
  `test/properties` is compiled (otherwise it is not compiled and medusa
  crashes when it can't find it's compiled representation)
- set src,test,script to test/properties/medusa to not waste time
  compiling contracts that are not required for the medusa campaign
- used an atomic bridge, which doesnt allow for testing of several of
  the proposed invariants

* fix: delete dead code

* test: give the fuzzer a head start

* feat: create suite for sybolic tests with halmos

* test: setup and 3 properties with symbolic tests

* chore: remove todo comment

* docs: fix properties order

* test: document & implement assertions 22, 23  and 24

* fix: fixes from self-review

* test: guide the fuzzer a little bit less

previously: initial mint, bound on transfer amount: 146625 calls in 200s
now: no initial mint, no bound on transfer amount: 176835 calls in 200s

it doesn't seem to slow the fuzzer down

* feat: add property for burn

* refactor: remove symbolic address on mint property

* refactor: order the tests based on the property id

* feat: checkpoint

* chore: set xdomain sender on failing test

* chore: enhance mocks

* Revert "Merge branch 'chore/setup-medusa' into feat/halmos-symbolic-tests"

This reverts commit 945d6b6, reversing
changes made to 5dcb3a8.

* refactor: remove symbolic addresses to make all of the test work

* chore: remove console logs

* feat: add properties file

* chore: polish

* refactor: enhance test on property 7 using direct try catch (now works)

* fix: review comments

* refactor: add symbolic addresses on test functions

* feat: create halmos toml

* chore: polish test contract and mock

* chore: update property

* refactor: move symbolic folder into properties one

* feat: create advanced tests helper contract

* refactor: enhance tests using symbolic addresses instead of concrete ones

* chore: remove 0 property natspec

* feat: add halmos profile and just script

* chore: rename symbolic folder to halmos

* feat: add halmos commands to justfile

* chore: reorder assertions on one test

* refactor: complete test property seven

* chore: mark properties as completed

* chore: add halmos-cheatcodes dependency

* chore: rename advancedtest->halmosbase

* chore: minimize mocked messenger

* chore: delete empty halmos file

* chore: revert changes to medusa.json

* docs: update changes to PROPERTIES.md from base branch

* test: sendERC20 destination fix

* chore: natspec fixes

---------

Co-authored-by: agusduha <[email protected]>
Co-authored-by: 0xng <[email protected]>
Co-authored-by: teddy <[email protected]>
0xng added a commit that referenced this pull request Sep 18, 2024
…11776)

* chore: configure medusa with basic supERC20 self-bridging (#19)

- used --foundry-compile-all to ensure the test contract under
  `test/properties` is compiled (otherwise it is not compiled and medusa
  crashes when it can't find it's compiled representation)
- set src,test,script to test/properties/medusa to not waste time
  compiling contracts that are not required for the medusa campaign
- used an atomic bridge, which doesnt allow for testing of several of
  the proposed invariants

fix: delete dead code
test: give the fuzzer a head start
docs: fix properties order
test: document & implement assertions 22, 23  and 24
fix: fixes from self-review
test: guide the fuzzer a little bit less
  previously: initial mint, bound on transfer amount: 146625 calls in 200s
  now: no initial mint, no bound on transfer amount: 176835 calls in 200s
  it doesn't seem to slow the fuzzer down
fix: fixes after lovely feedback by disco
docs: merge both documents and categorized properties by their milestone
fix: fixes from parti's review
fix: feedback from disco
fix: feedback from doc
refactor: separate state transitions from pure properties
docs: update tested properties
refactor: move all assertions into properties contract
fix: move function without assertions back into handler
test: only use assertion mode
fix: improve justfile recipie for medusa

* feat: halmos symbolic tests (#21)

* feat: introduce OptimismSuperchainERC20

* fix: contract fixes

* feat: add snapshots and semver

* test: add supports interface tests

* test: add invariant test

* feat: add parameters to the RelayERC20 event

* fix: typo

* fix: from param description

* fix: event signature and interface pragma

* feat: add initializer

* feat: use unstructured storage and OZ v5

* feat: update superchain erc20 interfaces

* fix: adapt storage to ERC7201

* test: add initializable OZ v5 test

* fix: invariant docs

* fix: ERC165 implementation

* test: improve superc20 invariant (#11)

* fix: gas snapshot

* chore: configure medusa with basic supERC20 self-bridging

- used --foundry-compile-all to ensure the test contract under
  `test/properties` is compiled (otherwise it is not compiled and medusa
  crashes when it can't find it's compiled representation)
- set src,test,script to test/properties/medusa to not waste time
  compiling contracts that are not required for the medusa campaign
- used an atomic bridge, which doesnt allow for testing of several of
  the proposed invariants

* fix: delete dead code

* test: give the fuzzer a head start

* feat: create suite for sybolic tests with halmos

* test: setup and 3 properties with symbolic tests

* chore: remove todo comment

* docs: fix properties order

* test: document & implement assertions 22, 23  and 24

* fix: fixes from self-review

* test: guide the fuzzer a little bit less

previously: initial mint, bound on transfer amount: 146625 calls in 200s
now: no initial mint, no bound on transfer amount: 176835 calls in 200s

it doesn't seem to slow the fuzzer down

* feat: add property for burn

* refactor: remove symbolic address on mint property

* refactor: order the tests based on the property id

* feat: checkpoint

* chore: set xdomain sender on failing test

* chore: enhance mocks

* Revert "Merge branch 'chore/setup-medusa' into feat/halmos-symbolic-tests"

This reverts commit 945d6b6, reversing
changes made to 5dcb3a8.

* refactor: remove symbolic addresses to make all of the test work

* chore: remove console logs

* feat: add properties file

* chore: polish

* refactor: enhance test on property 7 using direct try catch (now works)

* fix: review comments

* refactor: add symbolic addresses on test functions

* feat: create halmos toml

* chore: polish test contract and mock

* chore: update property

* refactor: move symbolic folder into properties one

* feat: create advanced tests helper contract

* refactor: enhance tests using symbolic addresses instead of concrete ones

* chore: remove 0 property natspec

* feat: add halmos profile and just script

* chore: rename symbolic folder to halmos

* feat: add halmos commands to justfile

* chore: reorder assertions on one test

* refactor: complete test property seven

* chore: mark properties as completed

* chore: add halmos-cheatcodes dependency

* chore: rename advancedtest->halmosbase

* chore: minimize mocked messenger

* chore: delete empty halmos file

* chore: revert changes to medusa.json

* docs: update changes to PROPERTIES.md from base branch

* test: sendERC20 destination fix

* chore: natspec fixes

---------

Co-authored-by: agusduha <[email protected]>
Co-authored-by: 0xng <[email protected]>
Co-authored-by: teddy <[email protected]>

* test: remaining protocol properties (#26)

* test: cross-user fuzzed bridges + actor setup

* test: fuzz properties 8 and 9

* test: properties 7 and 25

* fix: implement doc's feedback

* test: superc20 tob properties (#27)

* chore: add crytic/properties dependency

* test: extend protocol properties so it also covers ToB erc20 properties

* chore: small linter fixes

* docs: update property list

* test: handlers for remaining superc20 state transitions

* fix: disable ToB properties we are not using and guide the fuzzer a bit more

* fix: disable another ToB property not implemented by solady

* chore: remove zero-initializations

* fix: feedback from disco

* chore: separate fuzz campaign tests in guided vs unguided

* test: dont revert on successful unguided relay

* test: add fuzzed calls to burn and mint

* docs: document the separation of fuzz test functions

* chore: move the properties file to its own directory

* chore: consistently use fuzz_ and property_ + camelcase

* chore: fix typo

* chore: camelcase for handlers as well

* fix: revert change that broke halmos campaign compile :D

* test: fuzz non atomic bridging (#31)

* test: changed mocked messenger ABI for message sending but kept assertions the same

* docs: add new properties 26&27

* test: queue cross-chain messages and test related properties

* test: relay random messages from queue and check associated invariants

* chore: rename bridge->senderc20 method for consistency with relayerc20

* test: not-yet-deployed supertokens can get funds sent to them

* chore: medusa runs forever by default

doable since it also handles SIGINTs gracefully

* chore: document the reason behind relay zero and send zero inconsistencies

* fix: feedback from doc

* fix: walk around possible medusa issue

I'm getting an 'unknown opcode 0x4e' in ProtocolAtomic constructor when
calling the MockL2ToL2CrossDomainMessenger for the first time

* test: unguided handler for sendERC20

* fix: feedback from disco

* chore: remove halmos testsuite

* chore: foundry migration (#40)

* chore: track assertion failures

this is so foundry's invariant contract can check that an assertion
returned false in the handler, while still allowing `fail_on_revert =
false` so we can still take full advantage of medusa's fuzzer & coverage
reports

* fix: explicitly skip duplicate supertoken deployments

* chore: remove duplicated PROPERTIES.md file

* chore: expose data to foundry's external invariant checker

* test: run medusa fuzzing campaign from within foundry

* fix: eagerly check for duplicate deployments

* fix: feedback from doc

* chore: shoehorn medusa campaign into foundry dir structure

* chore: remove PROPERTIES.md file

* chore: delete medusa config

* docs: limited support for subdirectories in test/invariant

* chore: rename contracts to be more sneaky about medusa

* docs: rewrite invariant docs in a way compliant with autogen scripts

* chore: fixes from rebase

* fix: cleanup superc20 invariants (#46)

* chore: revert modifications from medusa campaign

* docs: extra docs on why ForTest contract is required

* doc: add list of all supertoken properties

* chore: run forge fmt

* ci: allow for testfiles to be deleted

* fix: run doc autogen script after rebase

---------

Co-authored-by: Disco <[email protected]>
Co-authored-by: agusduha <[email protected]>
Co-authored-by: 0xng <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants