diff --git a/.github/markets/pr_template.md b/.github/markets/pr_template.md
index 17a34f3..6ecb128 100644
--- a/.github/markets/pr_template.md
+++ b/.github/markets/pr_template.md
@@ -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.
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.
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.
@@ -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 |
|---|---|---|---|---|
diff --git a/README.md b/README.md
index efa8d77..0f7f551 100644
--- a/README.md
+++ b/README.md
@@ -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
@@ -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,
diff --git a/config.schema.json b/config.schema.json
index 641ea39..683a082 100644
--- a/config.schema.json
+++ b/config.schema.json
@@ -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",
@@ -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",
diff --git a/configs/devnet.json b/configs/devnet.json
index 5559c22..86d3aff 100644
--- a/configs/devnet.json
+++ b/configs/devnet.json
@@ -8,6 +8,11 @@
],
"blacklisted_pools": [],
"blacklisted_tokens": [],
+ "transfer_disabled_tokens": {
+ "deposit": [],
+ "withdraw": []
+ },
+ "token_name_override_map": {},
"transfer_options": {},
"network_fees": {
"swth": 0,
diff --git a/configs/mainnet.json b/configs/mainnet.json
index 7a4152b..1a22159 100644
--- a/configs/mainnet.json
+++ b/configs/mainnet.json
@@ -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,
@@ -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",
diff --git a/configs/testnet.json b/configs/testnet.json
index ce9f0d3..2d3c393 100644
--- a/configs/testnet.json
+++ b/configs/testnet.json
@@ -10,6 +10,11 @@
],
"blacklisted_pools": [],
"blacklisted_tokens": [],
+ "transfer_disabled_tokens": {
+ "deposit": [],
+ "withdraw": []
+ },
+ "token_name_override_map": {},
"transfer_options": {},
"network_fees": {
"swth": 0,
diff --git a/scripts/check_configs.ts b/scripts/check_configs.ts
index 1ff89fc..c13f7d3 100644
--- a/scripts/check_configs.ts
+++ b/scripts/check_configs.ts
@@ -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;
};
@@ -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;
@@ -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[] = [];
@@ -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[] = [];
@@ -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(', ');