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

beta-v0.0.1 #7

Merged
merged 45 commits into from
Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
f4f1f74
Update Gaussian.sol
0xJepsen Dec 28, 2022
50f4f0a
Update the Readme
0xJepsen Dec 29, 2022
f9bab78
update readme
0xJepsen Dec 29, 2022
ded3faa
Quantile function
0xJepsen Dec 29, 2022
6608a52
cleaning up deps
Alexangelj Dec 30, 2022
39083db
forge install: forge-std
Alexangelj Dec 30, 2022
dabf1ae
test(differential): use ts-node to compile ffi inputs
Alexangelj Dec 30, 2022
85e9e24
delete hardhat
Alexangelj Dec 30, 2022
cd4090a
agpl-v3 license
Alexangelj Dec 30, 2022
740f0ad
forge install: solmate
Alexangelj Dec 30, 2022
99b4cd7
forge changes
Alexangelj Dec 30, 2022
5d90215
deps cleanup
Alexangelj Dec 30, 2022
6e3e0bd
more deps
Alexangelj Dec 30, 2022
9119c8e
forge install: forge-std
Alexangelj Dec 30, 2022
1935922
forge install: solmate
Alexangelj Dec 30, 2022
6a71246
refactor testing suite
Alexangelj Dec 30, 2022
4350dd0
test(finish-clean): removes most bloat
Alexangelj Dec 30, 2022
986d924
Merge pull request #5 from primitivefinance/0xJepsen-patch-1
Alexangelj Jan 1, 2023
f25f8a2
clean deps
Alexangelj Jan 2, 2023
853ee9b
forge install: forge-std
Alexangelj Jan 2, 2023
d44ceb0
forge install: solmate
Alexangelj Jan 2, 2023
ae3c39c
clean deps
Alexangelj Jan 2, 2023
257614c
forge install: solmate
Alexangelj Jan 2, 2023
3be7413
Merge branch 'develop' into alex/dec-updates
Alexangelj Jan 2, 2023
cb1ed22
clean deps
Alexangelj Jan 2, 2023
694322b
forge install: solmate
Alexangelj Jan 2, 2023
2e5073e
forge install: forge-std
Alexangelj Jan 2, 2023
ee5ba16
remove ds-test
Alexangelj Jan 2, 2023
07f7428
Merge pull request #6 from primitivefinance/alex/dec-updates
Alexangelj Jan 2, 2023
fdeab51
feat(gaussian-ref): adds gaussian lib ref
Alexangelj Jan 2, 2023
59f4b7b
feat(invariant-ref): adds invariant reference
Alexangelj Jan 2, 2023
aa13470
feat(gas-tests): profiles gas of reference
Alexangelj Jan 2, 2023
49897e0
Merge pull request #8 from primitivefinance/beta/reference-implementa…
Alexangelj Jan 2, 2023
ea587e5
chore(remove-bisection): deletes bisection lib and refs
Alexangelj Jan 2, 2023
5b12f71
build(ci): adds ci testing
Alexangelj Jan 2, 2023
0ed839a
fix(ci): fixes test to build before running tests
Alexangelj Jan 2, 2023
d33a111
test(ppf): more tests and edge conditions
Alexangelj Jan 2, 2023
193fe55
test(invariant): adds lots of invariant tests
Alexangelj Jan 2, 2023
fc3e3f4
docs(readme-natspec): adds some info to readme and natspec edits
Alexangelj Jan 2, 2023
e869b27
build(deps): adds evm bn deps
Alexangelj Jan 2, 2023
c19d94e
Merge pull request #9 from primitivefinance/beta/testing
Alexangelj Jan 2, 2023
505bf8d
Final Changes on Readme
0xJepsen Jan 2, 2023
554dfdf
update gitignore
0xJepsen Jan 2, 2023
78730f6
ci(more-fuzz): adds more fuzz to ci
Alexangelj Jan 2, 2023
48ee022
fix(test-rel-err): updates reverse fuzz relative err %
Alexangelj Jan 2, 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
28 changes: 28 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
on: [push]

name: test

jobs:
check:
name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install deps
run: yarn install

- name: Build
run: yarn build

- name: Run tests
run: forge test
env:
FOUNDRY_FUZZ_RUNS: 10000
6 changes: 1 addition & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ coverage
coverage.json
typechain-types
yarn-error.log

#Hardhat files
artifacts/
hh-cache/

dist/

# Foundry
cache
Expand Down
8 changes: 5 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
branch = v1.2.0
[submodule "lib/solmate"]
path = lib/solmate
url = https://github.com/transmissions11/solmate
branch = v7
8 changes: 0 additions & 8 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,9 +1 @@
# Ignore artifacts:
artifacts
cache
coverage
coverage*
typechain-types

# Ignore certain files
/contracts/Bisection.sol
423 changes: 205 additions & 218 deletions LICENSE

Large diffs are not rendered by default.

79 changes: 76 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
# Hardhat Foundry Template
# SolStat

Combines hardhat and foundry testing frameworks to take advantage of coverage and fuzzing capabiltiies, along with their native tools.
SolStat is a Math library written in solidity for statistical function approximations. The library is composed of two core libraries; Gaussian.sol, and Invariant.sol. We will go over each of these libraries and their testing suites. We at Primitive use these libraries to support development with RMM-01s unique trading function, which utilizes the cumulative distribution function (CDF) of the normal distribution denoted by the greek capital letter Phi($\Phi$) in the literature [1,2]. You may recognize the normal or Gaussian distribution as the bell curve. This distribution is significant in modeling real-valued random numbers of unknown distributions. Within the RMM-01 trading function and options pricing, the CDF is used to model random price movement of a Markov process. Since price paths are commonly modeled with markovian proccesses, we believe that the greater community will find value in this library.

Inspired by [Seaport](https://github.com/ProjectOpenSea/seaport)
## How to use

Requirements: forge, node >=v16.0.0

```
yarn install
forge install
yarn build
forge test
```

To compute values using the gaussian.js library, you can use this commmand in the cli:

```
yarn cli --cdf {value}
yarn cli --pdf {value}
yarn cli --ppf {value}
```

## Irrational Functions

The primary reason for utilizing these approximation algorithms is that computers have trouble expressing irrational functions. This is because irrational numbers have an infinite number of decimals. Some examples of irrational numbers are $\pi$ and $\sqrt(2)$. This only becomes a challenge when we try to compute these numbers. This is because computers don't have an infinite amount of memory. Thus mathematicians and computer scientists have developed a variety of approximation algorithms to achieve varying degrees of speed and accuracy when approximating these irrational functions. These algorithms are commonly iterative and achieve greater accuracy with more iterations.

## Computational Constraints

In classical computing, our computational resources have become [abundant](https://en.wikipedia.org/wiki/Moore%27s_law), allowing us the liberty to iterate these algorithms to achieve our desired accuracy. However, the [Ethereum Virtual Machine (EVM)](https://ethereum.org/en/developers/docs/evm/) has a necessary monetary cost of computation. This computational environment has monetarily motivated developers to find efficient algorithms and hacks to reduce their applications' computational overhead (and thus the cost of computation).

## `Gaussian.sol`

This contract implements a number of functions important to the gaussian distributions. Importantly all these implementations are only for a mean $\mu = 0$ and variance $\sigma = 1$. These implementations are based on the [Numerical Recipes](https://e-maxx.ru/bookz/files/numerical_recipes.pdf) textbook and its C implementation. [Numerical Recipes](https://e-maxx.ru/bookz/files/numerical_recipes.pdf) cites the original text by Abramowitz and Stegun, "[Handbook of Mathematical Functions](https://personal.math.ubc.ca/~cbm/aands/abramowitz_and_stegun.pdf)," which should be read to understand these unique functions and the implications of their numerical approximations. This implementation was also inspired by the [javascript Gausian library](https://github.com/errcw/gaussian), which implements the same algorithm.

### Cumulative Distribution Function

The implementation of the CDF aproximation algorithm takes in a random variable $x$ as a single parameter. The function depends on a special helper functions known as the error function `erf`. The error function’s identity is `erfc(-x) = 2 - erfc(x)` and has a small collection of unique properties:

erfc(-$\infty$) = 2

erfc(0) = 1

erfc($\infty$) = 0

The reference implementation for the error function is on p221 of Numerical Recipes in section C 2e. A helpful resource is this [wolfram notebook](https://mathworld.wolfram.com/Erfc.html).

### Probability Density Function

The library also supports an approximation of the Probability Density Function(PPF) which is mathematically interpeted as $Z(x) = \frac{1}{\sigma\sqrt{2\pi}}e^{\frac{-(x - \mu)^2}{2\sigma^2}}$. This implementation has a maximum error bound of of $1.2e-7$ and can be refrenced in this [wofram notebook](https://mathworld.wolfram.com/ProbabilityDensityFunction.html).

### Percent Point Function / Quantile Function

Furthermore we implemented aproximation algorithms for the Percent Point Function(PPF) sometimes known as the inverse CDF or the quantile function. The function is mathmatically defined as $D(x) = \mu - \sigma\sqrt{2}(ierfc(2x))$, has a maximum error of `1.2e-7`, and depends on the inverse error function `ierf` which satisfies `ierfc(erfc(x)) = erfc(ierfc(x))`. The invers error function, defined as `ierfc(1 - x) = ierf(x)`, has a domain of in the interval $0 < x < 2$ and has some unique properties:

ierfc(0) = $\infty$

ierfc(1) = 0

ierfc(2) = -$\infty$

## `Invariant.sol`

`Invariant.sol` is a contract used to compute the invariant of the RMM-01 trading function such that we compute $y$ in $y = K\Phi(\Phi^{⁻¹}(1-x) - \sigma\sqrt(\tau)) + k$. Notice how we need to compute the normal CDF of a quantity. For a more detailed perspective on the trading function, please see the whitepaper. This is an example of how we have used this library for our research, development, and testing of RMM-01. The function reverts if $x$ is greater than one and simplifies to $K(1+x) + k$ when $\tau$ is zero (at expiry). The function takes in five parameters
`R_x`: The reserves of token $x$ per unit of liquidity, always within the bounds of $[0,1]$.
`strk`: The strike price of the pool.
`vol`: the implied volatility of the pool denoted by the lowercase greek letter sigma in finance literature.
`tau`: The time until the pool expires. Once expired, there can be no swaps.
`inv`: The current invariant given `R_x`.
The function then returns the quantity of token y per unit of liquidity denoted `R_y`, which is always within the bounds of $[0, stk]$. This is a clear example of how one would use this library.

## Differential Testing with Foundry

We leveraged foundry's support of differential testing for this library. Differential testing is a popular technique that seeds inputs to different implementations of the same application and detects differences in their execution. Differential testing is an excellent complement to traditional software testing as it is well suited to detect semantic errors. This library used differential testing against the javascript gaussian library to detect anomalies and varying bugs. This helped us to be confident in the performance and implementation of the library.

[1]: [Replicating Market Makers](https://arxiv.org/pdf/2103.14769.pdf)

[2]: [Replicating Portfolios: Contstructing Permissionless Derivatives](https://arxiv.org/pdf/2205.09890.pdf)
34 changes: 34 additions & 0 deletions cli/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import gaussian from 'gaussian'

const cdf = (x) => {
return gaussian(0, 1).cdf(x)
}

const ppf = (x) => {
return gaussian(0, 1).ppf(x)
}

const pdf = (x) => {
return gaussian(0, 1).pdf(x)
}

async function main() {
const args = process.argv
const [, , flag, value] = args

if (value) {
if (flag && flag === '--cdf') {
console.log(`cdf: ${cdf(value)}`)
} else if (flag && flag === '--ppf') {
console.log(`ppf: ${ppf(value)}`)
} else if (flag && flag === '--pdf') {
console.log(`pdf: ${pdf(value)}`)
} else {
console.log(`Unknown operation: ${flag}`)
}
} else {
console.log('No value supplied...')
}
}

main().catch((err) => process.exit(1))
10 changes: 0 additions & 10 deletions config/.solcover.js

This file was deleted.

53 changes: 0 additions & 53 deletions contracts/Bisection.sol

This file was deleted.

6 changes: 0 additions & 6 deletions contracts/Example.sol

This file was deleted.

26 changes: 0 additions & 26 deletions contracts/test/TestGaussian.sol

This file was deleted.

39 changes: 7 additions & 32 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,36 +1,11 @@
[default]
[profile.default]
solc = "0.8.13"
via_ir = true
src = 'contracts'
out = 'out'
libs = ['lib', 'node_modules']
test = 'test/foundry'
optimizer_runs = 15000
ffi = true # important!
remappings = [
'ds-test=lib/ds-test/src/',
'forge-std=lib/forge-std/src/',
'contracts/=contracts/',
'solmate/=lib/solmate/src/'
]
optimizer_runs = 15000
fuzz_runs = 256
fuzz_max_local_rejects = 65536
fuzz_max_global_rejects = 1024

[optimized]
solc = '0.8.13'
out = 'optimized-out'

[test]
solc = '0.8.13'
via_ir = false
src = 'test/foundry'
gas_reports = ["*"]
ffi = true
fuzz_runs = 500

[lite]
out = 'optimized-out'
via_ir = false
fuzz_runs = 1000



# See more config options https://github.com/gakonst/foundry/tree/master/config
[fuzz]
runs = 10000
39 changes: 0 additions & 39 deletions hardhat-coverage.config.ts

This file was deleted.

Loading