-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #459 from lidofinance/eth-steth
Eth steth
- Loading branch information
Showing
56 changed files
with
13,615 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules/ | ||
dist/ | ||
forta.config.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"parser": "@typescript-eslint/parser", | ||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], | ||
"plugins": ["@typescript-eslint", "prettier"], | ||
"env": { | ||
"node": true, | ||
"es6": true | ||
}, | ||
"rules": { | ||
"prettier/prettier": "error", | ||
"curly": "error", | ||
"semi": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
node_modules | ||
dist | ||
forta.config.json | ||
.yarn/* | ||
!.yarn/releases/ | ||
*.log | ||
version.json | ||
.DS_Store | ||
/coverage/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"semi": false, | ||
"trailingComma": "all", | ||
"singleQuote": true, | ||
"printWidth": 120, | ||
"tabWidth": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Build stage: compile Typescript to Javascript | ||
FROM node:20.10.0-alpine3.18 AS base | ||
|
||
FROM base as builder | ||
|
||
WORKDIR /app | ||
|
||
COPY . . | ||
RUN yarn install --immutable && yarn run build | ||
# Build app | ||
RUN yarn run build | ||
|
||
# Final stage: copy compiled Javascript from previous stage and install production dependencies | ||
FROM base as production | ||
LABEL "network.forta.settings.agent-logs.enable"="true" | ||
ENV NODE_ENV=production | ||
WORKDIR /app | ||
|
||
COPY package*.json yarn.lock ./ | ||
COPY --from=builder /app/node_modules ./node_modules | ||
COPY --from=builder /app/dist ./src | ||
COPY version.json ./ | ||
|
||
CMD ["yarn", "run", "start:prod"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# Lido Ethereum StETH bot | ||
|
||
## Supported chains | ||
|
||
- Ethereum mainnet | ||
|
||
## Alerts | ||
|
||
1. StETH operations | ||
1. HandleBlock | ||
1. 🚨🚨🚨 Buffered ETH drain (checks each block) | ||
2. 🚨 Huge depositable ETH amount (checks every 100 blocks) | ||
3. ⚠️ High depositable ETH amount (checks every 100 blocks) | ||
4. ⚠️ Low deposit executor balance (checks every 100 blocks) | ||
5. ⚠️ Unspent staking limit below 10% (checks every 25 blocks) | ||
6. 📉 Unspent staking limit below 30% (checks every 25 blocks) | ||
2. HandleTransaction | ||
1. Deposit Security events | ||
2. 🚨 Deposit Security: Deposits paused | ||
3. 🚨 Deposit Security: Guardian quorum changed | ||
4. 🚨 Deposit Security: Owner changed | ||
5. ⚠️ Deposit Security: Deposits resumed | ||
6. ⚠️ Deposit Security: Guardian added | ||
7. ⚠️ Deposit Security: Guardian removed | ||
8. ⚠️ Deposit Security: Max deposits changed | ||
9. ⚠️ Deposit Security: Min deposit block distance changed | ||
3. Lido events | ||
1. 🚨🚨🚨 Lido: Stopped 🚨🚨🚨 | ||
2. 🚨🚨🚨 Share rate unexpected has changed | ||
3. 🚨 Lido: Staking limit removed | ||
4. 🚨 Lido: Locator set | ||
5. ⚠️ Lido: Resumed | ||
6. 🚨 Lido: Staking paused | ||
7. ⚠️ Lido: Staking resumed | ||
8. ⚠️ Lido: Staking limit set | ||
9. ⚠️ Lido: Funds recovered to vault | ||
10. ⚠️ Lido: Contract version set | ||
11. ℹ️ Lido: Token rebased | ||
4. Insurance fund events | ||
1. 🚨 Insurance fund: ERC20 transferred | ||
2. 🚨 Insurance fund: Ownership transferred | ||
3. ⚠️ Insurance fund: ETH transferred | ||
4. ⚠️ Insurance fund: ERC1155 transferred | ||
5. ⚠️ Insurance fund: ERC721 transferred | ||
5. Burner events | ||
1. ℹ️ Lido Burner: ERC20 recovered | ||
2. ℹ️ Lido Burner: ERC721 recovered | ||
2. Withdrawals | ||
1. HandleBlock runs on each 100-th block or one per 20 minutes | ||
1. ⚠️ Withdrawals: <limitRate>% of stake limit is spent and unfinalized queue is on par with drained stake | ||
limit | ||
2. ⚠️ Withdrawals: unfinalized queue is more than 100_000 stETH | ||
3. ⚠️ Withdrawals: unfinalized queue wait time is <hours> more than 1 day | ||
4. ⚠️ Withdrawals: ${unclaimedSizeRate.times(100).toFixed(2)}% of finalized requests are unclaimed | ||
5. ⚠️ Withdrawals: unclaimed requests size is more than withdrawal queue balance | ||
2. HandleTransaction | ||
1. 🚨 Withdrawals: BUNKER MODE ON! 🚨 | ||
2. 🚨 Withdrawals: contract was paused | ||
3. ⚠️ Withdrawals: BUNKER MODE OFF! ✅ | ||
4. ℹ️ Huge stETH withdrawal requests batch | ||
5. ⚠️ Withdrawals: the sum of received withdrawal requests since the last rebase greater than 150_000 stETH (max | ||
staking limit) | ||
6. ⚠️ Withdrawals: claimed amount is more than requested | ||
7. ⚠️ Withdrawals: contract was unpaused | ||
3. GateSeal | ||
1. HandleBlock runs on each next block | ||
1. 🚨 GateSeal: actual address doesn't have PAUSE_ROLE for contracts | ||
2. 🚨 GateSeal: is expired! | ||
3. 🚨️ GateSeal: is expired. Update code! | ||
4. ⚠️ GateSeal: default GateSeal address in forta agent is expired | ||
5. ⚠️️ GateSeal: default GateSeal address in forta agent doesn't have PAUSE_ROLE for contracts | ||
6. ⚠️ GateSeal: is about to be expired | ||
2. HandleTransaction | ||
1. 🚨🚨🚨 GateSeal: is sealed 🚨🚨🚨 | ||
2. 🚨 GateSeal: is expired | ||
4. Vaults | ||
1. Handleblock | ||
1. 🚨🚨🚨 Withdrawal Vault balance mismatch. [without oracle report] | ||
2. 🚨🚨🚨 Withdrawal Vault balance mismatch. [within oracle report] | ||
3. 🚨🚨🚨 EL Vault balance mismatch. [without oracle report] | ||
4. 🚨🚨🚨 EL Vault balance mismatch. [within oracle report] | ||
5. 💵 Withdrawal Vault Balance significant change (checks every on 100-th block) | ||
6. 💵 EL Vault Balance significant change | ||
2. HandleTransaction | ||
1. 🚨 Burner shares transfer | ||
|
||
## Development (Forta specific) | ||
|
||
Edit `alerting-forta/<SUBMODULE>/forta.config.json` and set `jsonRpcUrl` to your JSON-RPC provider. Install deps: | ||
|
||
``` | ||
yarn install | ||
``` | ||
|
||
Running in a live mode: | ||
|
||
``` | ||
yarn start:dev | ||
``` | ||
|
||
Testing on a specific block/range/transaction: | ||
|
||
``` | ||
yarn block 13626668 | ||
yarn range '13626667..13626668' | ||
yarn tx 0x2d2774c04e3faf9f17cd26e0978bb812081b9d0b5cc6fd8bf04cc441f92c0a8c | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** @type {import("ts-jest").JestConfigWithTsJest} */ | ||
module.exports = { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
testPathIgnorePatterns: ['dist'], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
{ | ||
"name": "lido-steth-forta-bot", | ||
"version": "1.0.0", | ||
"description": "Forta Bot for Lido stETH", | ||
"repository": { | ||
"type": "git", | ||
"directory": "https://github.com/lidofinance/alerting-forta/tree/main/ethereum-steth" | ||
}, | ||
"license": "MIT", | ||
"chainIds": [ | ||
1 | ||
], | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "yarn run lint" | ||
} | ||
}, | ||
"scripts": { | ||
"update-version": "node ../utils/write-version.js", | ||
"build": "tsc && yarn run copy-version", | ||
"copy-version": "cp version.json dist", | ||
"start": "yarn run update-version && yarn run start:dev", | ||
"start:dev": "nodemon --watch src --watch forta.config.json -e js,ts,json --exec \"yarn run build && yarn run copy-version && forta-agent run\"", | ||
"start:prod": "forta-agent run --prod", | ||
"tx": "yarn run build && forta-agent run --tx", | ||
"block": "yarn run build && forta-agent run --block", | ||
"range": "yarn run build && forta-agent run --range", | ||
"alert": "yarn run build && forta-agent run --alert", | ||
"sequence": "yarn run build && forta-agent run --sequence", | ||
"file": "yarn run build && forta-agent run --file", | ||
"publish": "yarn run update-version && forta-agent publish", | ||
"info": "forta-agent info", | ||
"logs": "forta-agent logs", | ||
"push": "yarn run update-version && forta-agent push", | ||
"disable": "forta-agent disable", | ||
"enable": "forta-agent enable", | ||
"keyfile": "forta-agent keyfile", | ||
"stake": "forta-agent stake", | ||
"test": "jest", | ||
"generate-types": "typechain --target=ethers-v5 --out-dir=./src/generated ./src/abi/*", | ||
"eslint:lint": "eslint ./src ./tests", | ||
"eslint:format": "eslint ./src ./tests --fix", | ||
"prettier:check": "prettier --check ./src ./tests", | ||
"prettier:format": "prettier --write ./src ./tests README.md", | ||
"lint": "yarn run prettier:check && yarn run eslint:lint", | ||
"format": "yarn run eslint:format && yarn run prettier:format", | ||
"postinstall": "yarn generate-types" | ||
}, | ||
"dependencies": { | ||
"@types/lodash": "^4.14.202", | ||
"async-mutex": "^0.4.0", | ||
"bignumber.js": "^9.1.2", | ||
"ethers": "^5.5.1", | ||
"forta-agent": "^0.1.48", | ||
"fp-ts": "^2.16.1", | ||
"lodash": "^4.17.21", | ||
"ts-retry": "^4.2.4", | ||
"winston": "^3.11.0", | ||
"@ethersproject/abi": "^5.0.0", | ||
"@ethersproject/providers": "^5.0.0" | ||
}, | ||
"devDependencies": { | ||
"@faker-js/faker": "^8.3.1", | ||
"@jest/globals": "^29.7.0", | ||
"@tsconfig/node20": "^20.1.2", | ||
"@typechain/ethers-v5": "^11.1.2", | ||
"@types/jest": "^29.5.11", | ||
"@types/nodemon": "^1.19.0", | ||
"@types/ws": "^8.5.10", | ||
"@typescript-eslint/eslint-plugin": "^6.12.0", | ||
"@typescript-eslint/parser": "^6.12.0", | ||
"eslint": "^8.54.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"eslint-plugin-jest": "^27.6.0", | ||
"eslint-plugin-prettier": "^5.0.1", | ||
"husky": "^8.0.3", | ||
"jest": "^29.7.0", | ||
"nodemon": "^3.0.1", | ||
"postinstall": "^0.8.0", | ||
"prettier": "^3.1.0", | ||
"ts-generator": "^0.1.1", | ||
"ts-jest": "^29.1.2", | ||
"typechain": "^8.3.2", | ||
"typescript": "^5.3.2" | ||
}, | ||
"packageManager": "yarn@1.22.21" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
[ | ||
{ | ||
"name": "Sealed", | ||
"inputs": [ | ||
{ "name": "gate_seal", "type": "address", "indexed": false }, | ||
{ "name": "sealed_by", "type": "address", "indexed": false }, | ||
{ "name": "sealed_for", "type": "uint256", "indexed": false }, | ||
{ "name": "sealable", "type": "address", "indexed": false }, | ||
{ "name": "sealed_at", "type": "uint256", "indexed": false } | ||
], | ||
"anonymous": false, | ||
"type": "event" | ||
}, | ||
{ | ||
"stateMutability": "nonpayable", | ||
"type": "constructor", | ||
"inputs": [ | ||
{ "name": "_sealing_committee", "type": "address" }, | ||
{ "name": "_seal_duration_seconds", "type": "uint256" }, | ||
{ "name": "_sealables", "type": "address[]" }, | ||
{ "name": "_expiry_timestamp", "type": "uint256" } | ||
], | ||
"outputs": [] | ||
}, | ||
{ | ||
"stateMutability": "view", | ||
"type": "function", | ||
"name": "get_sealing_committee", | ||
"inputs": [], | ||
"outputs": [{ "name": "", "type": "address" }] | ||
}, | ||
{ | ||
"stateMutability": "view", | ||
"type": "function", | ||
"name": "get_seal_duration_seconds", | ||
"inputs": [], | ||
"outputs": [{ "name": "", "type": "uint256" }] | ||
}, | ||
{ | ||
"stateMutability": "view", | ||
"type": "function", | ||
"name": "get_sealables", | ||
"inputs": [], | ||
"outputs": [{ "name": "", "type": "address[]" }] | ||
}, | ||
{ | ||
"stateMutability": "view", | ||
"type": "function", | ||
"name": "get_expiry_timestamp", | ||
"inputs": [], | ||
"outputs": [{ "name": "", "type": "uint256" }] | ||
}, | ||
{ | ||
"stateMutability": "view", | ||
"type": "function", | ||
"name": "is_expired", | ||
"inputs": [], | ||
"outputs": [{ "name": "", "type": "bool" }] | ||
}, | ||
{ | ||
"stateMutability": "nonpayable", | ||
"type": "function", | ||
"name": "seal", | ||
"inputs": [{ "name": "_sealables", "type": "address[]" }], | ||
"outputs": [] | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
[ | ||
{ | ||
"name": "GateSealCreated", | ||
"inputs": [{ "name": "gate_seal", "type": "address", "indexed": false }], | ||
"anonymous": false, | ||
"type": "event" | ||
}, | ||
{ | ||
"stateMutability": "nonpayable", | ||
"type": "constructor", | ||
"inputs": [{ "name": "_blueprint", "type": "address" }], | ||
"outputs": [] | ||
}, | ||
{ | ||
"stateMutability": "view", | ||
"type": "function", | ||
"name": "get_blueprint", | ||
"inputs": [], | ||
"outputs": [{ "name": "", "type": "address" }] | ||
}, | ||
{ | ||
"stateMutability": "nonpayable", | ||
"type": "function", | ||
"name": "create_gate_seal", | ||
"inputs": [ | ||
{ "name": "_sealing_committee", "type": "address" }, | ||
{ "name": "_seal_duration_seconds", "type": "uint256" }, | ||
{ "name": "_sealables", "type": "address[]" }, | ||
{ "name": "_expiry_timestamp", "type": "uint256" } | ||
], | ||
"outputs": [] | ||
} | ||
] |
Oops, something went wrong.