Skip to content

Commit

Permalink
Merge pull request #1037 from liquity/main
Browse files Browse the repository at this point in the history
Update master / release assets
  • Loading branch information
edmulraney authored Jan 23, 2024
2 parents 14eac8a + fc37ee6 commit f79fc03
Show file tree
Hide file tree
Showing 212 changed files with 56,502 additions and 27,069 deletions.
22 changes: 8 additions & 14 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,17 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: 12.x

- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
node-version: 16
cache: yarn
env:
# Workaround for https://github.com/actions/setup-node/issues/317
FORCE_COLOR: 0

- run: yarn install --frozen-lockfile
- run: yarn install --immutable
- run: yarn build

- name: Test SDK & UI
Expand Down
44 changes: 16 additions & 28 deletions .github/workflows/test-contracts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,17 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: 12.x

- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
node-version: 16
cache: yarn
env:
# Workaround for https://github.com/actions/setup-node/issues/317
FORCE_COLOR: 0

- run: yarn install --frozen-lockfile
- run: yarn install --immutable

- name: Test contracts
run: yarn test-contracts
Expand All @@ -46,23 +40,17 @@ jobs:
continue-on-error: true

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- uses: actions/setup-node@v1
- uses: actions/setup-node@v3
with:
node-version: 12.x

- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
node-version: 16
cache: yarn
env:
# Workaround for https://github.com/actions/setup-node/issues/317
FORCE_COLOR: 0

- run: yarn install --frozen-lockfile
- run: yarn install --immutable

- name: Test contract coverage
run: yarn coverage
Expand Down
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,18 @@ node_modules

# Don't track NPM lockfile (we use Yarn)
package-lock.json

# Don't track hardhat mainnet fork cache
cache

# ngrok config is individual to each dev
ngrok.config.yml

# Yarn
.pnp.*
/.yarn/*
!/.yarn/patches
!/.yarn/plugins
!/.yarn/releases
!/.yarn/sdks
!/.yarn/versions
541 changes: 541 additions & 0 deletions .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs

Large diffs are not rendered by default.

873 changes: 873 additions & 0 deletions .yarn/releases/yarn-3.5.1.cjs

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
nodeLinker: node-modules

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

yarnPath: .yarn/releases/yarn-3.5.1.cjs
46 changes: 39 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Liquity: Decentralized Borrowing Protocol

[<img alt="DeFiSafety Badge" width="96px" align="right" src="images/defisafety-badge.png" />](https://www.defisafety.com/app/pqrs/376)

![Tests](https://github.com/liquity/dev/workflows/CI/badge.svg) [![Frontend status](https://img.shields.io/uptimerobot/status/m784948796-056b56fd51c67d682c11bb24?label=Testnet&logo=nginx&logoColor=white)](https://devui.liquity.org) ![uptime](https://img.shields.io/uptimerobot/ratio/7/m784948796-056b56fd51c67d682c11bb24) [![Discord](https://img.shields.io/discord/700620821198143498?label=join%20chat&logo=discord&logoColor=white)](https://discord.gg/2up5U32) [![Docker Pulls](https://img.shields.io/docker/pulls/liquity/dev-frontend?label=dev-frontend%20pulls&logo=docker&logoColor=white)](https://hub.docker.com/r/liquity/dev-frontend) [![codecov](https://codecov.io/gh/liquity/dev/branch/add_codecov/graph/badge.svg)](https://codecov.io/gh/liquity/dev)


Expand Down Expand Up @@ -123,6 +125,7 @@ Visit [liquity.org](https://www.liquity.org) to find out more and join the discu
- [Start a local blockchain and deploy the contracts](#start-a-local-blockchain-and-deploy-the-contracts)
- [Start dev-frontend in development mode](#start-dev-frontend-in-development-mode)
- [Start dev-frontend in demo mode](#start-dev-frontend-in-demo-mode)
- [Start dev-frontend against a mainnet fork RPC node](#start-dev-frontend-against-a-mainnet-fork-rpc-node)
- [Build dev-frontend for production](#build-dev-frontend-for-production)
- [Configuring your custom frontend](#configuring-your-custom-dev-ui)
- [Running a frontend with Docker](#running-dev-ui-with-docker)
Expand Down Expand Up @@ -306,7 +309,7 @@ In the first year after launch:

- The Liquity admin address may transfer tokens **only to verified lockup contracts with an unlock date at least one year after system deployment**

Also, separate LQTY allocations are made at deployent to an EOA that will hold an amount of LQTY for bug bounties/hackathons and to a Uniswap LP reward contract. Aside from these allocations, the only LQTY made freely available in this first year is the LQTY that is publically issued to Stability Providers via the `CommunityIssuance` contract.
Also, separate LQTY allocations are made at deployment to an EOA that will hold an amount of LQTY for bug bounties/hackathons and to a Uniswap LP reward contract. Aside from these allocations, the only LQTY made freely available in this first year is the LQTY that is publically issued to Stability Providers via the `CommunityIssuance` contract.

### Lockup Implementation and admin transfer restriction

Expand Down Expand Up @@ -411,6 +414,12 @@ There is also a return condition `bothOraclesLiveAndUnbrokenAndSimilarPrice` whi

The current `PriceFeed.sol` contract has an external `fetchPrice()` function that is called by core Liquity functions which require a current ETH:USD price. `fetchPrice()` calls each oracle's proxy, asserts on the responses, and converts returned prices to 18 digits.

### Tellor price data lag

Liquity sees a Tellor ETH-USD price that is at least 15 minutes old. This is because Tellor operates via proof-of-stake, and some dispute period is needed in which fake prices can be disputed. When a Tellor price is disputed, it is removed from the list of prices that Liquity sees. This dispute period ensures that, given at least one responsive disputer who disputes fake ETH prices, Liquity will never consume fake price data from Tellor.

The choice of 15 minutes for the dispute period was based on careful analysis of the impact of a delayed ETH price on a Liquity system. We used historical ETH price data and looked at the impact of different delay lengths. 15 minutes was chosen as a sweet spot that gives plenty of time for disputers to respond to fake prices, while keeping any adverse impacts on Liquity to a minimum.

### PriceFeed Logic

The PriceFeed contract fetches the current price and previous price from Chainlink and changes its state (called `Status`) based on certain conditions.
Expand Down Expand Up @@ -481,7 +490,7 @@ Thus, nodes need only be re-inserted to the sorted list upon a Trove operation -

![Flow of Ether](images/ETH_flows.svg)

Ether in the system lives in three Pools: the ActivePool, the DefaultPool and the StabilityPool. When an operation is made, Ether is transferred in one of three ways:
Ether in the system lives in four Pools: the ActivePool, the DefaultPool, the StabilityPool and the CollSurplusPool, plus LQTYStaking contract. When an operation is made, Ether is transferred in one of three ways:

- From a user to a Pool
- From a Pool to a user
Expand All @@ -491,6 +500,8 @@ Ether is recorded on an _individual_ level, but stored in _aggregate_ in a Pool.

Likewise, the StabilityPool holds the total accumulated ETH gains from liquidations for all depositors.

LQTYStaking receives ETH coming from redemption fees.

**Borrower Operations**

| Function | ETH quantity | Path |
Expand Down Expand Up @@ -771,7 +782,7 @@ All data structures with the ‘public’ visibility specifier are ‘gettable

`getEntireSystemDebt()` Returns the systemic entire debt assigned to Troves, i.e. the sum of the LUSDDebt in the Active Pool and the Default Pool.

`getTCR()`: returns the total collateralization ratio (TCR) of the system. The TCR is based on the the entire system debt and collateral (including pending rewards).
`getTCR()`: returns the total collateralization ratio (TCR) of the system. The TCR is based on the entire system debt and collateral (including pending rewards).

`checkRecoveryMode()`: reveals whether or not the system is in Recovery Mode (i.e. whether the Total Collateralization Ratio (TCR) is below the Critical Collateralization Ratio (CCR)).

Expand All @@ -783,7 +794,7 @@ All data structures with the ‘public’ visibility specifier are ‘gettable

- `firstRedemptionHint` is a positional hint for the first redeemable Trove (i.e. Trove with the lowest ICR >= MCR).
- `partialRedemptionHintNICR` is the final nominal ICR of the last Trove after being hit by partial redemption, or zero in case of no partial redemption (see [Hints for `redeemCollateral`](#hints-for-redeemcollateral)).
- `truncatedLUSDamount` is the maximum amount that can be redeemed out of the the provided `_LUSDamount`. This can be lower than `_LUSDamount` when redeeming the full amount would leave the last Trove of the redemption sequence with less debt than the minimum allowed value.
- `truncatedLUSDamount` is the maximum amount that can be redeemed out of the provided `_LUSDamount`. This can be lower than `_LUSDamount` when redeeming the full amount would leave the last Trove of the redemption sequence with less debt than the minimum allowed value.

The number of Troves to consider for redemption can be capped by passing a non-zero value as `_maxIterations`, while passing zero will leave it uncapped.

Expand Down Expand Up @@ -1055,7 +1066,7 @@ Stability Providers expect a positive ROI on their initial deposit. That is:

When a liquidation hits the Stability Pool, it is known as an **offset**: the debt of the Trove is offset against the LUSD in the Pool. When **x** LUSD debt is offset, the debt is cancelled, and **x** LUSD in the Pool is burned. When the LUSD Stability Pool is greater than the debt of the Trove, all the Trove's debt is cancelled, and all its ETH is shared between depositors. This is a **pure offset**.

It can happen that the LUSD in the Stability Pool is less than the debt of a Trove. In this case, the the whole Stability Pool will be used to offset a fraction of the Trove’s debt, and an equal fraction of the Trove’s ETH collateral will be assigned to Stability Providers. The remainder of the Trove’s debt and ETH gets redistributed to active Troves. This is a **mixed offset and redistribution**.
It can happen that the LUSD in the Stability Pool is less than the debt of a Trove. In this case, the whole Stability Pool will be used to offset a fraction of the Trove’s debt, and an equal fraction of the Trove’s ETH collateral will be assigned to Stability Providers. The remainder of the Trove’s debt and ETH gets redistributed to active Troves. This is a **mixed offset and redistribution**.

Because the ETH collateral fraction matches the offset debt fraction, the effective ICR of the collateral and debt that is offset, is equal to the ICR of the Trove. So, for depositors, the ROI per liquidation depends only on the ICR of the liquidated Trove.

Expand Down Expand Up @@ -1416,7 +1427,7 @@ In addition, some package scripts require Docker to be installed (Docker Desktop
You'll need to install the following:

- [Git](https://help.github.com/en/github/getting-started-with-github/set-up-git) (of course)
- [Node v12.x](https://nodejs.org/dist/latest-v12.x/)
- [Node v16.x](https://nodejs.org/dist/latest-v16.x/)
- [Docker](https://docs.docker.com/get-docker/)
- [Yarn](https://classic.yarnpkg.com/en/docs/install)

Expand Down Expand Up @@ -1489,7 +1500,7 @@ This copies the contract artifacts to a version controlled area (`packages/lib/l
yarn start-dev-chain
```

Starts an openethereum node in a Docker container, running the [private development chain](https://openethereum.github.io/wiki/Private-development-chain), then deploys the contracts to this chain.
Starts an openethereum node in a Docker container, running the [private development chain](https://openethereum.github.io/Private-development-chain), then deploys the contracts to this chain.

You may want to use this before starting the dev-frontend in development mode. To use the newly deployed contracts, switch MetaMask to the built-in "Localhost 8545" network.

Expand Down Expand Up @@ -1532,6 +1543,25 @@ When you no longer need the demo mode, press Ctrl+C in the terminal then run:
yarn stop-demo
```

#### Start dev-frontend against a mainnet fork RPC node

This will start a hardhat mainnet forked RPC node at the block number configured in `hardhat.config.mainnet-fork.ts`, so you need to make sure you're not running a hardhat node on port 8545 already.

You'll need an Alchemy API key to create the fork.

```
ALCHEMY_API_KEY=enter_your_key_here yarn start-fork
```

```
yarn start-demo:dev-frontend
```

This spawns a modified version of dev-frontend that automatically signs transactions so you don't need to interact with a browser wallet. It directly uses the local forked RPC node.

You may need to wait a minute or so for your fork mainnet provider to load and cache all the blockchain state at your chosen block number. Refresh the page after 5 minutes.


#### Build dev-frontend for production

In a freshly cloned & installed monorepo, or if you have only modified code inside the dev-frontend package:
Expand Down Expand Up @@ -1709,6 +1739,8 @@ In case of a redemption, the “last” trove affected by the transaction may en

An attacker trying to DoS redemptions could be bypassed by redeeming an amount that exactly corresponds to the debt of the affected trove(s).

The attack can be aggravated if a big trove is placed first in the queue, so that any incoming redemption is smaller than its debt, as no LUSD would be redeemed if the hint for that trove fails. But that attack would be very expensive and quite risky (risk of being redeemed if the strategy fails and of being liquidated as it may have a low CR).

Finally, this DoS could be avoided if the initial transaction avoids the public gas auction entirely and is sent direct-to-miner, via (for example) Flashbots.


Expand Down
2 changes: 1 addition & 1 deletion dev-chain/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID": "0x11",
"networkID": "0x539",
"registrar": "0x0000000000000000000000000000000000001337",
"eip150Transition": "0x0",
"eip160Transition": "0x0",
Expand Down
25 changes: 25 additions & 0 deletions hardhat.config.mainnet-fork.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { HardhatUserConfig } from "hardhat/config";

const alchemyApiKey = process.env.ALCHEMY_API_KEY;

const config: HardhatUserConfig = {
solidity: "0.7.3",
networks: {
hardhat: {
chainId: 1,
forking: {
url: `https://eth-mainnet.g.alchemy.com/v2/${alchemyApiKey}`,
blockNumber: 16233419
},
accounts: [
{
privateKey: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7",
balance: "100000000000000000000000"
}
],
initialBaseFeePerGas: 0
}
}
};

export default config;
Binary file added images/defisafety-badge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions ngrok.config.template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "2"
region: "eu"
web_addr: 127.0.0.1:41356
tunnels:
web:
addr: 32318
proto: http
schemes: [http]
host_header: rewrite
rpc:
addr: 8545
proto: http
schemes: [http]
36 changes: 23 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
"**/react-scripts"
]
},
"engines": {
"node": ">=14.0.0 <17.0.0"
},
"release": {
"extends": "semantic-release-monorepo",
"branches": [
Expand All @@ -40,15 +43,19 @@
]
},
"scripts": {
"build": "run-s build:*",
"build": "run-s 'build:*'",
"build:dev-frontend": "yarn workspace @liquity/dev-frontend build",
"build:subgraph": "yarn workspace @liquity/subgraph build",
"deploy": "yarn workspace @liquity/lib-ethers hardhat deploy",
"docs": "run-s docs:*",
"deploy:chicken-bonds": "yarn --cwd ../ChickenBond deploy-fork compile publish:local",
"watch:chicken-bonds": "yarn --cwd ../ChickenBond watch",
"link:chicken-bonds": "yarn workspace @liquity/dev-frontend link:chicken-bonds",
"unlink:chicken-bonds": "yarn workspace @liquity/dev-frontend unlink:chicken-bonds",
"docs": "run-s 'docs:*'",
"docs:collect-sdk-apis": "node scripts/collect-sdk-apis.js",
"docs:api-documenter": "api-documenter generate -i temp/sdk-apis -o docs/sdk",
"fuzzer": "yarn workspace @liquity/fuzzer fuzzer",
"prepare": "run-s prepare:*",
"postinstall": "run-s prepare",
"prepare": "run-s 'prepare:*'",
"prepare:contracts": "yarn workspace @liquity/contracts prepare",
"prepare:lib-base": "yarn workspace @liquity/lib-base prepare",
"prepare:lib-ethers": "yarn workspace @liquity/lib-ethers prepare",
Expand All @@ -58,35 +65,37 @@
"prepare:subgraph": "yarn workspace @liquity/subgraph prepare",
"prepare:docs": "run-s docs",
"rebuild": "run-s prepare build",
"release": "run-s release:*",
"release": "run-s 'release:*'",
"release:delete-dev-deployments": "yarn workspace @liquity/lib-ethers delete-dev-deployments",
"release:lib-base": "yarn workspace @liquity/lib-base semantic-release",
"release:lib-ethers": "yarn workspace @liquity/lib-ethers semantic-release",
"release:lib-react": "yarn workspace @liquity/lib-react semantic-release",
"release:providers": "yarn workspace @liquity/providers semantic-release",
"save-live-version": "yarn workspace @liquity/lib-ethers save-live-version",
"start-dev-chain": "run-s start-dev-chain:*",
"start-dev-chain": "run-s 'start-dev-chain:*'",
"start-dev-chain:openethereum": "node dev-chain/start.js",
"start-dev-chain:prepare-providers": "yarn prepare:providers",
"start-dev-chain:deploy-contracts": "yarn deploy --network dev",
"start-dev-chain:prepare-lib-ethers": "yarn prepare:lib-ethers",
"stop-dev-chain": "docker kill openethereum",
"start-dev-frontend": "yarn workspace @liquity/dev-frontend start",
"start-demo": "run-s start-demo:*",
"start-demo": "run-s 'start-demo:*'",
"start-demo:dev-chain": "yarn start-dev-chain",
"start-demo:dev-frontend": "yarn workspace @liquity/dev-frontend start-demo",
"stop-demo": "yarn stop-dev-chain",
"test": "run-s test:*",
"start-fork": "hardhat --config hardhat.config.mainnet-fork.ts node",
"start-tunnel": "./scripts/start-local-tunnel.sh",
"test": "run-s 'test:*'",
"test:lib-base": "yarn workspace @liquity/lib-base test",
"test:lib-ethers": "yarn workspace @liquity/lib-ethers test",
"test:dev-frontend": "run-s --continue-on-error test:dev-frontend:*",
"test:dev-frontend": "run-s --continue-on-error 'test:dev-frontend:*'",
"test:dev-frontend:start-dev-chain": "yarn start-dev-chain",
"test:dev-frontend:run": "yarn workspace @liquity/dev-frontend test --watchAll=false --forceExit --detectOpenHandles",
"test:dev-frontend:run": "yarn workspace @liquity/dev-frontend test run",
"test:dev-frontend:stop-dev-chain": "yarn stop-dev-chain",
"test-contracts": "yarn workspace @liquity/contracts test",
"test-live": "run-s test-live:*",
"test-live": "run-s 'test-live:*'",
"test-live:lib-ethers": "yarn workspace @liquity/lib-ethers test-live",
"coverage": "run-s coverage:*",
"coverage": "run-s 'coverage:*'",
"coverage:contracts": "yarn workspace @liquity/contracts coverage"
},
"devDependencies": {
Expand All @@ -98,5 +107,6 @@
"prettier": "^2.1.2",
"semantic-release": "^17.4.2",
"semantic-release-monorepo": "^7.0.4"
}
},
"packageManager": "[email protected]"
}
Loading

0 comments on commit f79fc03

Please sign in to comment.