Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check addressbook duplicate addresses on commit #1543

Merged
merged 2 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,13 +1,2 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn test:ts
yarn lint-staged

SRC_PATTERN="packages/address-book"
if git diff --cached --name-only | grep --quiet "$SRC_PATTERN"
then
cd packages/address-book
yarn lint-staged
yarn checksum
fi
#!/usr/bin/env sh
yarn lint-staged --verbose
8 changes: 8 additions & 0 deletions .lintstagedrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const ifStaged = fn => stagedFiles => stagedFiles.length === 0 ? [] : fn(stagedFiles);

module.exports = {
'./(src|scripts)/**/*.{ts,js,json}': ifStaged(stagedFiles => [
`prettier --write ${stagedFiles.join(' ')}`,
`tsc --noEmit`,
]),
};
11 changes: 3 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"test:ts": "tsc --noEmit",
"prettier:check": "prettier --check src/**/*",
"prettier:fix": "prettier --write src/**/*",
"prepare": "husky install",
"prepare": "husky",
"addFarm": "ts-node scripts/add-farm.ts",
"addSushi": "ts-node scripts/add-sushi.ts",
"addSolidly": "ts-node scripts/add-solidly.ts",
Expand Down Expand Up @@ -91,7 +91,7 @@
"ethers": "^5.7.2",
"graphql": "^15.5.0",
"graphql-tag": "^2.12.4",
"husky": "^6.0.0",
"husky": "^9.1.5",
"jsonpath": "^1.1.1",
"koa": "^2.13.0",
"koa-bodyparser": "^4.3.0",
Expand All @@ -116,17 +116,12 @@
"command-line-args": "^5.2.1",
"dotenv": "^8.2.0",
"fast-glob": "^3.2.12",
"lint-staged": "^12.1.7",
"lint-staged": "^15.2.10",
"lodash": "^4.17.21",
"nodemon": "^2.0.6",
"nyc": "^15.1.0",
"prettier": "^2.8.8",
"yargs": "^17.0.1"
},
"lint-staged": {
"*.ts": "prettier --write",
"*.js": "prettier --write",
"*.json": "prettier --write"
},
"packageManager": "[email protected]"
}
17 changes: 17 additions & 0 deletions packages/address-book/.lintstagedrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const ifStaged = fn => stagedFiles => stagedFiles.length === 0 ? [] : fn(stagedFiles);
const withArgs = (cmd, ...args) => `${cmd} ${args.flat().join(' ')}`;

module.exports = {
'./(src|scripts)/**/*.ts': ifStaged(stagedFiles => [
withArgs('prettier', '--write', stagedFiles),
withArgs('eslint', '--fix', stagedFiles),
withArgs('tsc', '--noEmit'),
]),
'./src/address-book/*/tokens/tokens.ts': ifStaged(stagedFiles => {
const chains = stagedFiles.map(file => file.split('/')[2]).filter(v => !!v);
if (!chains.length) {
throw new Error('Matched files do not match expected path structure');
}
return [withArgs('ts-node', '--transpileOnly', './scripts/checkDuplicates.ts', chains)];
}),
};
7 changes: 0 additions & 7 deletions packages/address-book/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,9 @@
"@types/node": "^20.14.7",
"cross-env": "^7.0.3",
"eslint": "^9.5.0",
"lint-staged": "^15.2.7",
"prettier": "^3.3.2",
"ts-node": "^10.9.2",
"typescript": "^5.5.2",
"typescript-eslint": "^7.13.1"
},
"lint-staged": {
"./(src|scripts)/**/*.ts": [
"prettier --write",
"eslint --fix"
]
}
}
34 changes: 25 additions & 9 deletions packages/address-book/scripts/checkDuplicates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ type ChainId = keyof typeof addressBook;
type TokenWithId = Token & { id: string };
const allChains = Object.keys(addressBook) as ChainId[];

function isChainId(chainId: string): chainId is ChainId {
return !!addressBook[chainId as ChainId];
}

function checkChain(chainId: ChainId) {
const { tokens } = addressBook[chainId];
const byAddress: Record<string, TokenWithId[]> = {};
Expand All @@ -22,30 +26,42 @@ function checkChain(chainId: ChainId) {

let errors = 0;
for (const [address, duplicates] of Object.entries(byAddress)) {
if (duplicates.length > 1 && duplicates[0].address !== tokens.WNATIVE.address) {
console.warn(
`[WARN] Duplicate address ${address} on ${chainId}: ${duplicates
.map(t => `${t.id} (${t.oracleId})`)
.join(', ')}`
);
if (duplicates.length > 1) {
const uniqueOracles = Array.from(new Set(duplicates.map(t => t.oracleId)));
if (uniqueOracles.length > 1) {
// Always error if oracleIds are different for same token address
console.error(
`[ERROR] Different oracleIds for ${address} on ${chainId}: ${uniqueOracles.join(', ')}`
);
++errors;
} else if (duplicates[0].address !== tokens.WNATIVE.address) {
// Only warn if same token address is used for multiple tokens and oracleIds are the same
// (exclude WNATIVE as it is always duplicated)
console.warn(
`[WARN] Duplicate address ${address} on ${chainId}: ${duplicates
.map(t => `${t.id} (${t.oracleId})`)
.join(', ')}`
);
}
}
}

return errors;
}

function start() {
const errors = allChains.map(checkChain).reduce((acc, e) => acc + e, 0);
function start(chains: ChainId[] = allChains) {
const errors = chains.map(checkChain).reduce((acc, e) => acc + e, 0);
if (errors > 0) {
throw new Error(`Found ${errors} errors, see above`);
}
}

start();
if (process.argv.length >= 3 && process.argv[1].endsWith('checkDuplicates.ts')) {
const [, , ...chains] = process.argv;
if (!chains.every(isChainId)) {
throw new Error(`Invalid chainId: ${chains.filter(c => !isChainId(c)).join(', ')}`);
}
start(chains);
} else {
start();
}
33 changes: 18 additions & 15 deletions packages/address-book/src/address-book/bsc/tokens/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ const BNB = {
documentation: 'https://www.binance.com/en/bnb',
} as const satisfies Token;

const lisUSD = {
name: 'Lista USD',
symbol: 'lisUSD',
oracleId: 'lisUSD',
address: '0x0782b6d8c4551B9760e74c0545a9bCD90bdc41E5',
chainId: 56,
decimals: 18,
logoURI: '',
website: 'https://lista.org/',
documentation: 'https://docs.bsc.lista.org/',
description:
'lisUSD is a decentralized, unbiased, collateral backed destablecoin soft-pegged to the US Dollar. Users who have collateralized their assets via Lista are eligible to take out a loan in lisUSD against their collateral.',
bridge: 'native',
risks: ['NO_TIMELOCK'],
} as const satisfies Token;

export const tokens = {
CASH: {
name: 'CASH',
Expand Down Expand Up @@ -230,6 +246,7 @@ export const tokens = {
description:
'HOOP is the reward and in-game currency for the Chibi Dinos Gaming Universe. It can be used to pay for merchandise and events; future uses include staking and governance for in-game decisions. Chibi Dinos is a basketball and dinosaur themed metaverse with games such as Primal Hoop, an arcade basketball game with an adventure role-playing game (RPG) mode and Primal Pickem, a predictive play-to earn game (P2E).',
},
HAY: lisUSD,
jCHF: {
name: 'Jarvis Synthetic Swiss Franc',
symbol: 'jCHF',
Expand Down Expand Up @@ -4675,21 +4692,7 @@ export const tokens = {
bridge: 'native',
risks: ['NO_TIMELOCK'],
},
lisUSD: {
name: 'Lista USD',
symbol: 'lisUSD',
oracleId: 'lisUSD',
address: '0x0782b6d8c4551B9760e74c0545a9bCD90bdc41E5',
chainId: 56,
decimals: 18,
logoURI: '',
website: 'https://lista.org/',
documentation: 'https://docs.bsc.lista.org/',
description:
'lisUSD is a decentralized, unbiased, collateral backed destablecoin soft-pegged to the US Dollar. Users who have collateralized their assets via Lista are eligible to take out a loan in lisUSD against their collateral.',
bridge: 'native',
risks: ['NO_TIMELOCK'],
},
lisUSD,
pxETH: {
name: 'Pirex Ether OFT',
symbol: 'pxETH',
Expand Down
Loading
Loading