Skip to content

Commit

Permalink
Sherlock reviewed fixes - to be merged in master only after Sherlock …
Browse files Browse the repository at this point in the history
…review (#594)

* Develop (#565)

* reworked the RNG to use a deterministic seed (#523)

* reworked the RNG to use a deterministic seed

* reordered params such that they are in the same order as "bound" is called

* Nonfuzzy fill (#529)

* work in progress

* reproduced fenwick tree failures at last index

* proposed changes in light that max index is special case for prefix suim (#533)

* proposed changes in light that max index is special case for prefix suim

* removed comment

Co-authored-by: mwc <matt@ajna.finance>
Co-authored-by: Ed Noepel <ed@lpl.io>

* removed two temp tests

* ported Matt's changes to the fuzzed implementation

Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com>
Co-authored-by: mwc <matt@ajna.finance>
Co-authored-by: Ed Noepel <ed@lpl.io>

Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com>
Co-authored-by: mwc <matt@ajna.finance>
Co-authored-by: Ed Noepel <ed@lpl.io>

* Docs (#535)

* Diagrams

* Add components

* Updates

* Center components

* add pool architectire diagrams (#536)

Co-authored-by: prateek105 <prateek@ajna.finance>

Co-authored-by: Prateek Gupta <prateek105@users.noreply.github.com>
Co-authored-by: prateek105 <prateek@ajna.finance>

* Test Coverage and Tests Style improvements (#541)

* - Ajna balance less than rewards tests

* NFT take tests

* Loan heap test coverage

* PoolCommons 100% test coverage - no interest earned when htp > max price

* Test coverage move dusty amount

* Changes after review:
- comments
- common style on touched tests

* Common style across all unit tests

* PositionManager and RewardsManager deployment (#547)

* replaced bash script with forge script, update for PositionManager and RewardsManager

* intentionally broke example addresses so no one tries to use them for anything

* CI updates (#549)

* testing set-output for size-check

* update to cachev3

* make it look like an env var

* use it like an env var

* revert to old usage syntax

* deleted redundant forge test, since code coverage already runs the tests

* Made Token limitations more robust (#557)

# Description of change
## High level
* Altered `README.MD` to reflect a more robust definition of incompatible tokens

---------

Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com>
Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com>
Co-authored-by: mwc <matt@ajna.finance>
Co-authored-by: Ed Noepel <ed@lpl.io>
Co-authored-by: Prateek Gupta <prateek105@users.noreply.github.com>
Co-authored-by: prateek105 <prateek@ajna.finance>
Co-authored-by: Ian Harvey <ith.harvey@gmail.com>

* Consistent naming, replace lpTokens with LPs (#543)

* Consistent naming, replace lpTokens with LPs

* Changes after review: replace _lpTokenAllowances with _lpAllowances

* Apply test style

* gas improvements (#542)

* Gas improvements:
- LenderActions.removeQuoteToken: reuse depositTime instead loading again from storage

* RewardsManager: calculateAndClaimRewards, increment and then use next epoch

* Remove duped calculation of toPrice from moveQuoteToken function

* Take underflows when full pool debt repaid (#551)

    Take underflows when full pool debt repaid
    Scenario is exposed in testTakeAuctionRepaidAmountGreaterThanPoolDebt test:
       - when auction debt is fully repaid by take action then accrued pool debt value is less than repaid amount with 1 unit of WAD. When the repaid amount is subtracted from pool debt value (normally leaving no debt in pool) the operation underflows.
        - this happens because repaid debt is calculated using t0 value (t0 repaid debt * inflator) and then subtracted from already calculated pool debt
        - fix is to calculate pool debt as (t0 pool debt - t0 repaid debt) * inflator, hence preventing rounding issues

The scope of this PR is extended to uniformize the t0 / accrued debt values calculation across all contracts by using pattern below:
    - when values relative to t0 are changed then t0 is updated first and then transformed in actual value (by multiplying it with inflator value)
    - all accumulations of pool or borrower debt are done on spot and not deferred to Pool contracts (which only save states)

* Sherlock 103.md: Remaining collateral used by ERC721Pool is missed in Auctions take and bucketTake return structures (#566)

* Nft pledge accumulator (#567)

* Add test to expose pledgeCollateral inconsistency when settle NFT auction

* Fix pledgedCollateral accumulator

* Fix settle auction on bucket take

* Add test for auction settle and compensate borrower when settle pool debt. Check pool collateral conistency across buckets

* Fix for pledged collateral accumulator when settle auction with regular take

* Reorg test, add _assertCollateralInvariants helper

* Sherlock 162.md: ERC721Pool taker callback misreports quote funds whenever there was collateral amount rounding (#568)

* Flashloan non18 decimals (#569)

Fix flashloan, reserve auction and settle auction for non standard collateral / quote token precision

    Always use token precision when transferring during flashloans (and do not scale amounts to pool precision). For pool reserves use scaled pool token balance (WAD) so the reserves are accurately calculated.


* Fix flashloan and reserve auction for non standard collateral / quote token precision

* Changes after review: rename _getScaledPoolQuoteTokenBalance to _getNormalizedPoolQuoteTokenBalance

* remove redundant code (#558)

Co-authored-by: prateek105 <prateek@ajna.finance>

* Reduce flashloans logic, introduce _isFlashloanSupported function (default returns true for quote token address, overriden in ERC20 pool to allow both quote and collateral token).
Reorg the flashloan reverts conditions

* Safety measure: (#588)

- setting the remaining collateral to the current by default in drawDebt/repayDebt/_takeLoan functions
- update alongside with borrower.colalteral when more collateral pledged
Note: the remainingCollateral is used by NFT pool and only in the case of auction settlement. This commit doesn't change any logic but it's a safety measure for future developments that could alter this logic

* Sherlock 104.md: Settled collateral of a borrower aren't available for lenders until borrower's debt is fully cleared (#570)

- in ERC721Pool settle rebalance token ids if there's collateral settled
- remove unused return param from Auction.settle
- fix failing test

* Sherlock 105.md: ERC721Pool's mergeOrRemoveCollateral allows to remove collateral while auction is clearable (#571)

- check _revertIfAuctionClearable in mergeOrRemoveCollateral function
- update tests: add _assertMergeRemoveCollateralAuctionNotClearedRevert and assert in ERC721 mergeOrRemove unit tests

* Sherlock 101.md: Flashloan end result isn't controlled (#572)

- record pool balance before transfer flash loaned ERC20 tokens
- compare pool balance after flashloan with the initial / recorded balance
- intorduce FlashloanIncorrectBalance error to revert if initial and current pool balances are different
- update tests, introduce strategy that transfers tokens to pool, hence increasing pool balance, and expect FlashloanIncorrectBalance revert

* Sherlock 183.md: RewardsManager doesn't delete old bucket snapshot info on unstaking (#573)

- add getBucketStateStakeInfo view function to return info of recorded bucket at stake time
- when unstake loop through positions and delete BucketState structs
- in test helper _unstakeToken make sure there's no bucket state info remaining after token unstaked

* Sherlock 151.md: Permanent freezing of unclaimed yield (#574)

* Sherlock 151.md: Permanent freezing of unclaimed yield

- new EpochNotAvailable custom error added
- in claimRewards revert if epoch to claim is greater than latest burn epoch
- add test

* Changes after review: freeze typo

* Sherlock 134.md: (#575)

reported as Transferring funds to yourself increases your balance
actually: Transferring funds to yourself reset balance to 0 (effect is that owner lose all their LPs as it is removed as bucket lender at LenderActions#L550)

- added new custom error TransferToSameOwner, revert in Pool.transferLPs if new owner same as owner
- added revert test on transfer to same address as owner address
- tests style format

* Sherlock 075.md: If borrower or kicker got blacklisted by asset contract their collateral or bond funds can be permanently frozen with the pool (#578)

- Add recipient arg to withdrawBonds and repayDebt functions
- add tests

TBD: should we check and revert if recipient is 0x address

* Sherlock 139.md (#579)

* Sherlock 139.md: scaledQuoteTokenAmount isn't updated to be collateral sell value in the quote token constraint case of _calculateTakeFlowsAndBondChange

- setting the `scaledQuoteTokenAmount` to the `C * p` as a final step of quote token amount constraint case
- update tests

* Added an example to show that the new exchange rate is invariant

* Add tearDown to test, remove return

---------

Co-authored-by: mwc <matt@ajna.finance>

* Sherlock 096.md: Interest rate for pool is bounded wrongly (#580)

- allow creation of pools with min / max rate values
- add tests

* Sherlock 068.md (#581)

* Create standardized PR templates for contracts (#539)

This PR creates three github PR templates that should be followed:
* `logic_src_changes.md`
* `cosmetic_src_changes.md`
* `testing_or_misc_nonsrc_changes.md`

To learn more about how GH templates work -> https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

Co-authored-by: Ian Harvey <iharvey@comcast.net>

* Single template (#546)

* merged all of the templates into one so the text will auto fill when a PR is created.
* was running into this issue documented here with auto fill -> https://stackoverflow.com/questions/52139192/github-pull-requests-template-not-showing

* Sherlock 068.md: ERC721Pool's take will proceed with truncated collateral amount and full debt when borrower's collateral is fractional
- Early revert take action when borrower's collateral is less than `1` if the pool is ERC721
- ensure collateral, quote tokens and bond calculations are alwyas performed for the number of NFTs that will be taken:
instead passing Maths.min(borrower_.collateral, params_.takeCollateral) to _calculateTakeFlowsAndBondChange function calculate the rounded down collateral that can be taken from borrower
Example:
if borrower has 1.2 worth of colalteral and taker pass an amount of 2 collateral to take then calculations happens for Min(rounded(1.2), 2) = 1 NFT token
If borrower debt can be covered with less than 1 NFT then _calculateTakeFlowsAndBondChange will return a fractioned NFT (0.5 for example) and the difference between 1 NFT taken and 0.5 will be paid with excess quote tokens

---------

Co-authored-by: Ian Harvey <ith.harvey@gmail.com>
Co-authored-by: Ian Harvey <iharvey@comcast.net>

* fix sherlock issues 120 and 121 (#576)

* Create standardized PR templates for contracts (#539)

This PR creates three github PR templates that should be followed:
* `logic_src_changes.md`
* `cosmetic_src_changes.md`
* `testing_or_misc_nonsrc_changes.md`

To learn more about how GH templates work -> https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

Co-authored-by: Ian Harvey <iharvey@comcast.net>

* Single template (#546)

* merged all of the templates into one so the text will auto fill when a PR is created.
* was running into this issue documented here with auto fill -> https://stackoverflow.com/questions/52139192/github-pull-requests-template-not-showing

* fix sherlock issue 121 precision loss by multiplying before dividing

* add _transferAjnaRewards method

---------

Co-authored-by: Ian Harvey <ith.harvey@gmail.com>
Co-authored-by: Ian Harvey <iharvey@comcast.net>
Co-authored-by: Mike <mikehathaway@makerdao.com>

* Sherlock 163,140, 34 & 31: Remove support for non standard NFTs (#585)

* merged all of the templates into one so the text will auto fill when a PR is created.
* was running into this issue documented here with auto fill -> https://stackoverflow.com/questions/52139192/github-pull-requests-template-not-showing

* Remove support for non standard NFTs (will have to be wrapped)

* Sherlock 151: Changes for initial fix: (#596)

* Sherlock 151: Changes for initial fix:
- pass isManualEpoch_ param to _claimRewards function and do the epoch validation only if true (no need to validate for unstake which doesn't receive epoch as a param)
- load stake struct from storage only once (and pass as a param to _claimRewards function) minimize calls to load ajna pool from stake storage

* Changes after review: rename isManualEpoch to validateEpoch param

* Sherlock 134.md changes after review: move check in LenderActions external library to keep logic in same place (#597)

* Sherlock 98.md: (#577)

* Create standardized PR templates for contracts (#539)

This PR creates three github PR templates that should be followed:
* `logic_src_changes.md`
* `cosmetic_src_changes.md`
* `testing_or_misc_nonsrc_changes.md`

To learn more about how GH templates work -> https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

Co-authored-by: Ian Harvey <iharvey@comcast.net>

* Single template (#546)

* merged all of the templates into one so the text will auto fill when a PR is created.
* was running into this issue documented here with auto fill -> https://stackoverflow.com/questions/52139192/github-pull-requests-template-not-showing

* add reentrancy guard to PositionManager.mint(); update mint natspec

---------

Co-authored-by: Ian Harvey <ith.harvey@gmail.com>
Co-authored-by: Ian Harvey <iharvey@comcast.net>
Co-authored-by: Mike <mikehathaway@makerdao.com>

* Sherlock 145: Take adjustments: `msg.sender` provides QT instead of `_callee`  (#589)

<!---
No need to add special tag
src/ & non src/ changes you need the following (that apply):
-->
# Description of change
## High level
* inside of `take` for ERC721 and ERC20 pools changed the argument passed in `_transferQuoteTokenFrom()` from `_callee` to `msg.sender`. 
* This update now makes the `_take` call match other implementations such as Maker
* NOTE: 10-30K spike in gas cost because of change.

<!---
Add the `Status: Needs Auditor Approval` tags
CHANGES IN /SRC DIR:
- renaming (not retyping or resizing) of variables & methods
- reordering and moving of functions in files
- lite moving of functions accross files
- comments

src/ changes you need the following (that apply):
-->

# Description of bug or vulnerability and solution
[ERC20Pool](https://github.com/sherlock-audit/2023-01-ajna/blob/main/contracts/src/ERC20Pool.sol#L403) and [ERC721Pool](https://github.com/sherlock-audit/2023-01-ajna/blob/main/contracts/src/ERC721Pool.sol#L405) implement the take functions, which buy collateral from auction in exchange for quote tokens. The address to pull quote tokens from is specified in the `_callee` argument, which allows anyone to call the functions and pass an address that has previously approved spending of the quote token to the pool. As a result, such an address will pay for the liquidation and will receive the collateral.

The solution makes it so the `msg.sender` provides the QT when calling the `take()` method. 

# Contract size
## Pre Change
```
============ Deployment Bytecode Sizes ============
  ERC721Pool               -  22,267B  (90.60%)
  ERC20Pool                -  20,972B  (85.33%)
```
## Post Change
```
============ Deployment Bytecode Sizes ============
  ERC721Pool               -  22,267B  (90.60%)
  ERC20Pool                -  20,972B  (85.33%)
```

# Gas usage
## Pre Change
```
| src/ERC20Pool.sol:ERC20Pool contract |                 |        |        |        |         |
|--------------------------------------|-----------------|--------|--------|--------|---------|
| take                                 | 8550            | 158087 | 165977 | 520357 | 32      |

 src/ERC721Pool.sol:ERC721Pool contract |                 |        |        |        |         |
|----------------------------------------|-----------------|--------|--------|--------|---------|
| take                                   | 11246           | 292029 | 375721 | 632601 | 11      |
```

## Post Change
```
| src/ERC20Pool.sol:ERC20Pool contract |                 |        |        |        |         |
|--------------------------------------|-----------------|--------|--------|--------|---------|
| take                                 | 8550            | 164634 | 184194 | 520356 | 33      |

| src/ERC721Pool.sol:ERC721Pool contract |                 |        |        |          |         |
|----------------------------------------|-----------------|--------|--------|----------|---------|
| take                                   | 11246           | 320810 | 387200 | 637400   | 12      |
```

* Sherlock 70: user can drawDebt that is below dust amount (#598)

* ensure borrower debt exceeds dust amount regardless of loan count

* Revert "ensure borrower debt exceeds dust amount regardless of loan count"

This reverts commit c0a64f9.

* re-applied changes lost when rebasing

* Sherlock 68: (#599)

- review update: add suggested revert to be excessively safe (for the case if current or future version of _calculateTakeFlowsAndBondChange() malfunctions producing collateral bigger than its collateral argument)

* Sherlock 92: startClaimableReserveAuction using old inflator (#587)

* Sherlock 92: startClaimableReserveAuction using old inflator

* Add test to show interest accrued when start reserve auction

* Revert "Sherlock 92: startClaimableReserveAuction using old inflator (#587)"

This reverts commit 1414435.

* change safeTransferFrom to transferFrom to support Oasis (#592)

* Create standardized PR templates for contracts (#539)

This PR creates three github PR templates that should be followed:
* `logic_src_changes.md`
* `cosmetic_src_changes.md`
* `testing_or_misc_nonsrc_changes.md`

To learn more about how GH templates work -> https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

Co-authored-by: Ian Harvey <iharvey@comcast.net>

* Single template (#546)

* merged all of the templates into one so the text will auto fill when a PR is created.
* was running into this issue documented here with auto fill -> https://stackoverflow.com/questions/52139192/github-pull-requests-template-not-showing

* change safeTransferFrom to transferFrom

---------

Co-authored-by: Ian Harvey <ith.harvey@gmail.com>
Co-authored-by: Ian Harvey <iharvey@comcast.net>
Co-authored-by: Mike <mikehathaway@makerdao.com>

* Sherlock 148: Use pool debt when calculating MOMP in Loans.update (#586)

* Update comments: (#590)

- ERC721.addCollateral changes bucketTokenIds
- ERC721.repayDebt changes borrowerTokenIds and bucketTokenIds (when auction settled)
- fix comment in Auctions._calculateTakeFlowsAndBondChange for take below NP

* fix safeTransferFromWithPermit (#593)

* Create standardized PR templates for contracts (#539)

This PR creates three github PR templates that should be followed:
* `logic_src_changes.md`
* `cosmetic_src_changes.md`
* `testing_or_misc_nonsrc_changes.md`

To learn more about how GH templates work -> https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

Co-authored-by: Ian Harvey <iharvey@comcast.net>

* Single template (#546)

* merged all of the templates into one so the text will auto fill when a PR is created.
* was running into this issue documented here with auto fill -> https://stackoverflow.com/questions/52139192/github-pull-requests-template-not-showing

* fix safeTransferFromWithPermit

---------

Co-authored-by: Ian Harvey <ith.harvey@gmail.com>
Co-authored-by: Ian Harvey <iharvey@comcast.net>
Co-authored-by: Mike <mikehathaway@makerdao.com>

* LPS and Exchange Rate as WADs - Sherlock 133 & 83 (#606)

* LPs as WADs

* - record lender LPs in remove collateral and quote token only if bucket doesn't go bankrupt
- for remove colalteral use the same way to calculate LPs as when rewarding, to avoid precision issues
- tearDown should consider that bucket can go bankrupt, hence lender LPs should be checked = 0 taking this into account (lenderInfo function is doing this)
- all tests passing but testDepositTwoActorSameBucket fails in tearDown - that's because there are quote tokens remaining without being backed by LPs (were previously redeemed in tearDown for collateral)

* Use consistent way to calculate LPs reported to scaled amounts, remove unscaled rate exchange, fix tests
Couple of take tests fail in tearDown leaving small dust deposit

* Cleanup Maths library, update comments

* Fix remaining tests

* Fix sequence to empty buckets, one single settle test remaining failing in tearDown

* Add bucket clean out sequence, make consistent for removeCollateral too (per Sherlock 133)

* Add bankruptcy check for move quote token from bucket and unit test

* Guard against underflows in removeQuoteToken (due to roundings when transforming from scaled to unscaled amount)

* Changes after review:
- calculate amount using collateralAmount_ rather than bucketCollateral
- remove dead code in remove quote token

* Sherlock 39: expiration timestamp and slippage control (#600)

* ignore forge script tx broadcasts

* provide LUP limit when pulling collateral

* expiration checks for adding to buckets

* unit tests for addQuote and addCollateral expiration

* expiration checks for moveQuote

* ensure borrower debt exceeds dust amount regardless of loan count

* Revert "ensure borrower debt exceeds dust amount regardless of loan count"

This reverts commit c0a64f9.

* feedback from PR #600 (#604)

* removed comment

* Address review comments, update comment for _revertIfLupDroppedBelowL… (#607)

* Address review comments, update comment for _revertIfLupDroppedBelowLimit, changed LimitIndexReached to LimitIndexExceeded

* Remove lup Id variable, calculate LUP price directly

* Remove unused struct member

---------

Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com>

* Fix test compile

* Protocol invariants testing (#609)

* Invariants

* Exclude invariants from code coverage and GH action

* Fix coverage GH target

* Changes after review

* Disallow auctioned borrowers to draw more debt or pull collateral if auction is not settled. (#611)

This can happen in a scenario where user becomes recollateralized to the new LUP.
Without these checks, and since borrow and pull doesn't settle auctions, borrower is not removed from auction queue but added in loan queue as well, which violate invariant
- **A3**: number of borrowers with debt  = number of loans  + number of auctioned borrowers

* Sherlock 73 (#591)

* Create standardized PR templates for contracts (#539)

This PR creates three github PR templates that should be followed:
* `logic_src_changes.md`
* `cosmetic_src_changes.md`
* `testing_or_misc_nonsrc_changes.md`

To learn more about how GH templates work -> https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

Co-authored-by: Ian Harvey <iharvey@comcast.net>

* Single template (#546)

* merged all of the templates into one so the text will auto fill when a PR is created.
* was running into this issue documented here with auto fill -> https://stackoverflow.com/questions/52139192/github-pull-requests-template-not-showing

* update getNFTSubsetHash to uniquely sort array of tokenIds

* add natspec and slight gas optimization

* change encodePacked to encode to add byte padding

* pool deployer gas optimization

* check sort order instead of sorting on chain

* pr feedback to check for duplicate tokenIds

---------

Co-authored-by: Ian Harvey <ith.harvey@gmail.com>
Co-authored-by: Ian Harvey <iharvey@comcast.net>
Co-authored-by: Mike <mikehathaway@makerdao.com>

---------

Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com>
Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com>
Co-authored-by: mwc <matt@ajna.finance>
Co-authored-by: Ed Noepel <ed@lpl.io>
Co-authored-by: Prateek Gupta <prateek105@users.noreply.github.com>
Co-authored-by: prateek105 <prateek@ajna.finance>
Co-authored-by: Ian Harvey <ith.harvey@gmail.com>
Co-authored-by: Ian Harvey <iharvey@comcast.net>
Co-authored-by: Mike Hathaway <mahathaway93@gmail.com>
Co-authored-by: Mike <mikehathaway@makerdao.com>
  • Loading branch information
11 people authored Feb 13, 2023
1 parent f5ace44 commit ec79122
Show file tree
Hide file tree
Showing 151 changed files with 16,485 additions and 13,785 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

# Report code coverage to discord
- name: Generate coverage
run: forge coverage --report lcov --no-match-test testLoad
run: forge coverage --report lcov --no-match-test "testLoad|invariant"
- name: Setup LCOV
uses: hrishikesh-kadam/setup-lcov@v1
- name: Filter lcov
Expand Down
55 changes: 0 additions & 55 deletions .github/workflows/forge-tests.yml

This file was deleted.

17 changes: 9 additions & 8 deletions .github/workflows/size-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ jobs:
submodules: recursive

- name: Cache compiler installations
uses: actions/cache@v2
id: cache-compiler
uses: actions/cache@v3
with:
path: |
~/.solcx
Expand All @@ -32,13 +33,13 @@ jobs:
- name: Set pip cache directory path
id: pip-cache-dir-path
run: |
echo "::set-output name=dir::$(pip cache dir)"
echo "PIP_CACHE_DIR=$(pip cache dir)" >> $GITHUB_ENV
- name: Restore pip cache
uses: actions/cache@v2
uses: actions/cache@v3
id: pip-cache
with:
path: |
${{ steps.pip-cache-dir-path.outputs.dir }}
${PIP_CACHE_DIR}
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements-dev.txt') }}
restore-keys: |
${{ runner.os }}-pip-${{ hashFiles('**/requirements-dev.txt') }}
Expand All @@ -47,17 +48,17 @@ jobs:
run: pip install -r requirements-dev.txt

- name: Run check-size script
id: check-size
run: |
mkdir -p size-reports-${{ github.run_id }}
./check-size.sh | tee size-reports-${{github.run_id}}/size-report
echo "##[set-output name=size-report;]$(echo $(cat size-reports-${{github.run_id}}/size-report|tail -1))"
id: check-size
echo "SIZE_REPORT=$(echo $(cat size-reports-${{github.run_id}}/size-report|tail -1))" >> $GITHUB_OUTPUT
- name: Send size report to Discord
uses: appleboy/discord-action@master
with:
webhook_id: ${{ secrets.DISCORD_ID }}
webhook_token: ${{ secrets.DISCORD_TOKEN }}
username: "Contract Size Reporter"
message: Largest contract size for `${{ github.ref }}` ```${{ steps.check-size.outputs.size-report }}```
timeout-minutes: 2
message: Largest contract size for `${{ github.ref }}` ```${{ steps.check-size.outputs.SIZE_REPORT }}```
timeout-minutes: 3
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ reports/
coverage/
*.info
report/
keystore/
keystore/
broadcast/
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ install :; git submodule update --init --recursive
build :; forge clean && forge build

# Tests
test :; forge test --no-match-test testLoad # --ffi # enable if you need the `ffi` cheat code on HEVM
test-with-gas-report :; FOUNDRY_PROFILE=optimized forge test --no-match-test testLoad --gas-report # --ffi # enable if you need the `ffi` cheat code on HEVM
test :; forge test --no-match-test "testLoad|invariant" # --ffi # enable if you need the `ffi` cheat code on HEVM
test-with-gas-report :; FOUNDRY_PROFILE=optimized forge test --no-match-test "testLoad|invariant" --gas-report # --ffi # enable if you need the `ffi` cheat code on HEVM
test-load :; FOUNDRY_PROFILE=optimized forge test --match-test testLoad --gas-report
coverage :; forge coverage --no-match-test testLoad
test-invariant :; forge t --mt invariant
coverage :; forge coverage --no-match-test "testLoad|invariant"

# Generate Gas Snapshots
snapshot :; forge clean && forge snapshot

analyze:
slither src/. ; slither src/libraries/external/.


# Deployment
deploy-contracts:
forge script ./deploy.sol \
--rpc-url ${ETH_RPC_URL} --sender ${DEPLOY_ADDRESS} --keystore ${DEPLOY_KEY} --broadcast -vvv
60 changes: 34 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@

The Ajna protocol is a non-custodial, peer-to-peer, permissionless lending, borrowing and trading system that requires no governance or external price feeds to function. The protocol consists of pools: pairings of quote tokens provided by lenders and collateral tokens provided by borrowers. Ajna is capable of accepting fungible tokens as quote tokens and both fungible and non-fungible tokens as collateral tokens.

## Limitations
- The following types of tokens are incompatible with Ajna, and no countermeasures exist to explicitly prevent creating a pool with such tokens:
- Fungible tokens whose balance rebases.
- NFTs which charge a fee on transfer.
- Fungible tokens with more than 18 decimals or 0 decimals.
## Accepted tokens:
- Fungible tokens (following the [ERC20 token standard](https://eips.ethereum.org/EIPS/eip-20)).
- Non-fungible tokens (following the [ERC721 token standard](https://eips.ethereum.org/EIPS/eip-721))
- Special considerations have been made to support specific NFTs with nonstandard ERC721 implementations, including _CryptoPunks_ and _CryptoKitties_. This support is limited to Ethereum mainnet.

### Token limitations
- The following types of tokens are incompatible with Ajna, and no countermeasures exist to explicitly prevent creating a pool with such tokens, actors should use them at their own risk:
- NFT and fungible tokens which charge a fee on transfer.
- Fungible tokens whose balance rebases.
- Fungible tokens with more than 18 decimals or 0 decimals.
- Borrowers cannot draw debt from a pool in the same block as when the pool was created.
- With the exception of quantized prices, pool inputs and most accumulators are not explicitly limited. The pool will stop functioning when the bounds of a `uint256` need to be exceeded to process a request.



## Development
### Requirements
- `python` 3.0+
Expand Down Expand Up @@ -150,35 +155,38 @@ Modifications to, or notices of actions by Licensor, contemplated above or under

## Deployment

A deployment script has been created to automate deployment of libraries and factory contracts.
To use it, set up an environment with the following:
- **AJNA_TOKEN** - address of the AJNA token on your target chain
- **ETH_RPC_URL** - node pointing to the target chain
- **DEPLOY_KEY** - path to the JSON keystore file for your deployment account
A deployment script has been created to automate deployment of libraries, factory contracts, and manager contracts.

To use it, ensure the following env variables are in your `.env` file or exported into your environment.
| Environment Variable | Purpose |
|----------------------|---------|
| `AJNA_TOKEN` | address of the AJNA token on your target chain
| `DEPLOY_ADDRESS` | address from which you wish to deploy
| `DEPLOY_KEY` | path to the JSON keystore file for the deployment address
| `ETHERSCAN_API_KEY` | required to verify contracts
| `ETH_RPC_URL` | node on your target deployment network

Ensure your deployment account is funded with some ETH for gas.

The deployment script takes no arguments, and interactively prompts for your keystore password:
Since contract source has not yet been made public, the `--verify` switch has been omitted. To run:

```
./deploy.sh
make deploy-contracts
```

Upon completion, contract addresses will be printed to `stdout`:
```
Deploying to chain with AJNA token address 0xDD576260ed60AaAb798D8ECa9bdBf33D70E077F4
Enter keystore password:
Deploying libraries...
Deployed Auctions to 0xDD576260ed60AaAb798D8ECa9bdBf33D70E077F4
Deployed LenderActions to 0x4c08A2ec1f5C067DC53A5fCc36C649501F403b93
Deployed PoolCommons to 0x8BBCA51044d00dbf16aaB8Fd6cbC5B45503B898b
Deploying factories...
Deployed ERC20PoolFactory to 0xED625fbf62695A13d2cADEdd954b23cc97249988
Deployed ERC721PoolFactory to 0x775D30918A42160bC7aE56BA1660E32ff50CF6dC
Deploying PoolInfoUtils...
Deployed PoolInfoUtils to 0xd8A51cE16c7665111401C0Ba2ABEcE03B847b4e6
== Logs ==
Deploying to chain with AJNA token address 0x34A1D3fff3958843C43aD80F30b94c510645C...
=== Deployment addresses ===
ERC20 factory 0x50EEf481cae4250d252Ae577A09bF514f224C...
ERC721 factory 0x62c20Aa1e0272312BC100b4e23B4DC1Ed96dD...
PoolInfoUtils 0xDEb1E9a6Be7Baf84208BB6E10aC9F9bbE1D70...
PositionManager 0xD718d5A27a29FF1cD22403426084bA0d47986...
RewardsManager 0x4f559F30f5eB88D635FDe1548C4267DB8FaB0...
```

Record the factory addresses.
Record these addresses.

### Validation

Expand All @@ -203,4 +211,4 @@ cast send ${DAI_TOKEN} "approve(address,uint256)" ${WBTC_DAI_POOL} 50000ether \
--from ${DEPLOY_ADDRESS} --keystore ${DEPLOY_KEY}
cast send ${WBTC_DAI_POOL} "addQuoteToken(uint256,uint256)" 100ether 3232 \
--from ${DEPLOY_ADDRESS} --keystore ${DEPLOY_KEY}
```
```
2 changes: 1 addition & 1 deletion check-code-coverage.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

forge coverage --report lcov --no-match-test testLoad
forge coverage --report lcov --no-match-test "testLoad|invariant"

lcov -r lcov.info "tests/*" -o lcov-filtered.info --rc lcov_branch_coverage=1

Expand Down
63 changes: 0 additions & 63 deletions deploy.sh

This file was deleted.

36 changes: 36 additions & 0 deletions deploy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

import { Script } from "forge-std/Script.sol";
import "forge-std/console.sol";

import { ERC20PoolFactory } from 'src/ERC20PoolFactory.sol';
import { ERC721PoolFactory } from 'src/ERC721PoolFactory.sol';
import { PoolInfoUtils } from 'src/PoolInfoUtils.sol';
import { PositionManager } from 'src/PositionManager.sol';
import { RewardsManager } from 'src/RewardsManager.sol';

contract Deploy is Script {
address ajna;

function run() public {
ajna = vm.envAddress("AJNA_TOKEN");
console.log("Deploying to chain with AJNA token address %s", ajna);

vm.startBroadcast();
ERC20PoolFactory erc20factory = new ERC20PoolFactory(ajna);
ERC721PoolFactory erc721factory = new ERC721PoolFactory(ajna);
PoolInfoUtils poolInfoUtils = new PoolInfoUtils();

PositionManager positionManager = new PositionManager(erc20factory, erc721factory);
RewardsManager rewardsManager = new RewardsManager(ajna, positionManager);
vm.stopBroadcast();

console.log("=== Deployment addresses ===");
console.log("ERC20 factory %s", address(erc20factory));
console.log("ERC721 factory %s", address(erc721factory));
console.log("PoolInfoUtils %s", address(poolInfoUtils));
console.log("PositionManager %s", address(positionManager));
console.log("RewardsManager %s", address(rewardsManager));
}
}
4 changes: 2 additions & 2 deletions docs/Functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@

emit events:
- LenderActions.transferLPs():
- TransferLPTokens
- TransferLPs

### kick
external libraries call:
Expand Down Expand Up @@ -370,7 +370,7 @@
- BorrowerActions.drawDebt()
- borrower not sender BorrowerNotSender()
- borrower debt less than pool min debt AmountLTMinDebt()
- limit price reached LimitIndexReached()
- limit price reached LimitIndexExceeded()
- borrower cannot draw more debt BorrowerUnderCollateralized()

emit events:
Expand Down
1 change: 1 addition & 0 deletions docs/drawio/addCollateral.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2023-01-09T11:19:32.456Z" agent="5.0 (X11)" etag="q2IyEHYS9TFNI9EXhJNj" version="20.8.3" type="device"><diagram name="Page-1" id="13e1069c-82ec-6db2-03f1-153e76fe0fe0">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</diagram></mxfile>
Loading

0 comments on commit ec79122

Please sign in to comment.