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

PRBMath SD59x18 and UD60x18 properties #30

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6cc2820
created folder and copied ABDK properties
tuturu-tech May 9, 2023
ba4db69
converted ABDKMath properties to PBRMath properties
tuturu-tech May 9, 2023
ac22a9e
updated comments
tuturu-tech May 9, 2023
530c5fc
added comparison operators
tuturu-tech May 10, 2023
8de2618
added echidna config to test PRB
tuturu-tech May 10, 2023
8c5da0a
submodule mistake
tuturu-tech May 10, 2023
0c6000e
removed submodules
tuturu-tech May 10, 2023
efcf1ff
install forge prb dependency
tuturu-tech May 10, 2023
e734662
removed aliasing
tuturu-tech May 10, 2023
1a480c9
precision modifications
tuturu-tech May 11, 2023
1095586
draft 59x18 and 60x18 properties
tuturu-tech May 12, 2023
866773e
added helper to calculate precision loss, modified ud60x18
tuturu-tech May 12, 2023
fd38c7e
revert formatting changes
tuturu-tech May 15, 2023
413b76f
revert formatting changes
tuturu-tech May 15, 2023
2c51fed
fix foundry remappings bug
tuturu-tech May 15, 2023
fea861e
fix solmate remapping
tuturu-tech May 15, 2023
3800c1a
separate corpus for math libraries
tuturu-tech May 15, 2023
527ddf7
improve coverage, change bounds
tuturu-tech May 16, 2023
fc9daf5
clean up comments
tuturu-tech May 16, 2023
9b51148
split up and fix some invariants
tuturu-tech May 16, 2023
5371d5e
remove unused helpers
tuturu-tech May 16, 2023
fd3aa14
gm properties
tuturu-tech May 17, 2023
faf008e
updating readme and properties list
tuturu-tech May 18, 2023
507f7bd
Merge branch 'main' into dev-prbmath-v3
tuturu-tech May 18, 2023
6c50554
added submodule
tuturu-tech May 18, 2023
5dc2fce
bug with submodule
tuturu-tech May 18, 2023
cdff7fc
added slither config to support v4, created assert helpers, updated c…
tuturu-tech May 19, 2023
9ccd809
update package.json
tuturu-tech May 19, 2023
c93b9c2
update links, add link retry on error 429
tuturu-tech Jul 5, 2023
ac203b4
changed helpers and some error bounds
tuturu-tech Jul 6, 2023
a4a4d14
formatting
tuturu-tech Jul 6, 2023
b9e1f21
update property table
tuturu-tech Jul 6, 2023
2c3e1bb
add more decimals lost to mul associative
tuturu-tech Jul 7, 2023
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
8 changes: 8 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
branch = v4.8.0
[submodule "lib/prb-math"]
path = lib/prb-math
url = https://github.com/PaulRBerg/prb-math
branch = v4
[submodule "lib/prb-math-v3"]
path = lib/prb-math-v3
url = https://github.com/PaulRBerg/prb-math
branch = v3
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Bug reports and feature suggestions can be submitted to our issue tracker. For b

## Questions

Questions can be submitted to the issue tracker, but you may get a faster response if you ask in our [chat room](https://empireslacking.herokuapp.com/) (in the #ethereum channel).
Questions can be submitted to the issue tracker, but you may get a faster response if you ask in our [chat room](https://slack.empirehacking.nyc/) (in the #ethereum channel).

## Code

Expand Down
241 changes: 240 additions & 1 deletion PROPERTIES.md

Large diffs are not rendered by default.

43 changes: 42 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [ERC721 Tests](#erc721-tests)
- [ERC4626 Tests](#erc4626-tests)
- [ABDKMath64x64 tests](#abdkmath64x64-tests)
- [PRBMath tests](#prbmath-tests)
- [Additional resources](#additional-resources)
- [Helper functions](#helper-functions)
- [Usage examples](#usage-examples)
Expand All @@ -26,6 +27,7 @@ This repository contains 168 code properties for:
- [ERC721](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) token: mintable, burnable, and transferable invariants ([19 properties](PROPERTIES.md#erc721)).
- [ERC4626](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/) vaults: strict specification and additional security invariants ([37 properties](PROPERTIES.md#erc4626)).
- [ABDKMath64x64](https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.md) fixed-point library invariants ([106 properties](PROPERTIES.md#abdkmath64x64)).
- [PRBMath](https://github.com/PaulRBerg/prb-math/blob/main/README.md) fixed-point library invariants ([132 properties](PROPERTIES.md#prbmath-sd59x18)) for SD59x18, and ([96 properties](PROPERTIES.md#prbmath-ud60x18)) for UD60x18.

The goals of these properties are to:

Expand All @@ -47,6 +49,7 @@ The properties can be used through unit tests or through fuzzing with [Echidna](
- [ERC20 tests](#erc20-tests)
- [ERC4626 test](#erc4626-tests)
- [ABDKMath64x64 tests](#abdkmath64x64-tests)
- [PRBMath tests](#prbmath-tests)

### ERC20 tests

Expand Down Expand Up @@ -414,10 +417,48 @@ contract CryticABDKMath64x64Harness is CryticABDKMath64x64PropertyTests {

Run the test suite using `echidna . --contract CryticABDKMath64x64Harness --seq-len 1 --test-mode assertion --corpus-dir tests/echidna-corpus` and inspect the coverage report in `tests/echidna-corpus` when it finishes.

### PRBMath tests

The Solidity smart contract programming language does not have any inbuilt feature for working with decimal numbers, so for contracts dealing with non-integer values, a third party solution is needed. [PRBMath](https://github.com/PaulRBerg/prb-math) is Solidity library for advanced fixed-point math that operates with signed 59.18-decimal fixed-point and unsigned 60.18-decimal fixed-point numbers

SD59x18 library implements [19 arithmetic operations](https://github.com/PaulRBerg/prb-math/blob/main/README.md#mathematical-functions "19 arithmetic operations") using fixed-point numbers and [11 conversion functions](https://github.com/PaulRBerg/prb-math/blob/main/README.md#mathematical-functions "6 conversion functions") between integer types and fixed-point types.

We provide a number of tests related with fundamental mathematical properties of the floating point numbers. To include these tests into your repository, follow these steps:

1. [Integration](#integration-4)
2. [Run](#run-4)


#### Integration

Create a new Solidity file containing the `PRBMathSD59x18Harness` or `PRBMath60x18Harness` contract:

```Solidity
pragma solidity ^0.8.0;
import "@crytic/properties/contracts/Math/PRBMath/v3/PRBMathSD59x18PropertyTests.sol;

contract CryticPRBMath59x18Harness is CryticPRBMath59x18Propertiesv3 {
/* Any additional test can be added here */
}
```

```Solidity
pragma solidity ^0.8.0;
import "@crytic/properties/contracts/Math/PRBMath/v3/PRBMathSD60x18PropertyTests.sol;

contract CryticPRBMath60x18Harness is CryticPRBMath60x18Propertiesv3 {
/* Any additional test can be added here */
}
```

#### Run

Run the test suite using `echidna-test . --contract CryticPRBMath59x18Harness --seq-len 1 --test-mode assertion --corpus-dir tests/echidna-corpus` and inspect the coverage report in `tests/echidna-corpus` when it finishes.

## Additional resources

- [Building secure contracts](https://secure-contracts.com/program-analysis/index.html)
- Our [EmpireSlacking](https://empireslacking.herokuapp.com/) slack server, channel #ethereum
- Our [EmpireSlacking](https://slack.empirehacking.nyc/) slack server, channel #ethereum
- Watch our [fuzzing workshop](https://www.youtube.com/watch?v=QofNQxW_K08&list=PLciHOL_J7Iwqdja9UH4ZzE8dP1IxtsBXI)

# Helper functions
Expand Down
36 changes: 36 additions & 0 deletions contracts/Math/PRBMath/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# PRBMath test suite for Echidna

## What is PRBMath?

The Solidity smart contract programming language does not have any inbuilt feature for working with decimal numbers, so for contracts dealing with non-integer values, a third party solution is needed. PRBMath is a fixed-point arithmetic Solidity library that operates on signed 59x18-decimal fixed-point and unsigned 60.18-decimal fixed-point numbers. This library was developed by [Paul Razvan Berg](https://github.com/PaulRBerg "Paul Razvan Berg") and is [open source](https://github.com/PaulRBerg/prb-math "open source") under the MIT License.

## Why are tests needed?

Solidity libraries are used in smart contracts that at some point in time can hold important value in tokens or other assets. The security of those assets is directly related to the robustness and reliability of the smart contract source code.

While testing does not guarantee the absence of errors, it helps the developers in assessing what the risky operations are, how they work, and ultimately how can they fail. Furthermore, having a working test suite with common and edge cases is useful to ensure that code does not behave unexpectedly, and that future versions of the library do not break compatibility.

Echidna testing can be integrated into CI/CD pipelines, so bugs are caught early and the developers are notified about security risks in their contracts.

## Who are these tests designed for?

In principle, these tests are meant to be an entry level practice to learn how to use Echidna for assertion-based fuzz tests, targeting a stand-alone library. It is a self contained exercise that shows how to determine the contract invariants, create proper tests, and configure the relevant Echidna parameters for the campaign.

Determining the invariants is a process that involves an intermediate-level comprehension of the library and the math properties behind the operations implemented. For example, the addition function has the `x+y == y+x` commutative property. This statement should always be true, no matter the values of `x` and `y`, therefore it should be a good invariant for the system. More complex operations can demand more complex invariants.

The next step, creating the tests, means to implement Solidity functions that verify the previously defined invariants. Echidna is a fuzz tester, so it can quickly test different values for the arguments of a function. For example, the commutative property can be tested using a function that takes two parameters and performs the additions, as shown below:

```solidity
// Test for commutative property
// x + y == y + x
function add_test_commutative(SD59x18 x, SD59x18 y) public pure {
SD59x18 x_y = x.add(y);
SD59x18 y_x = y.add(x);

assert(x_y.eq(y_x));
}
```

Finally, the fuzzer has to be instructed to perform the correct type of test, the number of test runs to be made, among other configuration parameters. Since the invariant is checked using an assertion, Echidna must be configured to try to find assertion violations. In this mode, different argument values are passed to `add_test_commutative()`, and the result of the `assert(x_y == y_x)` expression is evaluated for each call: if the assertion is false, the invariant was broken, and it is a sign that there can be an issue with the library implementation.

However, even if this particular test suite is meant as an exercise, it can be used as a template to create tests for other fixed-point arithmetic libraries implementations.
Loading