Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/build/get-started/developer-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ Now with the actual writing of your contract complete, we now need to test its f

* Contract interaction in the [Clarinet REPL](../clarinet/contract-interaction.md)
* Running your contract in a [local blockchain environment](../clarinet/local-blockchain-development.md)
* Fuzz testing with [Rendezvous](https://stacks-network.github.io/rendezvous/)
* Fuzz testing with [Rendezvous](https://stx-labs.github.io/rendezvous/)
* Writing unit tests with the [Clarinet JS SDK](../clarinet/testing-with-clarinet-sdk.md)

We'll go with unit testing for now. In your `tests` folder, open up the related `message-board.test.ts` file and let's use the unit test written below.
Expand Down
37 changes: 23 additions & 14 deletions docs/build/rendezvous/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ A property is a universal truth about your smart contract's state, functions, et

**How to extract a property?**

Say that your smart contract has a function that reverses a list of `uint`s. In this case, one property can be that "reversing a list twice returns the original list". The property will look like this:
Say that your smart contract has a function that reverses a list of `uint`s. In this case, one property can be that "reversing a list twice returns the original list". You write the property directly inside your contract, marked as [simnet-only code](../clarinet/simnet-only-code.md):

```clarity
(define-public (test-reverse-list (seq (list 127 uint)))
;; #[env(simnet)]
(define-private (test-reverse-list (seq (list 127 uint)))
(begin
(asserts!
(is-eq seq
Expand All @@ -48,10 +49,11 @@ Say that your smart contract has a function that reverses a list of `uint`s. In

**Making your property valid for Rendezvous**

> For a property to be cosidered valid by Rendezvous, it has to comply with the following rules:
> For a property to be considered valid by Rendezvous, it has to comply with the following rules:
>
> * Function lives in the contract file, annotated with `;; #[env(simnet)]`
> * Function name starts with `test-`
> * Function is declared as `public`
> * Function is declared as `private`
> * Test passes when it returns `(ok true)`
> * Test would be discarded if it returned `(ok false)`
> * Test fails if it returns an error or throws an exception
Expand All @@ -68,9 +70,10 @@ An invariant is a general truth regarding your smart contract's internal state.

**How to extract an invariant?**

Say that you have a counter contract, having functions to `increment` and `decrement`. In this case, you could use the Rendezvous [`context`](https://stacks-network.github.io/rendezvous/chapter_6.html?#the-rendezvous-context) to extract an invariant regarding your smart contract's internal state:
Say that you have a counter contract, having functions to `increment` and `decrement`. In this case, you could use the Rendezvous [`context`](https://stx-labs.github.io/rendezvous/chapter_6.html#the-rendezvous-context) to extract an invariant regarding your smart contract's internal state:

```clarity
;; #[env(simnet)]
(define-read-only (invariant-counter-gt-zero)
(let
(
Expand All @@ -92,12 +95,17 @@ Say that you have a counter contract, having functions to `increment` and `decre

**Making your invariant valid for Rendezvous**

> For an invariant to be cosidered valid by Rendezvous, it has to complain to the following ruleset:
> For an invariant to be considered valid by Rendezvous, it has to comply with the following ruleset:
>
> * Function name starts with invariant-
> * Function is declared as read-only (not public)
> * Function lives in the contract file, annotated with `;; #[env(simnet)]`
> * Function name starts with `invariant-`
> * Function is declared as `read-only`
> * Function returns a boolean value (true if the invariant holds, false if violated)
> * The test can use the special context map to access execution history
> * The test can use the special `context` map to access execution history

{% hint style="info" %}
Invariant testing requires the `context` map and a `update-context` private function in your contract (both annotated with `;; #[env(simnet)]`). Rendezvous uses them to track how many times each public function has been called. See the [Rendezvous Reference](https://stx-labs.github.io/rendezvous/chapter_6.html#the-rendezvous-context) for the exact definitions.
{% endhint %}

## Why Test in Clarity?

Expand Down Expand Up @@ -129,14 +137,13 @@ Running tests in Clarity reduces the number of external tools and integrations y

## Getting Started

Put tests next to contracts. Rendezvous will find them.
Write your tests directly inside your contract, marked as [simnet-only code](../clarinet/simnet-only-code.md) with the `;; #[env(simnet)]` annotation. Clarinet strips this code when deploying to real networks, so it never reaches mainnet — and Rendezvous picks it up automatically during testing.

```
my-project/
├── Clarinet.toml
├── contracts/
│ ├── my-contract.clar # Contract
│ ├── my-contract.tests.clar # Tests
│ └── my-contract.clar # Contract + its #[env(simnet)] tests
└── settings/
└── Devnet.toml
```
Expand All @@ -155,5 +162,7 @@ This will add Rendezvous to your project's `node_modules` and update your `packa

### Additional Resources

* \[[Github](https://stacks-network.github.io/rendezvous/)] Rendezvous repo
* \[[Youtube @jofawole](https://youtu.be/deWQxCEy9_M?si=bBpUoKGpJvFLFu_9)] How to Use Rendezvous to Fuzz Clarity Contracts
* \[[GitHub](https://github.com/stx-labs/rendezvous)] Rendezvous repository
* \[[Rendezvous Book](https://stx-labs.github.io/rendezvous/)] Full documentation
* \[[Library API](https://stx-labs.github.io/rendezvous/chapter_9.html)] Drive the testing loop yourself from TypeScript
* \[[YouTube @jofawole](https://youtu.be/deWQxCEy9_M?si=bBpUoKGpJvFLFu_9)] How to Use Rendezvous to Fuzz Clarity Contracts
43 changes: 18 additions & 25 deletions docs/build/rendezvous/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,21 +246,13 @@ The main functions and state of the contract are now covered by tests. Line cove

Rendezvous lets you test a broader range of inputs, not just specific examples. Let's see how to write your first property-based test and why it matters.

### Create the Test File

Create the Rendezvous test file:

```bash
touch contracts/stx-defi.tests.clar
```

### Add an Ice-Breaker Test

Before writing any meaningful properties, it's a good idea to check that Rendezvous can run. Add a simple "always-true" test to verify your setup.
Open `contracts/stx-defi.tests.clar` and add an always-true test:
Before writing any meaningful properties, it's a good idea to check that Rendezvous can run. Add a simple "always-true" test, annotated with `#[env(simnet)]`, to the end of `contracts/stx-defi.clar`:

```clarity
(define-public (test-always-true)
;; #[env(simnet)]
(define-private (test-always-true)
(ok true)
)
```
Expand Down Expand Up @@ -316,15 +308,14 @@ If you see similar output, your setup works. You're ready to write a **real prop

### Define a Borrowing Property

You want to test that **borrowing always updates the loan amount correctly**:
You want to test that **borrowing always updates the loan amount correctly**. Add this to the end of `contracts/stx-defi.clar`:

```clarity
;; stx-defi.tests.clar

;; #[env(simnet)]
;; Property: Borrowing should always update the loan amount correctly.
;; The new loan amount should equal the old loan amount plus the borrowed
;; amount.
(define-public (test-borrow (amount uint))
(define-private (test-borrow (amount uint))
(let (
;; Record the loan amount before performing any action that would end up
;; changing the internal state of the smart contract. Query the loans map
Expand Down Expand Up @@ -353,8 +344,8 @@ You want to test that **borrowing always updates the loan amount correctly**:

Rendezvous:

1. Injects all property-based tests directly into the deployed contract.
2. Detects all public `test-*` functions automatically.
1. Deploys the contract with all `#[env(simnet)]`-annotated test functions included.
2. Detects all private `test-*` functions automatically.
3. Generates a random sequence to call each test.
4. Produces random argument values for each function parameter.
5. Randomly selects senders from settings/Devnet.toml.
Expand All @@ -378,13 +369,14 @@ Let's address them one by one.

### Handle Preconditions

**First, you need deposits.** You can create a helper function that Rendezvous will pick up during property-based testing runs. This helper will allow deposits to be created so other tests can check properties that require deposits:
**First, you need deposits.** You can create a helper function that Rendezvous will pick up during property-based testing runs. Add this to `contracts/stx-defi.clar`:

```clarity
;; #[env(simnet)]
;; This is a helper function that will eventually be picked up during
;; property-based-testing runs. It allows creating deposits in the smart
;; contract so other tests can check properties requiring a deposit.
(define-public (test-deposit-helper (amount uint))
(define-private (test-deposit-helper (amount uint))
(let (
;; Call the deposit function and ignore the result.
(deposit-result (deposit amount))
Expand All @@ -394,13 +386,14 @@ Let's address them one by one.
)
```

**Next, add discard logic to the borrow test.** A test is discarded when it returns `(ok false)`. Wrap the core test logic in a conditional that checks for invalid preconditions (the three cases listed above) and returns `(ok false)` to discard those cases:
**Next, add discard logic to the borrow test.** A test is discarded when it returns `(ok false)`. Replace the previous `test-borrow` with this version that checks for invalid preconditions (the three cases listed above) and returns `(ok false)` to discard those cases:

```clarity
;; #[env(simnet)]
;; Property: Borrowing should always update the loan amount correctly.
;; The new loan amount should equal the old loan amount plus the borrowed
;; amount.
(define-public (test-borrow (amount uint))
(define-private (test-borrow (amount uint))
(if (or
;; If amount is 0, the STX transfer performed in the borrow operation
;; would fail, resulting in a false negative.
Expand Down Expand Up @@ -479,7 +472,7 @@ Seed : 1880056597

Counterexample:
- Test Contract : stx-defi
- Test Function : test-borrow (public)
- Test Function : test-borrow (private)
- Arguments : [1]
- Caller : wallet_8
- Outputs : {"type":{"response":{"ok":"bool","error":{"string-ascii":{"length":33}}}}}
Expand Down Expand Up @@ -678,17 +671,17 @@ You can see a complete step-by-step implementation of this tutorial with commit-

Now that you understand the power of Rendezvous, explore:

- **More examples**: Study other smart contracts in the [Examples Chapter](https://stacks-network.github.io/rendezvous/chapter_8.html) of the [Rendezvous Docs](https://stacks-network.github.io/rendezvous/)
- **More examples**: Study other smart contracts in the [Examples Chapter](https://stx-labs.github.io/rendezvous/chapter_8.html) of the [Rendezvous Docs](https://stx-labs.github.io/rendezvous/)
- **Your own contracts**: Apply Rendezvous to your projects and find bugs before they reach production

---

## Get Involved

**Found this tutorial useful?** Star the [Rendezvous repository on GitHub](https://github.com/stacks-network/rendezvous) to show your support!
**Found this tutorial useful?** Star the [Rendezvous repository on GitHub](https://github.com/stx-labs/rendezvous) to show your support!

Have questions, found a bug, or want to contribute? We'd love to hear from you:

- **Open an issue** on [GitHub](https://github.com/stacks-network/rendezvous/issues)
- **Open an issue** on [GitHub](https://github.com/stx-labs/rendezvous/issues)
- **Reach out** with questions or feedback
- **Share your findings** — contribute examples of bugs you've caught to show others how powerful advanced testing techniques can be
2 changes: 1 addition & 1 deletion docs/build/stacks-devtools-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Official Stacks devtools are built and maintained by either **Stacks Labs** or *

### Testing & Simulation

* [**Rendezvous**](https://stacks-network.github.io/rendezvous/) - A smart contract fuzzer for Clarity.
* [**Rendezvous**](https://stx-labs.github.io/rendezvous/) - A smart contract fuzzer for Clarity.

***

Expand Down
2 changes: 1 addition & 1 deletion docs/learn/network-fundamentals/audits.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ For any project, layers of security are crucial. Audits represent one layer, whi
* Bitcoin L2 Labs' [whitehat security program](https://bitcoinl2-labs.github.io/2024/06/04/orange-hats.html)
* Stacks Foundation's partnership with Staking Defense League
* Stacks Founation's ongoing [Immunefi bug bounty program](https://immunefi.com/bug-bounty/stacks/information/)
* Dedicated Stacks Foundation Residents focused exclusively on fuzz and penetration testing (created [Rendezvous](https://stacks-network.github.io/rendezvous/))
* Dedicated Stacks Foundation Residents focused exclusively on fuzz and penetration testing (created [Rendezvous](https://stx-labs.github.io/rendezvous/))

{% hint style="warning" %}
_All 'high' or 'critical' issues listed in audits have either been mitigated or otherwise made obsolete, even if the report states otherwise._
Expand Down
Loading
Loading