Skip to content

Commit

Permalink
Mellow integration (#247)
Browse files Browse the repository at this point in the history
* chore: set default strategy

* Upgrade python to 3.12

* Upgrade poetry

* upgrade curl

* Mellow mvp (#224)

* Mellow direct deposit, skip ABI

* Prepare direct deposit transaction

* Property checking

* Fix linter

* amount parameter in the contract

* Fix comments

* Check variable not set

* Contract abi integration test

* Add fixtures

* Remove amount parameter from abi

* Formatter changes

* Formatter changes

* Holesky mark in tests

* Test balanceOf of weth

* Renamings

* Rename mark

* block_identifier

* Update src/variables.py

Co-authored-by: Raman Siamionau <[email protected]>

* Fix comments

* Renamed env var in pipeline

* Change module to deposit

* Send mellow transaction

* Change comment

* DD description

* Update README.md

Co-authored-by: Raman Siamionau <[email protected]>

* Refactor sending mellow transaction

* Refactor sending mellow transaction

* is_mellow_depositable unit test

* Unit test for sending mellow tx

* Formatting

---------

Co-authored-by: Raman Siamionau <[email protected]>

* Metric for modules (#229)

* Expose modules metric

* Reorder

* Reorder

* Update src/metrics/metrics.py

Co-authored-by: Raman Siamionau <[email protected]>

---------

Co-authored-by: Raman Siamionau <[email protected]>

* Log env vars (#227)

* Log public env vars

* Add chain_id

* Public env vars in prometheus metric

* Add message to a log

* Change info description

* Update src/variables.py

Co-authored-by: Raman Siamionau <[email protected]>

* Update src/metrics/metrics.py

Co-authored-by: Raman Siamionau <[email protected]>

* Remove prefix, not assert

* Fix imports

---------

Co-authored-by: Raman Siamionau <[email protected]>

* Fix Info metircs endpoint(#231)

* Fix log string

* Change forematting

* Convert values to strings

* remove convertion

* Mellow deposit strategy (#230)

* Change validation for mellow deposits

* Load WQ contract from the locator

* Refactor

* Change log message

* Beffered ether

* Change ABI

* Move check inside is_mellow_depositable

* Add ping type to the rabbit messages in the unvetter

* Mellow new ABIs

* Remove old build metrics (#239)

* Add mellow variable to examples (#237)

* Add mellow variable to examples

* Remove import

* Update holesky address

* Add account to variables (#241)

* Add account to metrics

* Fix field ref

* Change to propery

* Direct access property

* Separate mellow flow (#235)

* Separate mellow flow

* Formatting

* Rerun integration tests

* Strategy return

* Rewrite to abstract classes

* Fix formatting

* Fix bug with return

* Restructure

* remove init

* _is_mellow

* Fix tests

* Fix signs test

* Fix integration

* Fix unit test

* Mellow test

* Update src/blockchain/deposit_strategy/base_deposit_strategy.py

Co-authored-by: Raman Siamionau <[email protected]>

* Refactor

* Renamings

* Imports

* inject dependecies

---------

Co-authored-by: Raman Siamionau <[email protected]>

* Metric per module (#244)

* Per module metric

* FOrmatting

* Fix error repr

---------

Co-authored-by: F4ever <[email protected]>
  • Loading branch information
hweawer and F4ever authored Aug 5, 2024
1 parent c5d9bed commit d73c534
Show file tree
Hide file tree
Showing 44 changed files with 1,200 additions and 665 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ DEPOSIT_MODULES_WHITELIST=1

# Prefix for the Prometheus metrics(depositor_bot,pauser_bot,unvetter_bot)
PROMETHEUS_PREFIX=depositor_bot

# Mellow strategy address for direct deposits
# Holesky: 0x182Cb3A76B0EFaCb25255F9594B5807460882fa4
MELLOW_CONTRACT_ADDRESS=0x182Cb3A76B0EFaCb25255F9594B5807460882fa4
17 changes: 14 additions & 3 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.11'
python-version: '3.12'

- name: Setup poetry
run: |
Expand All @@ -29,7 +29,18 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Integration tests with pytest
- name: Integration tests with pytest, holesky fork
run: |
poetry run pytest tests -m integration_holesky
env:
WEB3_RPC_ENDPOINTS: ${{ secrets.HOLESKY_WEB3_RPC_ENDPOINT }}
DEPOSIT_CONTRACT: "0x4242424242424242424242424242424242424242"
LIDO_LOCATOR: "0x28FAB2059C713A7F9D8c86Db49f9bb0e96Af1ef8"
MELLOW_CONTRACT_ADDRESS: "0x182Cb3A76B0EFaCb25255F9594B5807460882fa4"
ANVIL_PATH: ""

- name: Integration tests with pytest, mainnet fork
if: success() || failure()
run: |
poetry run pytest tests -m integration
env:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests-and-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.11'
python-version: '3.12'

- name: Setup poetry
run: |
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11.9-slim as base
FROM python:3.12.4-slim as base

RUN apt-get update && apt-get install -y --no-install-recommends -qq \
gcc=4:12.2.0-3 \
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Depositor and pauser bots are parts of [Deposit Security Module](https://github.
Once a sufficient number of messages is collected to constitute a quorum, the bot proceeds to initiate a deposit into the designated staking module.
This deposit is executed using the depositBufferedEther function within the "DepositSecurityModule" smart contract.

Direct deposit is a mechanism that allows depositors to use side vault facilities for deposits. This process transfers ETH from the vault and facilitates the deposit to specified in side vault staking module, preventing funds from being stuck in the withdrawal queue.

**The Pauser Bot** obtains pause message from Council Daemon and enacts pause deposits on protocol. Pause can occurs when Lido detects stealing.

**The Unvetting Bot** obtains unvet message from Council Daemon and enacts unvet on the specified node operator.
Expand Down Expand Up @@ -82,6 +84,8 @@ Unvetting is the proces of decreasing approved depositable signing keys.
| PROMETHEUS_PREFIX | depositor_bot | Prefix for the metrics |
| HEALTHCHECK_SERVER_PORT | 9010 | Port with bot`s status server |
| MAX_CYCLE_LIFETIME_IN_SECONDS | 1200 | Max lifetime of usual cycle. If cycle will not end in this time, bot will crush |
| MELLOW_CONTRACT_ADDRESS | None | If variable is set then deposit can go to predifined module |
| VAULT_DIRECT_DEPOSIT_THRESHOLD | 1 ether | If mellow vault has VAULT_DIRECT_DEPOSIT_THRESHOLD ethers then direct deposit will be sent |

## Metrics and logs

Expand Down Expand Up @@ -119,11 +123,13 @@ poetry run pytest tests -m unit
#### Run integration tests.

Install Anvil

```bash
poetry run pytest tests -m integration
```

In case of "command not found: anvil" error, provide `ANVIL_PATH` variable
In case of "command not found: anvil" error, provide `ANVIL_PATH` variable

```bash
export ANVIL_PATH='pathto/anvil'
```
Expand Down
1 change: 1 addition & 0 deletions interfaces/ERC20.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"constant": true, "inputs": [], "name": "name", "outputs": [{"name": "", "type": "string"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [{"name": "_spender", "type": "address"}, {"name": "_value", "type": "uint256"}], "name": "approve", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "totalSupply", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [{"name": "_from", "type": "address"}, {"name": "_to", "type": "address"}, {"name": "_value", "type": "uint256"}], "name": "transferFrom", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "decimals", "outputs": [{"name": "", "type": "uint8"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [{"name": "_owner", "type": "address"}], "name": "balanceOf", "outputs": [{"name": "balance", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "symbol", "outputs": [{"name": "", "type": "string"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [{"name": "_to", "type": "address"}, {"name": "_value", "type": "uint256"}], "name": "transfer", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [{"name": "_owner", "type": "address"}, {"name": "_spender", "type": "address"}], "name": "allowance", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"payable": true, "stateMutability": "payable", "type": "fallback"}, {"anonymous": false, "inputs": [{"indexed": true, "name": "owner", "type": "address"}, {"indexed": true, "name": "spender", "type": "address"}, {"indexed": false, "name": "value", "type": "uint256"}], "name": "Approval", "type": "event"}, {"anonymous": false, "inputs": [{"indexed": true, "name": "from", "type": "address"}, {"indexed": true, "name": "to", "type": "address"}, {"indexed": false, "name": "value", "type": "uint256"}], "name": "Transfer", "type": "event"}]
1 change: 1 addition & 0 deletions interfaces/SimpleDVTStakingStrategy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"contract IVault","name":"vault_","type":"address"},{"internalType":"contract IStakingModule","name":"stakingModule_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[],"name":"DepositFailed","type":"error"},{"inputs":[],"name":"Forbidden","type":"error"},{"inputs":[],"name":"InvalidWithdrawalQueueState","type":"error"},{"inputs":[],"name":"LimitOverflow","type":"error"},{"inputs":[],"name":"NotEnoughWeth","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"ConvertAndDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxAllowedRemainder","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"MaxAllowedRemainderChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"users","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amountForStake","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"ProcessWithdrawals","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"ADMIN_DELEGATE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct IDepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"convertAndDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAllowedRemainder","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"uint256","name":"amountForStake","type":"uint256"}],"name":"processWithdrawals","outputs":[{"internalType":"bool[]","name":"statuses","type":"bool[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"requireAdmin","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"requireAtLeastOperator","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxAllowedRemainder","type":"uint256"}],"name":"setMaxAllowedRemainder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingModule","outputs":[{"internalType":"contract IStakingModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
1 change: 1 addition & 0 deletions interfaces/StakingModule.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[{"internalType":"address","name":"weth_","type":"address"},{"internalType":"address","name":"steth_","type":"address"},{"internalType":"address","name":"wsteth_","type":"address"},{"internalType":"contract ILidoLocator","name":"lidoLocator_","type":"address"},{"internalType":"contract IWithdrawalQueue","name":"withdrawalQueue_","type":"address"},{"internalType":"uint256","name":"stakingModuleId_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"Forbidden","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidDepositRoot","type":"error"},{"inputs":[],"name":"InvalidWithdrawalQueueState","type":"error"},{"inputs":[],"name":"NotEnoughWeth","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Converted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"DepositCompleted","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"convert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"internalType":"bytes32","name":"depositRoot","type":"bytes32"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"depositCalldata","type":"bytes"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"vs","type":"bytes32"}],"internalType":"struct IDepositSecurityModule.Signature[]","name":"sortedGuardianSignatures","type":"tuple[]"}],"name":"convertAndDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lidoLocator","outputs":[{"internalType":"contract ILidoLocator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingModuleId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"steth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalQueue","outputs":[{"internalType":"contract IWithdrawalQueue","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wsteth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
1 change: 1 addition & 0 deletions interfaces/WithdrawalQueue.json

Large diffs are not rendered by default.

Loading

0 comments on commit d73c534

Please sign in to comment.