From f30ede0ed9a388aa37994ea117150898ae77c26f Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 10:28:29 +0000 Subject: [PATCH 01/40] struct less solution to viaIR --- contracts/libraries/HyperdriveMath.sol | 44 +++++---- contracts/libraries/YieldSpaceMath.sol | 123 +++++++++---------------- foundry.toml | 2 +- test/YieldSpaceMath.t.sol | 6 +- 4 files changed, 70 insertions(+), 105 deletions(-) diff --git a/contracts/libraries/HyperdriveMath.sol b/contracts/libraries/HyperdriveMath.sol index da701b202..9e46ac0b1 100644 --- a/contracts/libraries/HyperdriveMath.sol +++ b/contracts/libraries/HyperdriveMath.sol @@ -133,15 +133,18 @@ library HyperdriveMath { // timeRemaining*amountIn shares to purchase newly minted bonds on a // YieldSpace curve configured to timeRemaining = 1. uint256 curveIn = _amountIn.mulDown(_timeRemaining); + + // Credit the share reserves by the flat trade. + _shareReserves = _shareReserves.add(flat); + // Debit the bond reserves by the flat trade. + _bondReserves = _bondReserves.sub(flat.mulDown(_sharePrice)); + uint256 curveOut = YieldSpaceMath.calculateOutGivenIn( - // Credit the share reserves by the flat trade. - _shareReserves.add(flat), - // Debit the bond reserves by the flat trade. - _bondReserves.sub(flat.mulDown(_sharePrice)), + _shareReserves, + _bondReserves, _bondReserveAdjustment, curveIn, - FixedPointMath.ONE_18, - _timeStretch, + FixedPointMath.ONE_18.sub(_timeStretch), _sharePrice, _initialSharePrice, _isBondOut @@ -162,15 +165,18 @@ library HyperdriveMath { uint256 curveIn = _amountIn.mulDown(_timeRemaining).divDown( _sharePrice ); + + // Debit the share reserves by the flat trade. + _shareReserves = _shareReserves.sub(flat); + // Credit the bond reserves by the flat trade. + _bondReserves = _bondReserves.add(flat.mulDown(_sharePrice)); + uint256 curveOut = YieldSpaceMath.calculateOutGivenIn( - // Debit the share reserves by the flat trade. - _shareReserves.sub(flat), - // Credit the bond reserves by the flat trade. - _bondReserves.add(flat.mulDown(_sharePrice)), + _shareReserves, + _bondReserves, _bondReserveAdjustment, curveIn, - FixedPointMath.ONE_18, - _timeStretch, + FixedPointMath.ONE_18.sub(_timeStretch), _sharePrice, _initialSharePrice, _isBondOut @@ -230,15 +236,17 @@ library HyperdriveMath { uint256 curveOut = _amountOut.mulDown(_timeRemaining).divDown( _sharePrice ); + + // Credit the share reserves by the flat trade. + _shareReserves = _shareReserves.add(flat); + // Debit the bond reserves by the flat trade. + _bondReserves = _bondReserves.sub(flat.mulDown(_sharePrice)); uint256 curveIn = YieldSpaceMath.calculateInGivenOut( - // Credit the share reserves by the flat trade. - _shareReserves.add(flat), - // Debit the bond reserves by the flat trade. - _bondReserves.sub(flat.mulDown(_sharePrice)), + _shareReserves, + _bondReserves, _bondReserveAdjustment, curveOut, - FixedPointMath.ONE_18, - _timeStretch, + FixedPointMath.ONE_18.sub(_timeStretch), _sharePrice, _initialSharePrice, false diff --git a/contracts/libraries/YieldSpaceMath.sol b/contracts/libraries/YieldSpaceMath.sol index fde9abcb4..78caf88ab 100644 --- a/contracts/libraries/YieldSpaceMath.sol +++ b/contracts/libraries/YieldSpaceMath.sol @@ -19,8 +19,7 @@ library YieldSpaceMath { /// @param bondReserves bond reserves amount, unit is the face value in underlying /// @param bondReserveAdjustment An optional adjustment to the reserve which MUST have units of underlying. /// @param amountIn amount to be traded, if bonds in the unit is underlying, if shares in the unit is shares - /// @param t time till maturity in seconds - /// @param s time stretch coefficient. e.g. 25 years in seconds + /// @param oneMinusT 1 - st /// @param c price of shares in terms of their base /// @param mu Normalization factor -- starts as c at initialization /// @param isBondOut determines if the output is bond or shares @@ -30,56 +29,31 @@ library YieldSpaceMath { uint256 bondReserves, uint256 bondReserveAdjustment, uint256 amountIn, - uint256 t, - uint256 s, + uint256 oneMinusT, uint256 c, uint256 mu, bool isBondOut - ) internal pure returns (uint256 result) { - uint256 outReserves; - uint256 rhs; - // Notes: 1 >= 1-st >= 0 - uint256 oneMinusT = FixedPointMath.ONE_18.sub(s.mulDown(t)); - // c/mu + ) internal pure returns (uint256) { uint256 cDivMu = c.divDown(mu); - // Adjust the bond reserve, optionally shifts the curve around the inflection point - uint256 modifiedBondReserves = bondReserves.add(bondReserveAdjustment); - // c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - uint256 k = cDivMu - .mulDown(mu.mulDown(shareReserves).pow(oneMinusT)) - .add(modifiedBondReserves.pow(oneMinusT)); - + bondReserves = bondReserves.add(bondReserveAdjustment); + uint256 k = _k(cDivMu, mu, shareReserves, oneMinusT, bondReserves); if (isBondOut) { - // bondOut = bondReserves - ( c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - c/mu * (mu*(shareReserves + shareIn))^(1-t) )^(1 / (1 - t)) - outReserves = modifiedBondReserves; - // (mu*(shareReserves + amountIn))^(1-t) - uint256 newScaledShareReserves = mu - .mulDown(shareReserves.add(amountIn)) - .pow(oneMinusT); - // c/mu * (mu*(shareReserves + amountIn))^(1-t) - newScaledShareReserves = cDivMu.mulDown(newScaledShareReserves); - // Notes: k - newScaledShareReserves >= 0 to avoid a complex number - // ( c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - c/mu * (mu*(shareReserves + amountIn))^(1-t) )^(1 / (1 - t)) - rhs = k.sub(newScaledShareReserves).pow( + shareReserves = mu.mulDown(shareReserves.add(amountIn)).pow( + oneMinusT + ); + shareReserves = cDivMu.mulDown(shareReserves); + uint256 rhs = k.sub(shareReserves).pow( FixedPointMath.ONE_18.divDown(oneMinusT) ); + return bondReserves.sub(rhs); } else { - // shareOut = shareReserves - [ ( c/mu * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + bondIn)^(1-t) ) / c/u ]^(1 / (1 - t)) / mu - outReserves = shareReserves; - // (bondReserves + bondIn)^(1-t) - uint256 newScaledBondReserves = modifiedBondReserves - .add(amountIn) - .pow(oneMinusT); - // Notes: k - newScaledBondReserves >= 0 to avoid a complex number - // [( (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + bondIn)^(1-t) ) / c/u ]^(1 / (1 - t)) - rhs = k.sub(newScaledBondReserves).divDown(cDivMu).pow( + bondReserves = bondReserves.add(amountIn).pow(oneMinusT); + uint256 rhs = k.sub(bondReserves).divDown(cDivMu).pow( FixedPointMath.ONE_18.divDown(oneMinusT) ); - // [( (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + bondIn)^(1-t) ) / c/u ]^(1 / (1 - t)) / mu rhs = rhs.divDown(mu); + return shareReserves.sub(rhs); } - // Notes: outReserves - rhs >= 0, but i think avoiding a complex number in the step above ensures this never happens - result = outReserves.sub(rhs); } /// @dev Calculates the amount of an asset that will be received given a @@ -88,8 +62,7 @@ library YieldSpaceMath { /// @param bondReserves bond reserves amount, unit is the face value in underlying /// @param bondReserveAdjustment An optional adjustment to the reserve which MUST have units of underlying. /// @param amountOut amount to be received, if bonds in the unit is underlying, if shares in the unit is shares - /// @param t time till maturity in seconds - /// @param s time stretch coefficient. e.g. 25 years in seconds + /// @param oneMinusT 1 - st /// @param c price of shares in terms of their base /// @param mu Normalization factor -- starts as c at initialization /// @param isBondIn determines if the input is bond or shares @@ -99,57 +72,43 @@ library YieldSpaceMath { uint256 bondReserves, uint256 bondReserveAdjustment, uint256 amountOut, - uint256 t, - uint256 s, + uint256 oneMinusT, uint256 c, uint256 mu, bool isBondIn - ) internal pure returns (uint256 result) { - uint256 inReserves; - uint256 rhs; - // Notes: 1 >= 1-st >= 0 - uint256 oneMinusT = FixedPointMath.ONE_18.sub(s.mulDown(t)); - // c/mu + ) internal pure returns (uint256) { uint256 cDivMu = c.divDown(mu); - // Adjust the bond reserve, optionally shifts the curve around the inflection point - uint256 modifiedBondReserves = bondReserves.add(bondReserveAdjustment); - // c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - uint256 k = cDivMu - .mulDown(mu.mulDown(shareReserves).pow(oneMinusT)) - .add(modifiedBondReserves.pow(oneMinusT)); - + bondReserves = bondReserves.add(bondReserveAdjustment); + uint256 k = _k(cDivMu, mu, shareReserves, oneMinusT, bondReserves); if (isBondIn) { - // bondIn = ( c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - c/mu * (mu*(shareReserves - shareOut))^(1-t) )^(1 / (1 - t)) - bond_reserves - inReserves = modifiedBondReserves; - // (mu*(shareReserves - amountOut))^(1-t) - uint256 newScaledShareReserves = mu - .mulDown(shareReserves.sub(amountOut)) - .pow(oneMinusT); - // c/mu * (mu*(shareReserves - amountOut))^(1-t) - newScaledShareReserves = cDivMu.mulDown(newScaledShareReserves); - // Notes: k - newScaledShareReserves >= 0 to avoid a complex number - // ( c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - c/mu * (mu*(shareReserves - amountOut))^(1-t) )^(1 / (1 - t)) - rhs = k.sub(newScaledShareReserves).pow( + shareReserves = mu.mulDown(shareReserves.sub(amountOut)).pow( + oneMinusT + ); + shareReserves = cDivMu.mulDown(shareReserves); + uint256 rhs = k.sub(shareReserves).pow( FixedPointMath.ONE_18.divDown(oneMinusT) ); + return rhs.sub(bondReserves); } else { - // shareOut = [ ( c/mu * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - bondOut)^(1-t) ) / c/u ]^(1 / (1 - t)) / mu - share_reserves - inReserves = shareReserves; - // (bondReserves - amountOut)^(1-t) - uint256 newScaledBondReserves = modifiedBondReserves - .sub(amountOut) - .pow(oneMinusT); - // Notes: k - newScaledBondReserves >= 0 to avoid a complex number - // [( (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - amountOut)^(1-t) ) / c/u ]^(1 / (1 - t)) - rhs = k.sub(newScaledBondReserves).divDown(cDivMu).pow( + bondReserves = bondReserves.sub(amountOut).pow(oneMinusT); + uint256 rhs = k.sub(bondReserves).divDown(cDivMu).pow( FixedPointMath.ONE_18.divDown(oneMinusT) ); - // [( (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - amountOut)^(1-t) ) / c/u ]^(1 / (1 - t)) / mu rhs = rhs.divDown(mu); + return rhs.sub(shareReserves); } - // TODO: Double check this. - // - // Notes: rhs - inReserves >= 0, but i think avoiding a complex number in the step above ensures this never happens - result = rhs.sub(inReserves); + } + + function _k( + uint256 cDivMu, + uint256 mu, + uint256 shareReserves, + uint256 oneMinusT, + uint256 modifiedBondReserves + ) private pure returns (uint256) { + return + cDivMu.mulDown(mu.mulDown(shareReserves).pow(oneMinusT)).add( + modifiedBondReserves.pow(oneMinusT) + ); } } diff --git a/foundry.toml b/foundry.toml index df0b7e6b4..16fcc9adc 100644 --- a/foundry.toml +++ b/foundry.toml @@ -16,7 +16,7 @@ optimizer = true # The number of optimizer runs optimizer_runs = 7500 # Whether or not to use the Yul intermediate representation compilation pipeline -via_ir = true +via_ir = false remappings = ['forge-std=lib/forge-std/src', '@openzeppelin/=node_modules/@openzeppelin'] # gas limit - max u64 diff --git a/test/YieldSpaceMath.t.sol b/test/YieldSpaceMath.t.sol index eaf5a113e..66ad5872b 100644 --- a/test/YieldSpaceMath.t.sol +++ b/test/YieldSpaceMath.t.sol @@ -12,8 +12,7 @@ contract YieldSpaceMathTest is Test { 62.38101813e18, // bondReserves 119.1741606776616e18, // bondReserveAdjustment 5.03176076e18, // amountOut - 0.08065076081220067e18, // t - 1e18, // s + 1e18 - 0.08065076081220067e18, // t 1e18, // c 1e18, // mu true // isBondIn @@ -29,8 +28,7 @@ contract YieldSpaceMathTest is Test { 56.92761678068477e18, // bondReserves 119.1741606776616e18, // bondReserveAdjustment 5.500250311701939e18, // amountOut - 0.08065076081220067e18, // t - 1e18, // s + 1e18 - 0.08065076081220067e18, // t 1e18, // c 1e18, // mu false // isBondIn From e5093a11063b840afb1af2ef786fafde6e58ceac Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 10:43:52 +0000 Subject: [PATCH 02/40] add workflow for coverage --- .github/workflows/coverage.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 000000000..147560897 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,18 @@ +on: [push] + +name: coverage + +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 + + - name: Run coverage + run: forge coverage >> $GITHUB_STEP_SUMMARY From 7e73423dfdcb037aab7bf13c181cfebfdce086ee Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 10:45:23 +0000 Subject: [PATCH 03/40] add node in workflow --- .github/workflows/coverage.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 147560897..42c401baf 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -11,6 +11,18 @@ jobs: with: submodules: recursive + - name: install node + uses: actions/setup-node@v3 + with: + node-version: 14.x + + - name: install packages + uses: borales/actions-yarn@v4 + with: + cmd: install # will run `yarn install` command + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # if needed + - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 From 01096296ba4f4be2462d6b28c27553b357efc993 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 10:53:42 +0000 Subject: [PATCH 04/40] update --- .github/workflows/coverage.yml | 18 ++++++++++++++---- .github/workflows/lint.yml | 4 +--- .github/workflows/test.yml | 4 +--- .gitignore | 2 ++ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 42c401baf..24142f1c6 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,10 +1,8 @@ on: [push] -name: coverage - jobs: check: - name: Foundry project + name: coverage runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -27,4 +25,16 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 - name: Run coverage - run: forge coverage >> $GITHUB_STEP_SUMMARY + run: forge coverage --report lcov + + - name: Setup LCOV + uses: hrishikesh-kadam/setup-lcov@v1 + + - name: Report code coverage + uses: zgosalvez/github-actions-report-lcov@v3 + with: + coverage-files: lcov.info + artifact-name: code-coverage-report + github-token: ${{ secrets.GITHUB_TOKEN }} + + # run: lcov --remove lcov.info -o lcov.info 'test/*' 'script/*' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 60a67ac8e..32a8ddbba 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,10 +1,8 @@ on: [push] -name: lint - jobs: build: - name: solidity + name: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 258a72fb0..60d0d4d08 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,10 +1,8 @@ on: [push] -name: test - jobs: check: - name: solidity + name: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.gitignore b/.gitignore index 4bb3c375a..7ce3c7dc4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ node_modules/ yarn-error.log .direnv + +lcov.info From 4771c68dd358e46e920b05220f0c99cc80045258 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 10:55:02 +0000 Subject: [PATCH 05/40] update --- .github/workflows/coverage.yml | 4 ++-- .github/workflows/lint.yml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 24142f1c6..0daaa72dc 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,5 +1,7 @@ on: [push] +name: hyperdrive + jobs: check: name: coverage @@ -36,5 +38,3 @@ jobs: coverage-files: lcov.info artifact-name: code-coverage-report github-token: ${{ secrets.GITHUB_TOKEN }} - - # run: lcov --remove lcov.info -o lcov.info 'test/*' 'script/*' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 32a8ddbba..805c7f4d9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,7 @@ on: [push] +name: hyperdrive + jobs: build: name: lint From 7507379adccb45ec0ac0933bf78b079798ea4f0e Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 10:55:08 +0000 Subject: [PATCH 06/40] update --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 60d0d4d08..3dfccffcf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,7 @@ on: [push] +name: hyperdrive + jobs: check: name: test From c28148bc8b23cb33fb991b3fc4199d5ba4a2d56f Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:17:04 +0000 Subject: [PATCH 07/40] use codecov --- .github/workflows/coverage.yml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0daaa72dc..67422dc80 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -29,12 +29,19 @@ jobs: - name: Run coverage run: forge coverage --report lcov - - name: Setup LCOV - uses: hrishikesh-kadam/setup-lcov@v1 - - - name: Report code coverage - uses: zgosalvez/github-actions-report-lcov@v3 - with: - coverage-files: lcov.info - artifact-name: code-coverage-report - github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Upload to codecov + uses: codecov/codecov-action@v3 + with: token: ${{ secrets.CODECOV_TOKEN }} + files: ./lcov.info + fail_ci_if_error: true + + + # - name: Setup LCOV + # uses: hrishikesh-kadam/setup-lcov@v1 + + # - name: Report code coverage + # uses: zgosalvez/github-actions-report-lcov@v3 + # with: + # coverage-files: lcov.info + # artifact-name: code-coverage-report + # github-token: ${{ secrets.GITHUB_TOKEN }} From 5b57682f455b6739e80dbc24124328bf30800b7e Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:17:47 +0000 Subject: [PATCH 08/40] remove comments --- .github/workflows/coverage.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 67422dc80..5f4148dca 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -35,13 +35,3 @@ jobs: files: ./lcov.info fail_ci_if_error: true - - # - name: Setup LCOV - # uses: hrishikesh-kadam/setup-lcov@v1 - - # - name: Report code coverage - # uses: zgosalvez/github-actions-report-lcov@v3 - # with: - # coverage-files: lcov.info - # artifact-name: code-coverage-report - # github-token: ${{ secrets.GITHUB_TOKEN }} From 852f21c7cdd1526ad13cb1cf44a83263156ff4dc Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:20:31 +0000 Subject: [PATCH 09/40] update --- .github/workflows/coverage.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5f4148dca..7f97731c2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -31,7 +31,8 @@ jobs: - name: Upload to codecov uses: codecov/codecov-action@v3 - with: token: ${{ secrets.CODECOV_TOKEN }} - files: ./lcov.info - fail_ci_if_error: true - + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./lcov.info + fail_ci_if_error: true + verbose: true From e2ff78f584f8e276345f9d0bb624124654d00193 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:24:17 +0000 Subject: [PATCH 10/40] added comment? --- .github/workflows/coverage.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7f97731c2..411efa828 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -36,3 +36,9 @@ jobs: files: ./lcov.info fail_ci_if_error: true verbose: true + comment: # this is a top-level key + layout: "reach, diff, flags, files" + behavior: default + require_changes: false # if true: only post the comment if coverage changes + require_base: no # [yes :: must have a base report to post] + require_head: yes From 874d7c84dffc6f10c560ee483d8e0a64f94a4c26 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:26:37 +0000 Subject: [PATCH 11/40] update --- codecov.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..896ea35c1 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,6 @@ +comment: + layout: "reach, diff, flags, files" + behavior: default + require_changes: false + require_base: no + require_head: yes From 146dd6abf6e063b7aed9411b28663f43b9a036aa Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:26:59 +0000 Subject: [PATCH 12/40] remove comment --- .github/workflows/coverage.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 411efa828..7f97731c2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -36,9 +36,3 @@ jobs: files: ./lcov.info fail_ci_if_error: true verbose: true - comment: # this is a top-level key - layout: "reach, diff, flags, files" - behavior: default - require_changes: false # if true: only post the comment if coverage changes - require_base: no # [yes :: must have a base report to post] - require_head: yes From 885fadf3c877539d152561de993a63e545eafbcb Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:33:26 +0000 Subject: [PATCH 13/40] filter test and script files --- .github/workflows/coverage.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7f97731c2..99f6b3885 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -27,7 +27,9 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 - name: Run coverage - run: forge coverage --report lcov + run: | + forge coverage --report lcov + lcov --remove lcov.info 'test/*' 'script/*' > lcov.info - name: Upload to codecov uses: codecov/codecov-action@v3 From 19778e20a52d6d90ad4d91442bdc9a99cd251308 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:35:44 +0000 Subject: [PATCH 14/40] add to README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index e2d0bd5d9..26ecf2c97 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![codecov](https://codecov.io/gh/element-fi/hyperdrive/branch/main/graph/badge.svg?token=I35ZGDABCS)](https://codecov.io/gh/element-fi/hyperdrive) + # Hyperdrive Hyperdrive is an automated market maker that enables fixed-rate markets to be @@ -34,3 +36,9 @@ If you want to automatically format the code, run `yarn prettier`. The language used in this codebase is for coding convenience only, and is not intended to, and does not, have any particular legal or regulatory significance. + +# Coverage + + + + From 8a41e97b2699185a566df70f69b69d1f9f63c7d7 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:38:37 +0000 Subject: [PATCH 15/40] comment --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26ecf2c97..13b1ecd58 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ If you want to automatically format the code, run `yarn prettier`. The language used in this codebase is for coding convenience only, and is not intended to, and does not, have any particular legal or regulatory significance. -# Coverage +## Coverage From 604ce90bd513d40f0dc47ee935d1a326da13ead9 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:42:34 +0000 Subject: [PATCH 16/40] update --- codecov.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/codecov.yml b/codecov.yml index 896ea35c1..c8f7db32b 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,3 +1,6 @@ +ignore: + - "test" + - "script" comment: layout: "reach, diff, flags, files" behavior: default From 7144f16472854de70dc6f174f954a53169050672 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 11:42:56 +0000 Subject: [PATCH 17/40] fix --- .github/workflows/coverage.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 99f6b3885..7f97731c2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -27,9 +27,7 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 - name: Run coverage - run: | - forge coverage --report lcov - lcov --remove lcov.info 'test/*' 'script/*' > lcov.info + run: forge coverage --report lcov - name: Upload to codecov uses: codecov/codecov-action@v3 From 2259cb300215c8d7c32909a6274ae1da686e1eeb Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 15:58:08 +0000 Subject: [PATCH 18/40] update --- .github/workflows/coverage.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7f97731c2..f917937a9 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -27,7 +27,10 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 - name: Run coverage - run: forge coverage --report lcov + run: | + forge coverage --report lcov + sudo apt-get install lcov + lcov --remove lcov.info -o lcov.info 'test/*' 'script/*' - name: Upload to codecov uses: codecov/codecov-action@v3 From 52f9b898e35169536c4d3f653ca336ef03122a09 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 16:08:59 +0000 Subject: [PATCH 19/40] linting --- codecov.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codecov.yml b/codecov.yml index c8f7db32b..0e6c77b56 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,6 +1,6 @@ ignore: - - "test" - - "script" + - "test" + - "script" comment: layout: "reach, diff, flags, files" behavior: default From 866189a1310e3e185efeb4cb8ef8a45d74ec870c Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 16:33:47 +0000 Subject: [PATCH 20/40] update --- codecov.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codecov.yml b/codecov.yml index 0e6c77b56..eec775e9d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -7,3 +7,5 @@ comment: require_changes: false require_base: no require_head: yes +codecov: + bot: "Padraic-O-Mhuiris" From 22bc7663d835544b1c0b48b80cf10252b4c707e7 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 16:39:19 +0000 Subject: [PATCH 21/40] use coveralls instead of codecov --- .github/workflows/coverage.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index f917937a9..1340c5cb1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,4 +1,4 @@ -on: [push] +on: ["push", "pull_request"] name: hyperdrive @@ -32,10 +32,8 @@ jobs: sudo apt-get install lcov lcov --remove lcov.info -o lcov.info 'test/*' 'script/*' - - name: Upload to codecov - uses: codecov/codecov-action@v3 + - name: Coveralls + uses: coverallsapp/github-action@master with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./lcov.info - fail_ci_if_error: true - verbose: true + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: "./lcov.info" From 85d5470eb6399209ba779b4f39b710a87ddf9f28 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 16:41:01 +0000 Subject: [PATCH 22/40] update --- .github/workflows/coverage.yml | 2 +- codecov.yml | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 codecov.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1340c5cb1..45a452f7e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,4 +1,4 @@ -on: ["push", "pull_request"] +on: [push] name: hyperdrive diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index eec775e9d..000000000 --- a/codecov.yml +++ /dev/null @@ -1,11 +0,0 @@ -ignore: - - "test" - - "script" -comment: - layout: "reach, diff, flags, files" - behavior: default - require_changes: false - require_base: no - require_head: yes -codecov: - bot: "Padraic-O-Mhuiris" From 4172cf886c68088e46fbea733489670df9c07bc0 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 16:46:20 +0000 Subject: [PATCH 23/40] test --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 13b1ecd58..3e5419a8f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![codecov](https://codecov.io/gh/element-fi/hyperdrive/branch/main/graph/badge.svg?token=I35ZGDABCS)](https://codecov.io/gh/element-fi/hyperdrive) +[![Coverage Status](https://coveralls.io/repos/github/element-fi/hyperdrive/badge.svg?branch=via-ir-2&t=US78Aq)](https://coveralls.io/github/element-fi/hyperdrive?branch=via-ir-2) # Hyperdrive @@ -36,9 +36,3 @@ If you want to automatically format the code, run `yarn prettier`. The language used in this codebase is for coding convenience only, and is not intended to, and does not, have any particular legal or regulatory significance. - -## Coverage - - - - From 60935a07f31d8d5f84312250046508f3f20b5bd8 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 16:53:28 +0000 Subject: [PATCH 24/40] update --- .github/workflows/coverage.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 45a452f7e..25714fd73 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -3,7 +3,7 @@ on: [push] name: hyperdrive jobs: - check: + test: name: coverage runs-on: ubuntu-latest steps: @@ -37,3 +37,14 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: "./lcov.info" + parallel: true + + finish: + needs: test + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true From 96889da1f0d19b609bd1f64147723f33abf5a163 Mon Sep 17 00:00:00 2001 From: padraic Date: Fri, 10 Feb 2023 16:55:13 +0000 Subject: [PATCH 25/40] fix --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 25714fd73..171d0fa6e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -46,5 +46,5 @@ jobs: - name: Coveralls Finished uses: coverallsapp/github-action@master with: - github-token: ${{ secrets.github_token }} + github-token: ${{ secrets.GITHUB_TOKEN }} parallel-finished: true From 1e7af2812de7f26e5f0d767b93904a21587e6791 Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 15:17:15 +0000 Subject: [PATCH 26/40] add comments to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7ce3c7dc4..5adde47b4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ forge-cache/ node_modules/ yarn-error.log +# nix/shell extension - https://direnv.net/ .direnv +# code coverage lcov.info From d2d8e499a93d8bfbd4980cff2484b679efdffba0 Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 15:21:49 +0000 Subject: [PATCH 27/40] fix coverage badge link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e5419a8f..47e6292dd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Coverage Status](https://coveralls.io/repos/github/element-fi/hyperdrive/badge.svg?branch=via-ir-2&t=US78Aq)](https://coveralls.io/github/element-fi/hyperdrive?branch=via-ir-2) +[![Coverage Status](https://coveralls.io/repos/github/element-fi/hyperdrive/badge.svg?t=US78Aq)](https://coveralls.io/github/element-fi/hyperdrive) # Hyperdrive From 7ce781f43c250cfe86650370edf07494cfaa8a2c Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 15:26:44 +0000 Subject: [PATCH 28/40] add test badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 47e6292dd..5a6ea4b94 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![Coverage Status](https://coveralls.io/repos/github/element-fi/hyperdrive/badge.svg?t=US78Aq)](https://coveralls.io/github/element-fi/hyperdrive) +[![Tests](https://github.com/element-fi/hyperdrive/actions/workflows/test.yml/badge.svg)](https://github.com/element-fi/hyperdrive/actions/workflows/test.yml) +[![Coverage](https://coveralls.io/repos/github/element-fi/hyperdrive/badge.svg?t=US78Aq)](https://coveralls.io/github/element-fi/hyperdrive) # Hyperdrive From a0de0f452ad7ad52e9442ac988d04993b12d3147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draic=20=C3=93=20Mhuiris?= Date: Mon, 13 Feb 2023 15:28:53 +0000 Subject: [PATCH 29/40] Update contracts/libraries/HyperdriveMath.sol Co-authored-by: Alex Towle --- contracts/libraries/HyperdriveMath.sol | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contracts/libraries/HyperdriveMath.sol b/contracts/libraries/HyperdriveMath.sol index 9e46ac0b1..8e0a27993 100644 --- a/contracts/libraries/HyperdriveMath.sol +++ b/contracts/libraries/HyperdriveMath.sol @@ -134,11 +134,13 @@ library HyperdriveMath { // YieldSpace curve configured to timeRemaining = 1. uint256 curveIn = _amountIn.mulDown(_timeRemaining); - // Credit the share reserves by the flat trade. + // TODO: Revisit this assumption. It seems like LPs can bake this into the + // fee schedule rather than adding a hidden fee. + // + // Calculate the curved part of the trade assuming that the flat part of + // the trade was applied to the share and bond reserves. _shareReserves = _shareReserves.add(flat); - // Debit the bond reserves by the flat trade. _bondReserves = _bondReserves.sub(flat.mulDown(_sharePrice)); - uint256 curveOut = YieldSpaceMath.calculateOutGivenIn( _shareReserves, _bondReserves, From b860fc620cd7bf5a4da4eb6d43c6985591bcb3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draic=20=C3=93=20Mhuiris?= Date: Mon, 13 Feb 2023 15:29:02 +0000 Subject: [PATCH 30/40] Update contracts/libraries/HyperdriveMath.sol Co-authored-by: Alex Towle --- contracts/libraries/HyperdriveMath.sol | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contracts/libraries/HyperdriveMath.sol b/contracts/libraries/HyperdriveMath.sol index 8e0a27993..412963c71 100644 --- a/contracts/libraries/HyperdriveMath.sol +++ b/contracts/libraries/HyperdriveMath.sol @@ -168,11 +168,13 @@ library HyperdriveMath { _sharePrice ); - // Debit the share reserves by the flat trade. + // TODO: Revisit this assumption. It seems like LPs can bake this into the + // fee schedule rather than adding a hidden fee. + // + // Calculate the curved part of the trade assuming that the flat part of + // the trade was applied to the share and bond reserves. _shareReserves = _shareReserves.sub(flat); - // Credit the bond reserves by the flat trade. _bondReserves = _bondReserves.add(flat.mulDown(_sharePrice)); - uint256 curveOut = YieldSpaceMath.calculateOutGivenIn( _shareReserves, _bondReserves, From da99d3c74322b48784dcf1caa527db1e2ca9042c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draic=20=C3=93=20Mhuiris?= Date: Mon, 13 Feb 2023 15:29:14 +0000 Subject: [PATCH 31/40] Update contracts/libraries/HyperdriveMath.sol Co-authored-by: Alex Towle --- contracts/libraries/HyperdriveMath.sol | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/contracts/libraries/HyperdriveMath.sol b/contracts/libraries/HyperdriveMath.sol index 412963c71..3bfb0dbcc 100644 --- a/contracts/libraries/HyperdriveMath.sol +++ b/contracts/libraries/HyperdriveMath.sol @@ -241,9 +241,12 @@ library HyperdriveMath { _sharePrice ); - // Credit the share reserves by the flat trade. + // TODO: Revisit this assumption. It seems like LPs can bake this into the + // fee schedule rather than adding a hidden fee. + // + // Calculate the curved part of the trade assuming that the flat part of + // the trade was applied to the share and bond reserves. _shareReserves = _shareReserves.add(flat); - // Debit the bond reserves by the flat trade. _bondReserves = _bondReserves.sub(flat.mulDown(_sharePrice)); uint256 curveIn = YieldSpaceMath.calculateInGivenOut( _shareReserves, From c92173c79614214c27f4711476a5e63dee741bb0 Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 15:46:12 +0000 Subject: [PATCH 32/40] relabel parameters in consistency with HyperdriveMath --- contracts/libraries/YieldSpaceMath.sol | 170 ++++++++++++++----------- 1 file changed, 98 insertions(+), 72 deletions(-) diff --git a/contracts/libraries/YieldSpaceMath.sol b/contracts/libraries/YieldSpaceMath.sol index 78caf88ab..f74094609 100644 --- a/contracts/libraries/YieldSpaceMath.sol +++ b/contracts/libraries/YieldSpaceMath.sol @@ -15,100 +15,126 @@ library YieldSpaceMath { using FixedPointMath for uint256; /// Calculates the amount of bond a user would get for given amount of shares. - /// @param shareReserves yield bearing vault shares reserve amount, unit is shares - /// @param bondReserves bond reserves amount, unit is the face value in underlying - /// @param bondReserveAdjustment An optional adjustment to the reserve which MUST have units of underlying. - /// @param amountIn amount to be traded, if bonds in the unit is underlying, if shares in the unit is shares - /// @param oneMinusT 1 - st - /// @param c price of shares in terms of their base - /// @param mu Normalization factor -- starts as c at initialization - /// @param isBondOut determines if the output is bond or shares - /// @return result the amount of shares a user would get for given amount of bond + /// @param _shareReserves yield bearing vault shares reserve amount, unit is shares + /// @param _bondReserves bond reserves amount, unit is the face value in underlying + /// @param _bondReserveAdjustment An optional adjustment to the reserve which MUST have units of underlying. + /// @param _amountIn amount to be traded, if bonds in the unit is underlying, if shares in the unit is shares + /// @param _stretchedTimeElapsed Amount of time elapsed since term start + /// @param _c price of shares in terms of their base + /// @param _mu Normalization factor -- starts as c at initialization + /// @param _isBondOut determines if the output is bond or shares + /// @return Amount of shares a user would get for given amount of bond function calculateOutGivenIn( - uint256 shareReserves, - uint256 bondReserves, - uint256 bondReserveAdjustment, - uint256 amountIn, - uint256 oneMinusT, - uint256 c, - uint256 mu, - bool isBondOut + uint256 _shareReserves, + uint256 _bondReserves, + uint256 _bondReserveAdjustment, + uint256 _amountIn, + uint256 _stretchedTimeElapsed, + uint256 _c, + uint256 _mu, + bool _isBondOut ) internal pure returns (uint256) { - uint256 cDivMu = c.divDown(mu); - bondReserves = bondReserves.add(bondReserveAdjustment); - uint256 k = _k(cDivMu, mu, shareReserves, oneMinusT, bondReserves); - if (isBondOut) { - shareReserves = mu.mulDown(shareReserves.add(amountIn)).pow( - oneMinusT + uint256 cDivMu = _c.divDown(_mu); + _bondReserves = _bondReserves.add(_bondReserveAdjustment); + uint256 k = _k( + cDivMu, + _mu, + _shareReserves, + _stretchedTimeElapsed, + _bondReserves + ); + if (_isBondOut) { + _shareReserves = _mu.mulDown(_shareReserves.add(_amountIn)).pow( + _stretchedTimeElapsed ); - shareReserves = cDivMu.mulDown(shareReserves); - uint256 rhs = k.sub(shareReserves).pow( - FixedPointMath.ONE_18.divDown(oneMinusT) + _shareReserves = cDivMu.mulDown(_shareReserves); + uint256 rhs = k.sub(_shareReserves).pow( + FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - return bondReserves.sub(rhs); + return _bondReserves.sub(rhs); } else { - bondReserves = bondReserves.add(amountIn).pow(oneMinusT); - uint256 rhs = k.sub(bondReserves).divDown(cDivMu).pow( - FixedPointMath.ONE_18.divDown(oneMinusT) + _bondReserves = _bondReserves.add(_amountIn).pow( + _stretchedTimeElapsed ); - rhs = rhs.divDown(mu); - return shareReserves.sub(rhs); + uint256 rhs = k.sub(_bondReserves).divDown(cDivMu).pow( + FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) + ); + rhs = rhs.divDown(_mu); + return _shareReserves.sub(rhs); } } /// @dev Calculates the amount of an asset that will be received given a /// specified amount of the other asset given the current AMM reserves. - /// @param shareReserves yield bearing vault shares reserve amount, unit is shares - /// @param bondReserves bond reserves amount, unit is the face value in underlying - /// @param bondReserveAdjustment An optional adjustment to the reserve which MUST have units of underlying. - /// @param amountOut amount to be received, if bonds in the unit is underlying, if shares in the unit is shares - /// @param oneMinusT 1 - st - /// @param c price of shares in terms of their base - /// @param mu Normalization factor -- starts as c at initialization - /// @param isBondIn determines if the input is bond or shares - /// @return result the amount of shares a user would get for given amount of bond + /// @param _shareReserves yield bearing vault shares reserve amount, unit is shares + /// @param _bondReserves bond reserves amount, unit is the face value in underlying + /// @param _bondReserveAdjustment An optional adjustment to the reserve which MUST have units of underlying. + /// @param _amountOut amount to be received, if bonds in the unit is underlying, if shares in the unit is shares + /// @param _stretchedTimeElapsed Amount of time elapsed since term start + /// @param _c price of shares in terms of their base + /// @param _mu Normalization factor -- starts as c at initialization + /// @param _isBondIn determines if the input is bond or shares + /// @return Amount of shares a user would get for given amount of bond function calculateInGivenOut( - uint256 shareReserves, - uint256 bondReserves, - uint256 bondReserveAdjustment, - uint256 amountOut, - uint256 oneMinusT, - uint256 c, - uint256 mu, - bool isBondIn + uint256 _shareReserves, + uint256 _bondReserves, + uint256 _bondReserveAdjustment, + uint256 _amountOut, + uint256 _stretchedTimeElapsed, + uint256 _c, + uint256 _mu, + bool _isBondIn ) internal pure returns (uint256) { - uint256 cDivMu = c.divDown(mu); - bondReserves = bondReserves.add(bondReserveAdjustment); - uint256 k = _k(cDivMu, mu, shareReserves, oneMinusT, bondReserves); - if (isBondIn) { - shareReserves = mu.mulDown(shareReserves.sub(amountOut)).pow( - oneMinusT + uint256 cDivMu = _c.divDown(_mu); + _bondReserves = _bondReserves.add(_bondReserveAdjustment); + uint256 k = _k( + cDivMu, + _mu, + _shareReserves, + _stretchedTimeElapsed, + _bondReserves + ); + if (_isBondIn) { + _shareReserves = _mu.mulDown(_shareReserves.sub(_amountOut)).pow( + _stretchedTimeElapsed ); - shareReserves = cDivMu.mulDown(shareReserves); - uint256 rhs = k.sub(shareReserves).pow( - FixedPointMath.ONE_18.divDown(oneMinusT) + _shareReserves = cDivMu.mulDown(_shareReserves); + uint256 rhs = k.sub(_shareReserves).pow( + FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - return rhs.sub(bondReserves); + return rhs.sub(_bondReserves); } else { - bondReserves = bondReserves.sub(amountOut).pow(oneMinusT); - uint256 rhs = k.sub(bondReserves).divDown(cDivMu).pow( - FixedPointMath.ONE_18.divDown(oneMinusT) + _bondReserves = _bondReserves.sub(_amountOut).pow( + _stretchedTimeElapsed + ); + uint256 rhs = k.sub(_bondReserves).divDown(cDivMu).pow( + FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - rhs = rhs.divDown(mu); - return rhs.sub(shareReserves); + rhs = rhs.divDown(_mu); + return rhs.sub(_shareReserves); } } + /// @dev Helper function + /// + /// ( + /// c/mu + /// * (mu*shareReserves)^(1-t) + /// + bondReserves^(1-t) + /// - c/mu + /// * (mu*(shareReserves + amountIn))^(1-t) )^(1 / (1 - t) + /// ) + /// returns k function _k( - uint256 cDivMu, - uint256 mu, - uint256 shareReserves, - uint256 oneMinusT, - uint256 modifiedBondReserves + uint256 _cDivMu, + uint256 _mu, + uint256 _shareReserves, + uint256 _stretchedTimeElapsed, + uint256 _bondReserves ) private pure returns (uint256) { return - cDivMu.mulDown(mu.mulDown(shareReserves).pow(oneMinusT)).add( - modifiedBondReserves.pow(oneMinusT) - ); + _cDivMu + .mulDown(_mu.mulDown(_shareReserves).pow(_stretchedTimeElapsed)) + .add(_bondReserves.pow(_stretchedTimeElapsed)); } } From 3495bbca3bcd39643ed7d36e34e6606a4456e808 Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 15:59:16 +0000 Subject: [PATCH 33/40] added comments for _k --- contracts/libraries/YieldSpaceMath.sol | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/contracts/libraries/YieldSpaceMath.sol b/contracts/libraries/YieldSpaceMath.sol index f74094609..c8530866e 100644 --- a/contracts/libraries/YieldSpaceMath.sol +++ b/contracts/libraries/YieldSpaceMath.sol @@ -34,7 +34,10 @@ library YieldSpaceMath { uint256 _mu, bool _isBondOut ) internal pure returns (uint256) { + // c / mu uint256 cDivMu = _c.divDown(_mu); + // Adjust the bond reserve, optionally shifts the curve around the + // inflection point _bondReserves = _bondReserves.add(_bondReserveAdjustment); uint256 k = _k( cDivMu, @@ -115,15 +118,15 @@ library YieldSpaceMath { } } - /// @dev Helper function + /// @dev Helper function to derive invariant constant k /// - /// ( - /// c/mu - /// * (mu*shareReserves)^(1-t) - /// + bondReserves^(1-t) - /// - c/mu - /// * (mu*(shareReserves + amountIn))^(1-t) )^(1 / (1 - t) - /// ) + /// k = c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) + /// + /// @param _cDivMu Normalized price of shares in terms of base + /// @param _mu Normalization factor -- starts as c at initialization + /// @param _shareReserves Yield bearing vault shares reserve amount, unit is shares + /// @param _stretchedTimeElapsed Amount of time elapsed since term start + /// @param _bondReserves Bond reserves amount, unit is the face value in underlying /// returns k function _k( uint256 _cDivMu, From 5612bfba5564de507a503c4e1664d2669759f3bb Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 20:56:30 +0000 Subject: [PATCH 34/40] add comments back in --- contracts/libraries/YieldSpaceMath.sol | 57 +++++++++++++++++++------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/contracts/libraries/YieldSpaceMath.sol b/contracts/libraries/YieldSpaceMath.sol index c8530866e..988641022 100644 --- a/contracts/libraries/YieldSpaceMath.sol +++ b/contracts/libraries/YieldSpaceMath.sol @@ -23,7 +23,7 @@ library YieldSpaceMath { /// @param _c price of shares in terms of their base /// @param _mu Normalization factor -- starts as c at initialization /// @param _isBondOut determines if the output is bond or shares - /// @return Amount of shares a user would get for given amount of bond + /// @return Amount of shares/bonds function calculateOutGivenIn( uint256 _shareReserves, uint256 _bondReserves, @@ -39,6 +39,7 @@ library YieldSpaceMath { // Adjust the bond reserve, optionally shifts the curve around the // inflection point _bondReserves = _bondReserves.add(_bondReserveAdjustment); + // (c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) uint256 k = _k( cDivMu, _mu, @@ -46,24 +47,37 @@ library YieldSpaceMath { _stretchedTimeElapsed, _bondReserves ); + if (_isBondOut) { + // (mu * (shareReserves + amountIn))^(1-t) _shareReserves = _mu.mulDown(_shareReserves.add(_amountIn)).pow( _stretchedTimeElapsed ); + // (c / mu) * (mu * (shareReserves + amountIn))^(1-t) _shareReserves = cDivMu.mulDown(_shareReserves); - uint256 rhs = k.sub(_shareReserves).pow( + // NOTE: k - shareReserves >= 0 to avoid a complex number + // ((c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu*(shareReserves + amountIn))^(1-t))^(1 / (1 - t)) + uint256 newBondReserves = k.sub(_shareReserves).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - return _bondReserves.sub(rhs); + // NOTE: bondReserves - newBondReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens + // bondsOut = bondReserves - ( (c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu*(shareReserves + shareIn))^(1-t))^(1 / (1 - t)) + return _bondReserves.sub(newBondReserves); } else { + // (bondReserves + amountIn)^(1-t) _bondReserves = _bondReserves.add(_amountIn).pow( _stretchedTimeElapsed ); - uint256 rhs = k.sub(_bondReserves).divDown(cDivMu).pow( + // NOTE: k - bondReserves >= 0 to avoid a complex number + // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + amountIn)^(1-t)) / (c / mu))^(1 / (1 - t)) + uint256 newShareReserves = k.sub(_bondReserves).divDown(cDivMu).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - rhs = rhs.divDown(_mu); - return _shareReserves.sub(rhs); + // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + bondIn)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu + newShareReserves = newShareReserves.divDown(_mu); + // NOTE: shareReserves - sharesOut >= 0, but I think avoiding a complex number in the step above ensures this never happens + // sharesOut = shareReserves - (((c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + bondIn)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu + return _shareReserves.sub(newShareReserves); } } @@ -77,7 +91,7 @@ library YieldSpaceMath { /// @param _c price of shares in terms of their base /// @param _mu Normalization factor -- starts as c at initialization /// @param _isBondIn determines if the input is bond or shares - /// @return Amount of shares a user would get for given amount of bond + /// @return Amount of shares/bonds function calculateInGivenOut( uint256 _shareReserves, uint256 _bondReserves, @@ -88,8 +102,11 @@ library YieldSpaceMath { uint256 _mu, bool _isBondIn ) internal pure returns (uint256) { + // c / mu uint256 cDivMu = _c.divDown(_mu); + // Adjust the bond reserve, optionally shifts the curve around the inflection point _bondReserves = _bondReserves.add(_bondReserveAdjustment); + // (c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) uint256 k = _k( cDivMu, _mu, @@ -98,30 +115,39 @@ library YieldSpaceMath { _bondReserves ); if (_isBondIn) { + // (mu * (shareReserves - amountOut))^(1-t) _shareReserves = _mu.mulDown(_shareReserves.sub(_amountOut)).pow( _stretchedTimeElapsed ); + // (c / mu) * (mu*(shareReserves - amountOut))^(1-t) _shareReserves = cDivMu.mulDown(_shareReserves); - uint256 rhs = k.sub(_shareReserves).pow( + // NOTE: k - shareReserves >= 0 to avoid a complex number + // ((c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu*(shareReserves - amountOut))^(1-t))^(1 / (1 - t)) + uint256 newBondReserves = k.sub(_shareReserves).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - return rhs.sub(_bondReserves); + // NOTE: newBondReserves - bondReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens + // bondIn = ((c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu * (shareReserves - shareOut))^(1-t))^(1 / (1 - t)) - bondReserves + return newBondReserves.sub(_bondReserves); } else { + // (bondReserves - amountOut)^(1-t) _bondReserves = _bondReserves.sub(_amountOut).pow( _stretchedTimeElapsed ); - uint256 rhs = k.sub(_bondReserves).divDown(cDivMu).pow( + // NOTE: k - newScaledBondReserves >= 0 to avoid a complex number + // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - amountOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) + uint256 newShareReserves = k.sub(_bondReserves).divDown(cDivMu).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - rhs = rhs.divDown(_mu); - return rhs.sub(_shareReserves); + // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - amountOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu + newShareReserves = rhs.divDown(_mu); + // NOTE: newShareReserves - shareReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens + // sharesIn = (((c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - bondOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu - shareReserves + return newShareReserves.sub(_shareReserves); } } /// @dev Helper function to derive invariant constant k - /// - /// k = c/mu * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - /// /// @param _cDivMu Normalized price of shares in terms of base /// @param _mu Normalization factor -- starts as c at initialization /// @param _shareReserves Yield bearing vault shares reserve amount, unit is shares @@ -135,6 +161,7 @@ library YieldSpaceMath { uint256 _stretchedTimeElapsed, uint256 _bondReserves ) private pure returns (uint256) { + /// k = (c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) return _cDivMu .mulDown(_mu.mulDown(_shareReserves).pow(_stretchedTimeElapsed)) From e99dc4ee09c0dbcfff14e2c65b7479e54487473f Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 20:59:40 +0000 Subject: [PATCH 35/40] prettier --- contracts/libraries/HyperdriveMath.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/libraries/HyperdriveMath.sol b/contracts/libraries/HyperdriveMath.sol index 3bfb0dbcc..50e0bd04a 100644 --- a/contracts/libraries/HyperdriveMath.sol +++ b/contracts/libraries/HyperdriveMath.sol @@ -134,10 +134,10 @@ library HyperdriveMath { // YieldSpace curve configured to timeRemaining = 1. uint256 curveIn = _amountIn.mulDown(_timeRemaining); - // TODO: Revisit this assumption. It seems like LPs can bake this into the + // TODO: Revisit this assumption. It seems like LPs can bake this into the // fee schedule rather than adding a hidden fee. // - // Calculate the curved part of the trade assuming that the flat part of + // Calculate the curved part of the trade assuming that the flat part of // the trade was applied to the share and bond reserves. _shareReserves = _shareReserves.add(flat); _bondReserves = _bondReserves.sub(flat.mulDown(_sharePrice)); @@ -168,10 +168,10 @@ library HyperdriveMath { _sharePrice ); - // TODO: Revisit this assumption. It seems like LPs can bake this into the + // TODO: Revisit this assumption. It seems like LPs can bake this into the // fee schedule rather than adding a hidden fee. // - // Calculate the curved part of the trade assuming that the flat part of + // Calculate the curved part of the trade assuming that the flat part of // the trade was applied to the share and bond reserves. _shareReserves = _shareReserves.sub(flat); _bondReserves = _bondReserves.add(flat.mulDown(_sharePrice)); @@ -241,10 +241,10 @@ library HyperdriveMath { _sharePrice ); - // TODO: Revisit this assumption. It seems like LPs can bake this into the + // TODO: Revisit this assumption. It seems like LPs can bake this into the // fee schedule rather than adding a hidden fee. // - // Calculate the curved part of the trade assuming that the flat part of + // Calculate the curved part of the trade assuming that the flat part of // the trade was applied to the share and bond reserves. _shareReserves = _shareReserves.add(flat); _bondReserves = _bondReserves.sub(flat.mulDown(_sharePrice)); From 30e8a1c577b3b70840fd7c42815a1daa5c126415 Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 21:01:36 +0000 Subject: [PATCH 36/40] fix --- contracts/libraries/YieldSpaceMath.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/libraries/YieldSpaceMath.sol b/contracts/libraries/YieldSpaceMath.sol index 988641022..724b31eee 100644 --- a/contracts/libraries/YieldSpaceMath.sol +++ b/contracts/libraries/YieldSpaceMath.sol @@ -140,7 +140,7 @@ library YieldSpaceMath { FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - amountOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu - newShareReserves = rhs.divDown(_mu); + newShareReserves = newShareReserves.divDown(_mu); // NOTE: newShareReserves - shareReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens // sharesIn = (((c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - bondOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu - shareReserves return newShareReserves.sub(_shareReserves); From 749d0e0481762cb8501c0e917d936d4bb39688f2 Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 21:17:01 +0000 Subject: [PATCH 37/40] workflows --- .github/workflows/coverage.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 171d0fa6e..815f236ed 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,4 +1,4 @@ -on: [push] +on: ["push", "pull_request"] name: hyperdrive diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 805c7f4d9..cf523f2df 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,4 @@ -on: [push] +on: ["push", "pull_request"] name: hyperdrive diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3dfccffcf..ebcd80cd3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -on: [push] +on: ["push", "pull_request"] name: hyperdrive From 396e2b80cd1afd266a8f8df2a68eaf4f76a727e3 Mon Sep 17 00:00:00 2001 From: padraic Date: Mon, 13 Feb 2023 21:22:44 +0000 Subject: [PATCH 38/40] calculateOutGivenIn tests --- test/YieldSpaceMath.t.sol | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/YieldSpaceMath.t.sol b/test/YieldSpaceMath.t.sol index 66ad5872b..5a49d0726 100644 --- a/test/YieldSpaceMath.t.sol +++ b/test/YieldSpaceMath.t.sol @@ -5,30 +5,28 @@ import { Test } from "forge-std/Test.sol"; import { YieldSpaceMath } from "contracts/libraries/YieldSpaceMath.sol"; contract YieldSpaceMathTest is Test { - function test__calculateOutGivenIn_1() public { + function test__calculateOutGivenIn() public { assertEq( YieldSpaceMath.calculateOutGivenIn( 56.79314253e18, // shareReserves 62.38101813e18, // bondReserves 119.1741606776616e18, // bondReserveAdjustment 5.03176076e18, // amountOut - 1e18 - 0.08065076081220067e18, // t + 1e18 - 0.08065076081220067e18, // stretchedTimeElapsed 1e18, // c 1e18, // mu true // isBondIn ), 5.500250311701939082e18 ); - } - function test__calculateOutGivenIn_2() public { assertEq( YieldSpaceMath.calculateOutGivenIn( 61.824903300361854e18, // shareReserves 56.92761678068477e18, // bondReserves 119.1741606776616e18, // bondReserveAdjustment 5.500250311701939e18, // amountOut - 1e18 - 0.08065076081220067e18, // t + 1e18 - 0.08065076081220067e18, // stretchedTimeElapsed 1e18, // c 1e18, // mu false // isBondIn From 969eb01778a6920a45dcf82bb549766496ccfb03 Mon Sep 17 00:00:00 2001 From: padraic Date: Tue, 14 Feb 2023 15:59:38 +0000 Subject: [PATCH 39/40] use tau instead of t --- contracts/libraries/YieldSpaceMath.sol | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/contracts/libraries/YieldSpaceMath.sol b/contracts/libraries/YieldSpaceMath.sol index 724b31eee..04153fe62 100644 --- a/contracts/libraries/YieldSpaceMath.sol +++ b/contracts/libraries/YieldSpaceMath.sol @@ -39,7 +39,7 @@ library YieldSpaceMath { // Adjust the bond reserve, optionally shifts the curve around the // inflection point _bondReserves = _bondReserves.add(_bondReserveAdjustment); - // (c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) + // (c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) uint256 k = _k( cDivMu, _mu, @@ -49,34 +49,34 @@ library YieldSpaceMath { ); if (_isBondOut) { - // (mu * (shareReserves + amountIn))^(1-t) + // (mu * (shareReserves + amountIn))^(1 - tau) _shareReserves = _mu.mulDown(_shareReserves.add(_amountIn)).pow( _stretchedTimeElapsed ); - // (c / mu) * (mu * (shareReserves + amountIn))^(1-t) + // (c / mu) * (mu * (shareReserves + amountIn))^(1 - tau) _shareReserves = cDivMu.mulDown(_shareReserves); // NOTE: k - shareReserves >= 0 to avoid a complex number - // ((c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu*(shareReserves + amountIn))^(1-t))^(1 / (1 - t)) + // ((c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (c / mu) * (mu * (shareReserves + amountIn))^(1 - tau))^(1 / (1 - tau))) uint256 newBondReserves = k.sub(_shareReserves).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); // NOTE: bondReserves - newBondReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens - // bondsOut = bondReserves - ( (c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu*(shareReserves + shareIn))^(1-t))^(1 / (1 - t)) + // bondsOut = bondReserves - ( (c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (c / mu) * (mu * (shareReserves + shareIn))^(1 - tau))^(1 / (1 - tau))) return _bondReserves.sub(newBondReserves); } else { - // (bondReserves + amountIn)^(1-t) + // (bondReserves + amountIn)^(1 - tau) _bondReserves = _bondReserves.add(_amountIn).pow( _stretchedTimeElapsed ); // NOTE: k - bondReserves >= 0 to avoid a complex number - // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + amountIn)^(1-t)) / (c / mu))^(1 / (1 - t)) + // (((mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (bondReserves + amountIn)^(1 - tau)) / (c / mu))^(1 / (1 - tau))) uint256 newShareReserves = k.sub(_bondReserves).divDown(cDivMu).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + bondIn)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu + // (((mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (bondReserves + bondIn)^(1 - tau) ) / (c / mu))^(1 / (1 - tau))) / mu newShareReserves = newShareReserves.divDown(_mu); // NOTE: shareReserves - sharesOut >= 0, but I think avoiding a complex number in the step above ensures this never happens - // sharesOut = shareReserves - (((c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves + bondIn)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu + // sharesOut = shareReserves - (((c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (bondReserves + bondIn)^(1 - tau) ) / (c / mu))^(1 / (1 - tau))) / mu return _shareReserves.sub(newShareReserves); } } @@ -106,7 +106,7 @@ library YieldSpaceMath { uint256 cDivMu = _c.divDown(_mu); // Adjust the bond reserve, optionally shifts the curve around the inflection point _bondReserves = _bondReserves.add(_bondReserveAdjustment); - // (c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) + // (c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) uint256 k = _k( cDivMu, _mu, @@ -115,34 +115,34 @@ library YieldSpaceMath { _bondReserves ); if (_isBondIn) { - // (mu * (shareReserves - amountOut))^(1-t) + // (mu * (shareReserves - amountOut))^(1 - tau) _shareReserves = _mu.mulDown(_shareReserves.sub(_amountOut)).pow( _stretchedTimeElapsed ); - // (c / mu) * (mu*(shareReserves - amountOut))^(1-t) + // (c / mu) * (mu * (shareReserves - amountOut))^(1 - tau) _shareReserves = cDivMu.mulDown(_shareReserves); // NOTE: k - shareReserves >= 0 to avoid a complex number - // ((c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu*(shareReserves - amountOut))^(1-t))^(1 / (1 - t)) + // ((c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (c / mu) * (mu*(shareReserves - amountOut))^(1 - tau))^(1 / (1 - tau))) uint256 newBondReserves = k.sub(_shareReserves).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); // NOTE: newBondReserves - bondReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens - // bondIn = ((c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (c / mu) * (mu * (shareReserves - shareOut))^(1-t))^(1 / (1 - t)) - bondReserves + // bondIn = ((c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (c / mu) * (mu * (shareReserves - shareOut))^(1 - tau))^(1 / (1 - tau))) - bondReserves return newBondReserves.sub(_bondReserves); } else { - // (bondReserves - amountOut)^(1-t) + // (bondReserves - amountOut)^(1 - tau) _bondReserves = _bondReserves.sub(_amountOut).pow( _stretchedTimeElapsed ); // NOTE: k - newScaledBondReserves >= 0 to avoid a complex number - // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - amountOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) + // (((mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (bondReserves - amountOut)^(1 - tau) ) / (c / mu))^(1 / (1 - tau))) uint256 newShareReserves = k.sub(_bondReserves).divDown(cDivMu).pow( FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed) ); - // (((mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - amountOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu + // (((mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (bondReserves - amountOut)^(1 - tau) ) / (c / mu))^(1 / (1 - tau))) / mu newShareReserves = newShareReserves.divDown(_mu); // NOTE: newShareReserves - shareReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens - // sharesIn = (((c / mu) * (mu * shareReserves)^(1-t) + bondReserves^(1-t) - (bondReserves - bondOut)^(1-t) ) / (c / mu))^(1 / (1 - t)) / mu - shareReserves + // sharesIn = (((c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (bondReserves - bondOut)^(1 - tau) ) / (c / mu))^(1 / (1 - tau))) / mu - shareReserves return newShareReserves.sub(_shareReserves); } } @@ -161,7 +161,7 @@ library YieldSpaceMath { uint256 _stretchedTimeElapsed, uint256 _bondReserves ) private pure returns (uint256) { - /// k = (c / mu) * (mu*shareReserves)^(1-t) + bondReserves^(1-t) + /// k = (c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) return _cDivMu .mulDown(_mu.mulDown(_shareReserves).pow(_stretchedTimeElapsed)) From d793f998218470a453a09bfb31ac622f6dae849c Mon Sep 17 00:00:00 2001 From: padraic Date: Tue, 14 Feb 2023 16:03:38 +0000 Subject: [PATCH 40/40] update flake --- flake.lock | 13 ++++++------- flake.nix | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index 69cc47dfe..8f52bb094 100644 --- a/flake.lock +++ b/flake.lock @@ -21,16 +21,15 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1672936714, - "narHash": "sha256-MaW0kIQH9Ns17vYGsUBYGkdR6GYCLd0Rzjznf0zUsVU=", + "lastModified": 1676365777, + "narHash": "sha256-vtZFb/F01q2CqogrWaIEv//g3Dm6R3QuuTKS+TrbSTo=", "owner": "shazow", "repo": "foundry.nix", - "rev": "e1a08c5650e0aa82b5de659827a8881b1ff79e55", + "rev": "b3ff192f7e19785781670f7d2365bb0ad097116d", "type": "github" }, "original": { "owner": "shazow", - "ref": "monthly", "repo": "foundry.nix", "type": "github" } @@ -74,11 +73,11 @@ }, "utils": { "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1676283394, + "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 41f94c930..f3dbc7553 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11"; utils.url = "github:numtide/flake-utils"; - foundry.url = "github:shazow/foundry.nix/monthly"; + foundry.url = "github:shazow/foundry.nix"; }; outputs = inputs@{ self, nixpkgs, foundry, utils }: utils.lib.eachDefaultSystem (system: @@ -17,7 +17,7 @@ devShell = with pkgs; mkShell { SOLHINT_PATH = "$HOME/.solhint.json"; - SOLC_VERSION = "0.8.15"; + SOLC_VERSION = "0.8.18"; buildInputs = [ foundry.defaultPackage.${system} solc-select yarn nodejs-14_x ]; shellHook = ''