Skip to content

Commit

Permalink
feat: automated validation of tokens decimals (#87)
Browse files Browse the repository at this point in the history
* ci: workflow to validate tokens decimals
feat: bash script to validate token decimals
chore: .env example file
chore: remove redundant tokens from list

* polish comment
  • Loading branch information
smol-ninja authored Dec 2, 2024
1 parent 877f352 commit dd6b419
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 51 deletions.
27 changes: 27 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export API_KEY_INFURA="YOUR_RPC_API_KEY"

# Mainnets
export ARBITRUM_MAINNET_RPC_URL="https://arbitrum-mainnet.infura.io/v3/$API_KEY_INFURA"
export AVALANCHE_MAINNET_RPC_URL="https://avalanche-mainnet.infura.io/v3/$API_KEY_INFURA"
export BASE_MAINNET_RPC_URL="https://base-mainnet.infura.io/v3/$API_KEY_INFURA"
export BLAST_MAINNET_RPC_URL="https://blast-mainnet.infura.io/v3/$API_KEY_INFURA"
export BSC_MAINNET_RPC_URL="https://bsc-mainnet.infura.io/v3/$API_KEY_INFURA"
export ETHEREUM_MAINNET_RPC_URL="https://mainnet.infura.io/v3/$API_KEY_INFURA"
export GNOSIS_MAINNET_RPC_URL="YOUR_GNOSIS_MAINNET_RPC_URL"
export IOTEX_MAINNET_RPC_URL="YOUR_IOTEX_MAINNET_RPC_URL"
export LIGHTLINK_MAINNET_RPC_URL="YOUR_LIGHTLINK_MAINNET_RPC_URL"
export LINEA_MAINNET_RPC_URL="https://linea-mainnet.infura.io/v3/$API_KEY_INFURA"
export MODE_MAINNET_RPC_URL="YOUR_MODE_MAINNET_RPC_URL"
export MORPH_MAINNET_RPC_URL="YOUR_MORPH_MAINNET_RPC_URL"
export OPTIMISM_MAINNET_RPC_URL="https://optimism-mainnet.infura.io/v3/$API_KEY_INFURA"
export POLYGON_MAINNET_RPC_URL="https://polygon-mainnet.infura.io/v3/$API_KEY_INFURA"
export RONIN_MAINNET_RPC_URL="YOUR_RONIN_MAINNET_RPC_URL"
export SCROLL_MAINNET_RPC_URL="https://scroll-mainnet.infura.io/v3/$API_KEY_INFURA"
export SUPERSEED_MAINNET_RPC_URL="YOUR_SUPERSEED_MAINNET_RPC_URL"
export TANGLE_MAINNET_RPC_URL="YOUR_TANGLE_MAINNET_RPC_URL"
export ZKSYNC_MAINNET_RPC_URL="https://zksync-mainnet.infura.io/v3/$API_KEY_INFURA"

# Testnets
export BASE_SEPOLIA_RPC_URL="https://base-sepolia.infura.io/v3/$API_KEY_INFURA"
export RONIN_TESTNET_RPC_URL="YOUR_RONIN_TESTNET_RPC_URL"
export SEPOLIA_RPC_URL="https://sepolia.infura.io/v3/$API_KEY_INFURA"
45 changes: 45 additions & 0 deletions .github/workflows/tokenlist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: "CI Tokenlist"

env:
ARBITRUM_MAINNET_RPC_URL: "https://arbitrum-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
AVALANCHE_MAINNET_RPC_URL: "https://avalanche-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
BASE_MAINNET_RPC_URL: "https://base-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
BASE_SEPOLIA_RPC_URL: "https://base-sepolia.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
BLAST_MAINNET_RPC_URL: "https://blast-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
BSC_MAINNET_RPC_URL: "https://bsc-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
ETHEREUM_MAINNET_RPC_URL: "https://mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
GNOSIS_MAINNET_RPC_URL: ${{ secrets.GNOSIS_MAINNET_RPC_URL }}
IOTEX_MAINNET_RPC_URL: ${{ secrets.IOTEX_MAINNET_RPC_URL }}
LIGHTLINK_MAINNET_RPC_URL: ${{ secrets.LIGHTLINK_MAINNET_RPC_URL }}
LINEA_MAINNET_RPC_URL: "https://linea-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
MODE_MAINNET_RPC_URL: ${{ secrets.MODE_MAINNET_RPC_URL }}
MORPH_MAINNET_RPC_URL: ${{ secrets.MORPH_MAINNET_RPC_URL }}
OPTIMISM_MAINNET_RPC_URL: "https://optimism-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
POLYGON_MAINNET_RPC_URL: "https://polygon-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
RONIN_MAINNET_RPC_URL: ${{ secrets.RONIN_MAINNET_RPC_URL }}
RONIN_TESTNET_RPC_URL: ${{ secrets.RONIN_TESTNET_RPC_URL }}
SCROLL_MAINNET_RPC_URL: "https://scroll-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
SEPOLIA_RPC_URL: "https://sepolia.infura.io/v3/${{ secrets.API_KEY_INFURA }}"
SUPERSEED_MAINNET_RPC_URL: ${{ secrets.SUPERSEED_MAINNET_RPC_URL }}
TANGLE_MAINNET_RPC_URL: ${{ secrets.TANGLE_MAINNET_RPC_URL }}
ZKSYNC_MAINNET_RPC_URL: "https://zksync-mainnet.infura.io/v3/${{ secrets.API_KEY_INFURA }}"

on:
workflow_dispatch:
pull_request:
push:
branches:
- "main"
schedule:
- cron: "0 3 * * 0" # at 3:00am UTC every Sunday

jobs:
check-tokenlist:
runs-on: "ubuntu-latest"
steps:
- name: "Check out the repo"
uses: "actions/checkout@v4"

- name: "Check decimals for tokens list"
run: ./shell/tokenlist.sh
shell: bash
75 changes: 75 additions & 0 deletions shell/tokenlist.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash

# Pre-requisites for running this script:
#
# - bash >=4.0.0
# - .env file

set -euo pipefail

# Source variables from .env file if it exists.
if [ -f .env ]; then
export $(grep -v '^#' .env | xargs)
source <(envsubst < .env)
fi

# Loop through files in `src/tokens` directory
for file in src/tokens/*.json; do
json_objects=$(cat "$file")

# Extract the filename and replace '-' with '_'
network=$(basename "$file" .json | tr '-' '_' | tr '[:lower:]' '[:upper:]')

echo -n "Decimals for $network tokens list: "

# Construct the RPC URL variable name from filename
rpc_url_var="${network}_RPC_URL"

# Load the RPC URL from the environment variable
rpc_url=${!rpc_url_var}

# Loop through JSON objects and extract address and token decimals
echo "$json_objects" | jq -c '.[]' | while read -r row; do
address=$(echo "$row" | jq -r '.address')
token_decimal=$(echo "$row" | jq -r '.decimals')

# Indicate progress
echo -n "."

# Make request through RPC
response=$(curl -sS $rpc_url \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_call",
"params": [{
"to": "'"$address"'",
"data": "0x313ce567"
}, "latest"],
"id": 1
}')

# Get token decimals (base-16) from curl response, exit if response is not valid
if ! actual_decimals=$(echo $response | jq -r '.result'); then
echo -e "\e[31m🔴 $response"
exit 1
fi

# Convert token decimals to base-10, exit if response is not valid
if ! actual_decimals=$(printf "%d" "$actual_decimals"); then
echo -e "🟡 Invalid for $address, could be an RPC issue, manual check is recommended."
continue
fi

# Compare token decimal with actual decimals and throw if they do not match
if [ "$token_decimal" -ne "$actual_decimals" ]; then
echo -e "\e[31m🔴 Mismatch for $address. Set to $token_decimal. Should be $actual_decimals\e[0m"
exit 1
fi

done

# Log success
echo -e "\e[32m🟢 Valid\e[0m"
done
10 changes: 1 addition & 9 deletions src/tokens/avalanche-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,6 @@
"name": "USD Coin",
"symbol": "USDC"
},
{
"address": "0x416494bD4FbEe227313b76a07A1e859928D7bA47",
"chainId": 43114,
"decimals": 18,
"logoURI": "https://files.sablier.com/tokens/USDCe-TIC-SLP.e.png",
"name": "USDCe-TIC SLP",
"symbol": "USDCe-TIC-SLP.e"
},
{
"address": "0xaBC9547B534519fF73921b1FBA6E672b5f58D083",
"chainId": 43114,
Expand Down Expand Up @@ -218,7 +210,7 @@
{
"address": "0x47c3118Ad183712Acd42648e9E522e13690f29a0",
"chainId": 43114,
"decimals": 18,
"decimals": 6,
"logoURI": "https://files.sablier.com/tokens/MEAT.png",
"name": "Meat",
"symbol": "MEAT"
Expand Down
2 changes: 1 addition & 1 deletion src/tokens/bsc-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
{
"address": "0x7ad7242A99F21aa543F9650A56D141C57e4F6081",
"chainId": 56,
"decimals": 18,
"decimals": 9,
"logoURI": "https://files.sablier.com/tokens/JADE.png",
"name": "Jade Protocol",
"symbol": "JADE"
Expand Down
38 changes: 6 additions & 32 deletions src/tokens/ethereum-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
{
"address": "0xdB25f211AB05b1c97D595516F45794528a807ad8",
"chainId": 1,
"decimals": 18,
"decimals": 2,
"logoURI": "https://files.sablier.com/tokens/EURS.png",
"name": "STASIS EURS Token",
"symbol": "EURS"
Expand Down Expand Up @@ -202,7 +202,7 @@
{
"address": "0x4cB1e6c430Bb4b874869Fd6049ed07aE975b02f1",
"chainId": 1,
"decimals": 18,
"decimals": 9,
"logoURI": "https://files.sablier.com/tokens/SWIPES.png",
"name": "BNDR",
"symbol": "SWIPES"
Expand Down Expand Up @@ -504,24 +504,6 @@
"name": "GameGPT",
"symbol": "DUEL"
},
{
"address": "0x321725ee44CB4bfA544CF45a5A585b925d30A58C",
"chainId": 1,
"decimals": 18,
"extensions": {
"bridgeInfo": {
"10": {
"tokenAddress": "0xc871cCf95024eFa2CbcE69B5B775D2a1DcF49c1B"
},
"8453": {
"tokenAddress": "0x321725ee44CB4bfA544CF45a5A585b925d30A58C"
}
}
},
"logoURI": "https://files.sablier.com/tokens/GROW.png",
"name": "ValleyDAO",
"symbol": "GROW"
},
{
"address": "0x51e00a95748DBd2a3F47bC5c3b3E7B3F0fea666c",
"chainId": 1,
Expand Down Expand Up @@ -805,7 +787,7 @@
{
"address": "0x903bEF1736CDdf2A537176cf3C64579C3867A881",
"chainId": 1,
"decimals": 18,
"decimals": 9,
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x903bEF1736CDdf2A537176cf3C64579C3867A881/logo.png",
"name": "Ichi (Legacy)",
"symbol": "ICHI"
Expand Down Expand Up @@ -1674,7 +1656,7 @@
{
"address": "0x9e10f61749c4952C320412A6B26901605Ff6Da1d",
"chainId": 1,
"decimals": 6,
"decimals": 18,
"logoURI": "https://files.sablier.com/tokens/THEOS.png",
"name": "THEOS",
"symbol": "THEOS"
Expand Down Expand Up @@ -1794,7 +1776,7 @@
{
"address": "0xB893A8049f250b57eFA8C62D51527a22404D7c9A",
"chainId": 1,
"decimals": 6,
"decimals": 9,
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xB893A8049f250b57eFA8C62D51527a22404D7c9A/logo.png",
"name": "American Shiba",
"symbol": "USHIBA"
Expand Down Expand Up @@ -1932,7 +1914,7 @@
{
"address": "0xa47c8bf37f92aBed4A126BDA807A7b7498661acD",
"chainId": 1,
"decimals": 6,
"decimals": 18,
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xa47c8bf37f92aBed4A126BDA807A7b7498661acD/logo.png",
"name": "Wrapped UST Token",
"symbol": "UST"
Expand Down Expand Up @@ -2025,14 +2007,6 @@
"name": "Lumerin",
"symbol": "LMR"
},
{
"address": "0x0C03Ce270B4826Ec62e7DD007f0B716068639F7B",
"chainId": 1,
"decimals": 18,
"logoURI": "https://files.sablier.com/tokens/TIG.png",
"name": "The Innovation Game",
"symbol": "TIG"
},
{
"address": "0xf59257E961883636290411c11ec5Ae622d19455e",
"chainId": 1,
Expand Down
8 changes: 0 additions & 8 deletions src/tokens/polygon-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -455,14 +455,6 @@
"name": "Neighbourhoods",
"symbol": "NHT"
},
{
"address": "0x66E535e8D2ebf13F49F3D49e5c50395a97C137b1",
"chainId": 137,
"decimals": 18,
"logoURI": "https://files.sablier.com/tokens/MOLTEN.png",
"name": "Molten",
"symbol": "MOLTEN"
},
{
"address": "0x0AA1e96D2a46Ec6beB2923dE1E61Addf5F5f1dce",
"chainId": 137,
Expand Down
2 changes: 1 addition & 1 deletion src/tokens/zksync-mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"address": "0xBBeB516fb02a01611cBBE0453Fe3c580D7281011",
"chainId": 324,
"decimals": 18,
"decimals": 8,
"logoURI": "https://files.sablier.com/tokens/WBTC.png",
"name": "Wrapped Bitcoin",
"symbol": "WBTC"
Expand Down

0 comments on commit dd6b419

Please sign in to comment.