Skip to content

Commit

Permalink
Feat/xfer disabled tokens (#284)
Browse files Browse the repository at this point in the history
* Add transfer disabled tokens field

* Add token name overrides map
  • Loading branch information
sarah-thong authored Dec 13, 2024
1 parent e7fa5fc commit c1e22d3
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 4 deletions.
8 changes: 8 additions & 0 deletions .github/markets/pr_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Each json file under the [configs](../../configs) folder correspond to their res
|`blacklisted_markets` |`string[]` |true |The array of market names that are blacklisted. A market can be blacklisted for a number of reasons, such as it being invalid/duplicate/wrongly-added/etc. |The market names listed here **MUST** match the market names listed under the Carbon [Markets API](https://api.carbon.network/carbon/market/v1/markets?pagination.limit=10000). The market names listed here **CANNOT** be under the `prelaunch_markets` field at the same time. |
|`blacklisted_pools` |`string[]` |true |The array of pool ids that are blacklisted. A pool can be blacklisted for a number of reasons, such as it being invalid/duplicate/wrongly-added/etc. |The pool ids listed here **MUST** match the pool ids listed under the Carbon [Liquidity Pool API](https://api.carbon.network/carbon/liquiditypool/v1/pools?pagination.limit=10000). |
|`blacklisted_tokens` |`string[]` |true |The array of token denoms that are blacklisted. A token can be blacklisted for a number of reasons, such as it being invalid/deprecated/etc. |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). |
| `transfer_disabled_tokens` |`TransferDisabledTokens` |true |Object that contains tokens for which deposits and withdrawals are temporarily disabled | |
| `token_name_override_map` |`object` |true |Object that contains token denoms and their respective token name overrides. This is used if we need to override the full token name of the tokens listed here. |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). |
|`transfer_options` |`object` |true |A collection of blockchain networks along with their associated priority numbers, used to establish their order in the transfer options list for deposit and withdrawal forms. |Blockchain network listed here **MUST** match the valid chainName of the bridges listed under BridgeAll RPC call.<br /><br /> To view the values of BridgeAll RPC call, simply run `yarn get-bridges [network]` on the command line. Sample for mainnet: `yarn get-bridges mainnet`|
|`network_fees` |`object` |true |List of token denoms along with their associated priority numbers, used to establish their default order in the network fees preference list. |Token denoms listed here **MUST** match the valid denoms listed under MinGasPriceAll RPC call.<br /><br /> To view the values of MinGasPriceAll RPC call, simply run `yarn get-min-gas-prices [network]` on the command line. Sample for mainnet: `yarn get-min-gas-prices mainnet`|
|`maintenance` |`Maintenance` |false |Object that dictates whether or not the maintenance page is displayed on each particular network. The maintenance page is displayed when the Carbon chain is down (i.e. blocks are not moving). | If the `maintenance` property is omitted, the maintenance page will not be shown.
Expand All @@ -28,6 +30,12 @@ Each json file under the [configs](../../configs) folder correspond to their res
|`market_promo` |`MarketPromo` |false |Map of Objects that contains market promo parameters for each market |If the `market_promo` property is omitted, no promo will be shown. The key of each entry is the ids of the market with existing promo. |
|`spot_pool_config` |`SpotPoolConfig` |false |Object that contains the config parameters for the [Spot Pools](https://app.dem.exchange/pools/spot) page on Demex |

## TransferDisabledTokens Data Structure
|Field |Type |Required |Description |Notes |
|---|---|---|---|---|
|`deposit` |`string[]` |true |List of tokens for which deposits are temporarily disabled |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). |
|`withdraw` |`string[]` |true |List of tokens for which withdrawals are temporarily disabled |The token denoms listed here **MUST** match the token denoms listed under the Carbon [Tokens API](https://api.carbon.network/carbon/coin/v1/tokens?pagination.limit=10000). |

## Maintenance Data Structure
|Field |Type |Required |Description |Notes |
|---|---|---|---|---|
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Currently, each JSON file contain the following data on its corresponding networ
- blacklisted markets
- blacklisted pools
- blacklisted tokens
- tokens for which deposits/withdrawals are disabled
- list of tokens and their token name overrides (which are used if we need to override the token's full name on the Demex webapp)
- default blockchain transfer option order in deposit/withdrawal forms dropdown
- default network token fee order
- cross selling source tokens
Expand Down Expand Up @@ -46,6 +48,15 @@ More metadata will be added in the future if required by the Demex frontend. Ple
"blacklisted_token_2",
"blacklisted_token_3"
],
"transfer_disabled_tokens": [
"transfer_disabled_token_1",
"transfer_disabled_token_2",
"transfer_disabled_token_3"
],
"token_name_override_map": {
"token_1": "token_name_override_1",
"token_2": "token_name_override_2"
},
"transfer_options": {
"chain_1": 0,
"chain_2": 1,
Expand Down
33 changes: 33 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"blacklisted_markets",
"blacklisted_pools",
"blacklisted_tokens",
"transfer_disabled_tokens",
"token_name_override_map",
"transfer_options",
"network_fees",
"cross_selling_source_tokens",
Expand Down Expand Up @@ -47,6 +49,37 @@
"$ref": "#/$defs/blacklisted_token"
}
},
"transfer_disabled_tokens": {
"type": "object",
"description": "Object containing tokens for which deposits and withdrawals have been temporarily disabled",
"required": ["deposit", "withdraw"],
"properties": {
"deposit": {
"type": "array",
"description": "List of tokens for which deposits have been temporarily disabled",
"items": {
"type": "string"
}
},
"withdraw": {
"type": "array",
"description": "List of tokens for which withdrawals have been temporarily disabled",
"items": {
"type": "string"
}
}
}
},
"token_name_override_map": {
"type": "object",
"description": "Object that contains token denoms and their respective token name overrides.",
"patternProperties": {
".*": {
"type": "string",
"minLength": 2
}
}
},
"transfer_options": {
"type": "object",
"description": "List of blockchain networks and their priority numbers, used to set their order in deposit and withdrawal forms transfer option dropdown",
Expand Down
5 changes: 5 additions & 0 deletions configs/devnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
],
"blacklisted_pools": [],
"blacklisted_tokens": [],
"transfer_disabled_tokens": {
"deposit": [],
"withdraw": []
},
"token_name_override_map": {},
"transfer_options": {},
"network_fees": {
"swth": 0,
Expand Down
34 changes: 30 additions & 4 deletions configs/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,32 @@
"usdc.1.6.e70e14",
"bit.1.2.9d68c4"
],
"transfer_disabled_tokens": {
"deposit": [
"nex.1.17.59c1ba",
"gmx.1.19.70275d",
"wbnb.1.6.ad598c",
"blur.1.2.0c0069",
"brdg/0b02ac3efc9df2e80d00f141133c180cdaee0122f92d3e2e310f704e82425a18",
"brdg/0f18019978979327ad0ecca00adba941ebf8828f40af270f5e2a3a94c3802d72",
"brdg/1768794901f8a19c2ec795a5402653cef6cbfe6b3ec6398d39fc37de963cb667",
"brdg/a8bbd91ae3dda9de2e50926a0d93be4d0d5cea34f3080014e5c0c0db6eaf61a4"
],
"withdraw": [
"nex.1.17.59c1ba",
"gmx.1.19.70275d",
"wbnb.1.6.ad598c",
"blur.1.2.0c0069",
"brdg/0b02ac3efc9df2e80d00f141133c180cdaee0122f92d3e2e310f704e82425a18",
"brdg/0f18019978979327ad0ecca00adba941ebf8828f40af270f5e2a3a94c3802d72",
"brdg/1768794901f8a19c2ec795a5402653cef6cbfe6b3ec6398d39fc37de963cb667",
"brdg/a8bbd91ae3dda9de2e50926a0d93be4d0d5cea34f3080014e5c0c0db6eaf61a4"
]
},
"token_name_override_map": {
"brdg/1299d2e94c483e72f64100088886b8a5b7c13595047e53e032c9938d07a98c20": "Ether (Arbitrum)",
"brdg/e3877e2c8ed05e404e04417747e2f430285c11dc839663b943b39ff7cbb56377": "Ether (Ethereum)"
},
"transfer_options": {
"Mantle": 0,
"Base": 1,
Expand Down Expand Up @@ -419,10 +445,10 @@
"native_token_contracts_map": {
"brdg/6418666cedaf875fb344dbd90bea7c842300939872365b933f7ee8b6c1e825e8": "0x0000000000000000000000000000000000000000",
"brdg/a02afc2c1edf77cc023eefa25fc036c184612faf9365cda9c1daa3b1675ebf8f": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000",
"brdg/41589e35bdd37fa000a2a310fe076015e52dfd78fc9a09b504903c7b83fb9c4b": "0x0000000000000000000000000000000000000000",
"brdg/54d7e3e21eeac0b0761a0294142b0c4f234e5e08a23f770e435755ebebdb951c": "0x0000000000000000000000000000000000000000",
"brdg/80e8c20d295cf162023922ecfa61fd73184b6e0bd1f3f4b32265fc69ae7aed23": "0x0000000000000000000000000000000000000000",
"brdg/a07dd6e75ea4045aaa3949322b6243163293aebd8610333eff20b6db4beffa0e": "0x0000000000000000000000000000000000000000"
"brdg/1299d2e94c483e72f64100088886b8a5b7c13595047e53e032c9938d07a98c20": "0x0000000000000000000000000000000000000000",
"brdg/1768794901f8a19c2ec795a5402653cef6cbfe6b3ec6398d39fc37de963cb667": "0x0000000000000000000000000000000000000000",
"brdg/e3877e2c8ed05e404e04417747e2f430285c11dc839663b943b39ff7cbb56377": "0x0000000000000000000000000000000000000000",
"brdg/e2238fb8fc5f08299c1789177d6d89bb2853238a65f6e48a9ec3b67e289f5601": "0x0000000000000000000000000000000000000000"
},
"native_depositor_contracts_map": {
"3/arbitrum/0x4ab44c7e881ee37cb02bc0c98547a0bbfad9291b": "0xd91a2AcbE1f9635277120fc200F73574f1Cdad65",
Expand Down
5 changes: 5 additions & 0 deletions configs/testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
],
"blacklisted_pools": [],
"blacklisted_tokens": [],
"transfer_disabled_tokens": {
"deposit": [],
"withdraw": []
},
"token_name_override_map": {},
"transfer_options": {},
"network_fees": {
"swth": 0,
Expand Down
73 changes: 73 additions & 0 deletions scripts/check_configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ interface ConfigJSON {
blacklisted_markets: string[];
blacklisted_pools: string[];
blacklisted_tokens: string[];
transfer_disabled_tokens: TransferDisabledTokensObj;
token_name_override_map: TokenNameOverrideMap;
transfer_options: {
[chainKey: string]: number;
};
Expand Down Expand Up @@ -57,6 +59,15 @@ interface PerpPoolBanner {
subtext?: string;
}

interface TransferDisabledTokensObj {
deposit: string[];
withdraw: string[];
}

type TokenNameOverrideMap = {
[denom: string]: string;
}

interface DemexPointsConfig {
depositsPerSpin: number;
tradingVolumePerSpin: number;
Expand Down Expand Up @@ -180,6 +191,16 @@ function checkAddressIsEVM(address: string): Boolean {
return regex.test(address)
}

function isErrorOutcome(outcome: DuplicateEntry): boolean {
return Boolean(outcome.status && outcome.entry?.length && outcome.entry.length > 0);
}

function joinEntriesIntoStr(entriesArr: string[]): string {
return entriesArr.length > 1
? `${entriesArr.slice(0, -1).join(", ")} and ${entriesArr[entriesArr.length - 1]}`
: entriesArr[0];
}

// check list of markets to ensure that it does not have blacklisted markets
function checkBlacklistedMarkets(marketData: string[], blacklistedMarkets: string[]): InvalidEntry {
let overlappingMarkets: string[] = [];
Expand All @@ -196,6 +217,50 @@ function checkBlacklistedMarkets(marketData: string[], blacklistedMarkets: strin
};
}

function isValidTransferDisabledTokens(transferDisabledTokens: TransferDisabledTokensObj, denoms: string[], network: CarbonSDK.Network): boolean {
const dupDepositTknsOutcome = checkDuplicateEntries(transferDisabledTokens.deposit);
const dupWithdrawTknsOutcome = checkDuplicateEntries(transferDisabledTokens.withdraw);

if (dupDepositTknsOutcome.status || dupWithdrawTknsOutcome.status) {
if (isErrorOutcome(dupDepositTknsOutcome)) {
const duplicateDepositTokensStr = joinEntriesIntoStr(dupDepositTknsOutcome.entry!);
console.error(`[ERROR] transfer_disabled_tokens.deposit of ${network}.json has the following duplicate token denoms: ${duplicateDepositTokensStr}. Please make sure to input each denom only once.`);
}
if (isErrorOutcome(dupWithdrawTknsOutcome)) {
const duplicateWithdrawTokensStr = joinEntriesIntoStr(dupWithdrawTknsOutcome.entry!);
console.error(`[ERROR] transfer_disabled_tokens.withdraw of ${network}.json has the following duplicate token denoms: ${duplicateWithdrawTokensStr}. Please make sure to input each denom only once.`);
}
return false;
}

const validDepositTknsOutcome = checkValidEntries(transferDisabledTokens.deposit, denoms);
const validWithdrawTknsOutcome = checkValidEntries(transferDisabledTokens.withdraw, denoms);
if (validDepositTknsOutcome.status || dupWithdrawTknsOutcome.status) {
if (isErrorOutcome(validDepositTknsOutcome)) {
const invalidDepositTokensStr = joinEntriesIntoStr(validDepositTknsOutcome.entry!);
console.error(`[ERROR] transfer_disabled_tokens.deposit of ${network}.json has the following invalid token denoms: ${invalidDepositTokensStr}. Please make sure to input only valid token denoms.`);
}
if (isErrorOutcome(validWithdrawTknsOutcome)) {
const invalidWithdrawTokensStr = joinEntriesIntoStr(validWithdrawTknsOutcome.entry!);
console.error(`[ERROR] transfer_disabled_tokens.withdraw of ${network}.json has the following invalid token denoms: ${invalidWithdrawTokensStr}. Please make sure to input only valid token denoms.`);
}
return false;
}

return true;
}

function isValidTokenNameOverrideMap(tokenNameOverrideMap: TokenNameOverrideMap, denoms: string[], network: CarbonSDK.Network): boolean {
const denomKeysArr = Object.keys(tokenNameOverrideMap);
const invalidDenomsOutcome = checkValidEntries(denomKeysArr, denoms);
if (isErrorOutcome(invalidDenomsOutcome)) {
const invalidTokensStr = joinEntriesIntoStr(invalidDenomsOutcome.entry!);
console.error(`[ERROR] token_name_override_map of ${network}.json has the following invalid token denom keys: ${invalidTokensStr}. Please make sure to input only valid token denoms.`);
return false;
}
return true;
}

function isValidExternalChainChannels(chainChannels: ExternalChannelsObj, bridges: string[], network: CarbonSDK.Network): boolean {
const duplicateChainKeys: string[] = [];
const invalidChainKeys: string[] = [];
Expand Down Expand Up @@ -476,6 +541,14 @@ async function main() {
outcomeMap[network] = false;
}

// transfer disabled tokens object check
const isTransferDisabledTokensValid = isValidTransferDisabledTokens(jsonData.transfer_disabled_tokens, tokens, network);
if (!isTransferDisabledTokensValid) outcomeMap[network] = false;

// token_name_override_map check
const isTokenNameOverrideMapValid = isValidTokenNameOverrideMap(jsonData.token_name_override_map, tokens, network);
if (!isTokenNameOverrideMapValid) outcomeMap[network] = false;

const hasInvalidCrossSellingTokens = checkValidEntries(jsonData.cross_selling_source_tokens, tokens);
if (hasInvalidCrossSellingTokens.status && hasInvalidCrossSellingTokens.entry) {
let listOfInvalidTokens: string = hasInvalidCrossSellingTokens.entry.join(', ');
Expand Down

0 comments on commit c1e22d3

Please sign in to comment.