From 14c5803c705ea162636910e14e681f3a3cd6f8de Mon Sep 17 00:00:00 2001 From: Marcus Aurelius Date: Wed, 17 Jan 2024 22:11:49 -0500 Subject: [PATCH] Add CCO2 price feed bot based on KLIMA/CCO2 pool --- .github/workflows/deploy.yaml | 1 + README.md | 1 + k8s/cco2_price/deployment_set_bot.yaml | 16 ++++++++ k8s/cco2_price/kustomization.yaml | 13 ++++++ k8s/kustomization.yaml | 3 +- k8s/secret.properties.template | 1 + src/cco2_price/__init__.py | 0 src/cco2_price/main.py | 56 ++++++++++++++++++++++++++ src/constants.py | 2 + src/contract_info.py | 4 +- 10 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 k8s/cco2_price/deployment_set_bot.yaml create mode 100644 k8s/cco2_price/kustomization.yaml create mode 100644 src/cco2_price/__init__.py create mode 100644 src/cco2_price/main.py diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index ed8cc30..cc26ba0 100755 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -51,6 +51,7 @@ jobs: DISCORD_BOT_TOKEN_KLIMA_PRICE: ${{ secrets.DISCORD_BOT_TOKEN_KLIMA_PRICE }} DISCORD_BOT_TOKEN_BCT_PRICE: ${{ secrets.DISCORD_BOT_TOKEN_BCT_PRICE }} DISCORD_BOT_TOKEN_MCO2_PRICE: ${{ secrets.DISCORD_BOT_TOKEN_MCO2_PRICE }} + DISCORD_BOT_TOKEN_CCO2_PRICE: ${{ secrets.DISCORD_BOT_TOKEN_CCO2_PRICE }} DISCORD_BOT_TOKEN_STAKING_REWARDS: ${{ secrets.DISCORD_BOT_TOKEN_STAKING_REWARDS }} DISCORD_BOT_TOKEN_SUPPLY_CC: ${{ secrets.DISCORD_BOT_TOKEN_SUPPLY_CC }} DISCORD_BOT_TOKEN_INDEX: ${{ secrets.DISCORD_BOT_TOKEN_INDEX }} diff --git a/README.md b/README.md index 68f0f28..0e73798 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ These variables must also be defined, and will be used to replace variables in t - `DISCORD_BOT_TOKEN_BCT_PRICE` - `DISCORD_BOT_TOKEN_MCO2_PRICE` - `DISCORD_BOT_TOKEN_STAKING_REWARDS` +- `DISCORD_BOT_TOKEN_CCO2_PRICE` #### Digital Ocean App Platform diff --git a/k8s/cco2_price/deployment_set_bot.yaml b/k8s/cco2_price/deployment_set_bot.yaml new file mode 100644 index 0000000..3a2ab64 --- /dev/null +++ b/k8s/cco2_price/deployment_set_bot.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bot +spec: + template: + spec: + containers: + - name: bot + args: ["src.cco2_price.main"] + env: + - name: DISCORD_BOT_TOKEN + valueFrom: + secretKeyRef: + name: discord-bots-secret + key: DISCORD_BOT_TOKEN_CCO2_PRICE diff --git a/k8s/cco2_price/kustomization.yaml b/k8s/cco2_price/kustomization.yaml new file mode 100644 index 0000000..62653b5 --- /dev/null +++ b/k8s/cco2_price/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../base + +namePrefix: cco2-price- + +commonLabels: + bot: cco2-price + +patchesStrategicMerge: + - deployment_set_bot.yaml diff --git a/k8s/kustomization.yaml b/k8s/kustomization.yaml index 0831060..236cce0 100644 --- a/k8s/kustomization.yaml +++ b/k8s/kustomization.yaml @@ -23,10 +23,11 @@ resources: - ./retirement_fee_info - ./dao_fee - ./dao_balance + - ./cco2_price namespace: discord-bots secretGenerator: - name: discord-bots-secret - envs: + envs: - secret.properties diff --git a/k8s/secret.properties.template b/k8s/secret.properties.template index 48bd166..feae9d9 100644 --- a/k8s/secret.properties.template +++ b/k8s/secret.properties.template @@ -8,6 +8,7 @@ DISCORD_BOT_TOKEN_MCO2_PRICE=${DISCORD_BOT_TOKEN_MCO2_PRICE} DISCORD_BOT_TOKEN_MOSS_PRICE=${DISCORD_BOT_TOKEN_MOSS_PRICE} DISCORD_BOT_TOKEN_NBO_PRICE=${DISCORD_BOT_TOKEN_NBO_PRICE} DISCORD_BOT_TOKEN_NCT_PRICE=${DISCORD_BOT_TOKEN_NCT_PRICE} +DISCORD_BOT_TOKEN_CCO2_PRICE=${DISCORD_BOT_TOKEN_CCO2_PRICE} DISCORD_BOT_TOKEN_REBASE=${DISCORD_BOT_TOKEN_REBASE} DISCORD_BOT_TOKEN_STAKING_REWARDS=${DISCORD_BOT_TOKEN_STAKING_REWARDS} DISCORD_BOT_TOKEN_SUPPLY_CC=${DISCORD_BOT_TOKEN_SUPPLY_CC} diff --git a/src/cco2_price/__init__.py b/src/cco2_price/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/cco2_price/main.py b/src/cco2_price/main.py new file mode 100644 index 0000000..6ba13bb --- /dev/null +++ b/src/cco2_price/main.py @@ -0,0 +1,56 @@ +import os +from discord.ext import tasks + +from ..constants import CCO2_ADDRESS, KLIMA_CCO2_POOL, KLIMA_DECIMALS +from ..contract_info import uni_v2_pool_price, token_supply, klima_usdc_price +from ..utils import get_polygon_web3, \ + get_discord_client, load_abi, prettify_number, \ + update_nickname, update_presence + +BOT_TOKEN = os.environ["DISCORD_BOT_TOKEN"] + +# Initialized Discord client +client = get_discord_client() + +# Initialize web3 +web3 = get_polygon_web3() + +# Load ABIs +cco2_abi = load_abi('carbon_pool.json') + + +@client.event +async def on_ready(): + print('Logged in as {0.user}'.format(client)) + if not update_info.is_running(): + update_info.start() + + +@tasks.loop(seconds=300) +async def update_info(): + klima_price = klima_usdc_price(web3) + token_price = uni_v2_pool_price( + web3, KLIMA_CCO2_POOL, + KLIMA_DECIMALS + ) + supply = token_supply(web3, CCO2_ADDRESS, cco2_abi) + + if klima_price is not None and token_price is not None and supply is not None: + price = klima_price * token_price + price_text = f'${price:,.3f} CCO2' + + print(price_text) + + success = await update_nickname(client, price_text) + if not success: + return + + supply_text = f'Supply: {prettify_number(supply)}' + success = await update_presence( + client, + supply_text + ) + if not success: + return + +client.run(BOT_TOKEN) diff --git a/src/constants.py b/src/constants.py index cd4919a..c19d36a 100755 --- a/src/constants.py +++ b/src/constants.py @@ -23,6 +23,7 @@ NCT_ADDRESS = Web3.to_checksum_address('0xD838290e877E0188a4A44700463419ED96c16107') UBO_ADDRESS = Web3.to_checksum_address('0x2B3eCb0991AF0498ECE9135bcD04013d7993110c') USDC_ADDRESS = Web3.to_checksum_address('0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174') +CCO2_ADDRESS = Web3.to_checksum_address('0x82B37070e43C1BA0EA9e2283285b674eF7f1D4E2') # LP Pool Addresses BCT_KLIMA_POOL = Web3.to_checksum_address('0x9803c7ae526049210a1725f7487af26fe2c24614') @@ -33,6 +34,7 @@ MOSS_USDC_POOL = Web3.to_checksum_address('0x75a7360e330c338007CF482e2CDf0A06573763A1') UBO_KLIMA_POOL = Web3.to_checksum_address('0x5400A05B8B45EaF9105315B4F2e31F806AB706dE') USDC_NCT_POOL = Web3.to_checksum_address('0xdb995f975f1bfc3b2157495c47e4efb31196b2ca') +KLIMA_CCO2_POOL = Web3.to_checksum_address('0x4D2263FF85e334C1f1d04C6262F6c2580335a93C') # Klima Protocol Contracts STAKING_ADDRESS = Web3.to_checksum_address('0x25d28a24Ceb6F81015bB0b2007D795ACAc411b4d') diff --git a/src/contract_info.py b/src/contract_info.py index beec938..901ff33 100755 --- a/src/contract_info.py +++ b/src/contract_info.py @@ -31,7 +31,7 @@ def klima_usdc_price(web3): ) -def token_supply(web3, token_address, abi, decimals): +def token_supply(web3, token_address, abi, decimals=None): ''' Compute the total supply of the specified ERC-20 token at `token_address` with `abi` and the correct `decimals` ''' @@ -41,6 +41,8 @@ def token_supply(web3, token_address, abi, decimals): ) try: + if decimals is None: + decimals = contract.functions.decimals().call() total_supply = contract.functions.totalSupply().call() / 10**decimals return total_supply except Exception: