diff --git a/.github/workflows/_update.yml b/.github/workflows/_update.yml new file mode 100644 index 0000000..1080fe1 --- /dev/null +++ b/.github/workflows/_update.yml @@ -0,0 +1,64 @@ +--- +name: Update CSM rewards tree + +on: + workflow_call: + inputs: + branch: + description: branch to commit the changes + required: true + type: string + distributor: + description: CSFeeDistributor address + required: true + type: string + +permissions: + contents: write + +jobs: + script: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + + - name: Set up Python 3.12 + uses: actions/setup-python@v4 + with: + python-version: "3.12" + + - name: Setup poetry + run: > + curl -sSL https://install.python-poetry.org | python - && + echo "$POETRY_HOME/bin" >> "$GITHUB_PATH" + env: + POETRY_HOME: "/opt/poetry" + POETRY_VERSION: 1.8.3 + + - name: Install dependencies + run: poetry install --no-interaction + + - name: Generate types + run: poetry run wake up pytypes + + - name: Run script + run: poetry run wake run main.py + id: script + env: + RPC_URL: ${{ inputs.branch == 'testnet' && secrets.RPC_URL_HOLESKY || secrets.RPC_URL_MAINNET }} + GW3_ACCESS_KEY: ${{ secrets.GW3_ACCESS_KEY }} + GW3_SECRET_KEY: ${{ secrets.GW3_SECRET_KEY }} + DISTRIBUTOR_ADDRESS: ${{ inputs.distributor }} + + - name: Commit new artifacts + if: ${{ steps.script.outputs.updated == 'True' }} + run: | + git config --global user.name "madlabman" + git config --global user.email "10616301+madlabman@users.noreply.github.com" + git add "*.json" + git commit -m "chore: update tree and proofs" -m "CID: ${{ steps.script.outputs.cid }}" + git fetch origin + git rebase --strategy-option=ours "origin/${{ inputs.branch }}" + git push diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 0000000..7500caf --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,18 @@ +--- +name: Automated update + +on: + schedule: + - cron: "0 */1 * * *" + workflow_dispatch: + +permissions: + contents: write + +jobs: + testnet: + uses: ./.github/workflows/_update.yml + with: + branch: testnet + distributor: "0xD7ba648C8F72669C6aE649648B516ec03D07c8ED" + secrets: inherit diff --git a/README.md b/README.md index de5cd36..6e5c0f6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ -**Latest [proofs](./proofs.json)** +If you're a Node Operator in CSM, you get staking rewards as a part of Lido +protocol fees. -**Latest [tree](./tree.json)** +The allocation of rewards for CSM operators using a Merkle tree is provided by +CSM Performance Oracle once in a frame, making a new portion of the rewards +available for claim. + +Here you can find the latest [rewards tree](./tree.json) as well as the +pre-generated [proofs](./proofs.json) for your convenience. diff --git a/main.py b/main.py index a579045..db8b1d1 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ import json import os +import subprocess import sys from wake.deployment import Address, default_chain, print @@ -37,7 +38,7 @@ def main(): proofs = { f"CSM Operator {v["value"][0]}": { - "leaf": tree.leaf(v["value"]), + "cumulativeFeeShares": v["value"][1], "proof": list(tree.get_proof(v["treeIndex"])), } for v in dump["values"] @@ -46,6 +47,23 @@ def main(): with open("proofs.json", "w", encoding="utf-8") as fp: json.dump(proofs, fp, indent=2, default=default) + github_output = os.getenv("GITHUB_OUTPUT", None) + if not github_output: + return + + git_diff = subprocess.run(["git", "diff", "--exit-code", "--quiet", "tree.json"]) + + with open(github_output, "a", encoding="utf-8") as fp: + fp.write( + "\n".join( + [ + "", + f"cid={cid}", + f"updated={git_diff.returncode != 0}", + ] + ) + ) + def default(o): if isinstance(o, bytes): diff --git a/proofs.json b/proofs.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/proofs.json @@ -0,0 +1 @@ +{} diff --git a/tree.json b/tree.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tree.json @@ -0,0 +1 @@ +{}