Skip to content

Commit 9f99f24

Browse files
authored
Deverification summary table (#3307)
* Add verification check for killed chains * Add killed chain to summary, simplify high liquidity table 1. Moved Killed Chain Assets Section - Now appears as a subsection at the bottom of the "Failed Checks" analysis section (after Logo Failures) - Always displays with fallback text when there are no killed chain assets: "No assets from killed chains detected. All assets belong to active chains." - Follows the same pattern as other report subsections 2. Merged High Liquidity Table Columns - Combined "Bid Depth" and "Other Failures" into a single "Failure Reasons" column - Bid depth failures now show as "Bid depth: [details]" within the merged column - All failures are now listed together, comma-separated, for easier reading
1 parent 6721a2c commit 9f99f24

File tree

2 files changed

+132
-15
lines changed

2 files changed

+132
-15
lines changed

.github/workflows/utility/checkVerificationCriteria.mjs

Lines changed: 127 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* - Uploads reports as artifacts
2121
*
2222
* ============================================================================
23-
* VERIFICATION CRITERIA (7 Checks)
23+
* VERIFICATION CRITERIA (8 Checks)
2424
* ============================================================================
2525
*
2626
* 1. STANDARD LISTING
@@ -116,6 +116,15 @@
116116
* - Pass: Either side has usd_amount >= $50 at 2% depth
117117
* - Fail: Both sides < $50, or no pool found
118118
*
119+
* 8. CHAIN STATUS
120+
* - Verifies the asset's chain is not marked as "killed"
121+
* - Check: chain_reg.getFileProperty(chainName, 'chain', 'status') !== 'killed'
122+
* - Exemption: Meme tokens (category includes "meme") skip this check
123+
* - Pass: Chain status is "live" or "upcoming" OR asset is a meme token
124+
* - Fail: Chain status is "killed" (unless meme token)
125+
* - Purpose: Prevents verification of assets on killed/deprecated chains
126+
* while allowing historical meme tokens to remain verified
127+
*
119128
* ============================================================================
120129
* ALLOY AUTO-VERIFICATION
121130
* ============================================================================
@@ -521,6 +530,22 @@ function isMemeToken(zoneAsset) {
521530
return hasCategories(zoneAsset, ['meme']);
522531
}
523532

533+
/**
534+
* Check if a chain is marked as killed in the chain registry
535+
*
536+
* @param {string} chainName - Chain name to check
537+
* @returns {boolean} True if chain is killed, false otherwise
538+
*/
539+
function isChainKilled(chainName) {
540+
try {
541+
const chainStatus = chain_reg.getFileProperty(chainName, 'chain', 'status');
542+
return chainStatus === 'killed';
543+
} catch (error) {
544+
// If we can't read the chain status, assume it's not killed
545+
return false;
546+
}
547+
}
548+
524549
//-- Verification Check Functions --
525550

526551
/**
@@ -1112,6 +1137,53 @@ async function checkBidDepth(chainName, baseDenom, numiaPairs) {
11121137
}
11131138
}
11141139

1140+
/**
1141+
* Check 8: Killed Chain Status
1142+
* Verifies that the asset's chain is not marked as "killed" in the chain registry
1143+
*
1144+
* Assets on killed chains should not be verified, and already-verified assets apart from memes
1145+
* should be de-verified.
1146+
*
1147+
* Exemption: Meme tokens (category includes "meme") are allowed to remain verified
1148+
* even on killed chains, as they may have historical/cultural value.
1149+
*
1150+
* Per LISTING.md chain status requirement
1151+
*
1152+
* @param {string} chainName - Chain name to check
1153+
* @param {boolean} isMeme - Whether the asset is a meme token
1154+
*/
1155+
async function checkChainStatus(chainName, isMeme) {
1156+
try {
1157+
// Exemption: Meme tokens can remain verified on killed chains
1158+
if (isMeme) {
1159+
return {
1160+
passed: true,
1161+
details: 'Meme category: exempt from chain status check',
1162+
skipped: true
1163+
};
1164+
}
1165+
1166+
const chainIsKilled = isChainKilled(chainName);
1167+
1168+
if (chainIsKilled) {
1169+
return {
1170+
passed: false,
1171+
details: `Chain "${chainName}" is marked as killed in the chain registry`
1172+
};
1173+
}
1174+
1175+
return {
1176+
passed: true,
1177+
details: 'Chain is active'
1178+
};
1179+
} catch (error) {
1180+
return {
1181+
passed: true, // Assume chain is active if we can't check
1182+
details: `Could not verify chain status: ${error.message}`
1183+
};
1184+
}
1185+
}
1186+
11151187
//-- Main Verification Function --
11161188

11171189
/**
@@ -1134,6 +1206,7 @@ async function verifyAsset(zoneAsset, numiaTokens, numiaPairs, alloyMembersMap)
11341206
comment: zoneAsset._comment || '',
11351207
currently_verified: zoneAsset.osmosis_verified || false,
11361208
is_meme: isMeme,
1209+
chainIsKilled: isChainKilled(chain_name),
11371210
checks: {},
11381211
alloyInfo: null
11391212
};
@@ -1153,6 +1226,7 @@ async function verifyAsset(zoneAsset, numiaTokens, numiaPairs, alloyMembersMap)
11531226
results.checks.logo = await checkLogo(chain_name, base_denom);
11541227
results.checks.poolLiquidity = await checkPoolLiquidity(chain_name, base_denom, numiaTokens);
11551228
results.checks.bidDepth = await checkBidDepth(chain_name, base_denom, numiaPairs);
1229+
results.checks.chainStatus = await checkChainStatus(chain_name, isMeme);
11561230

11571231
// Determine overall pass/fail
11581232
results.allChecksPassed = Object.values(results.checks).every(check => check.passed);
@@ -1179,9 +1253,13 @@ function generateMarkdownReport(verificationResults) {
11791253
const alreadyVerified = verificationResults.filter(r => r.currently_verified);
11801254
const failedChecks = verificationResults.filter(r => !r.allChecksPassed && !r.currently_verified);
11811255

1256+
// Filter killed chain assets (excluding meme tokens) - only verified assets that need de-verification
1257+
const killedChainAssetsVerified = verificationResults.filter(r => r.chainIsKilled && r.currently_verified && !r.is_meme);
1258+
11821259
markdown += `## Summary\n\n`;
11831260
markdown += `- **Ready for Verification**: ${readyForVerification.length}\n`;
11841261
markdown += `- **Failed Checks**: ${failedChecks.length}\n`;
1262+
markdown += `- **Killed Chain Assets**: ${killedChainAssetsVerified.length} (potential de-verification)\n`;
11851263
markdown += `- **Total Checked**: ${verificationResults.length}\n\n`;
11861264

11871265
// Ready for Verification section with asset links
@@ -1283,35 +1361,39 @@ function generateMarkdownReport(verificationResults) {
12831361

12841362
if (highLiquidityFailing.length > 0) {
12851363
markdown += `These assets have sufficient pool liquidity ($1000+) but fail other checks:\n\n`;
1286-
markdown += `| Asset | Comment | Pool Liquidity | Bid Depth | Other Failures |\n`;
1287-
markdown += `|-------|---------|----------------|-----------|----------------|\n`;
1364+
markdown += `| Asset | Comment | Pool Liquidity | Failure Reasons |\n`;
1365+
markdown += `|-------|---------|----------------|----------------|\n`;
12881366

12891367
highLiquidityFailing.forEach(r => {
12901368
const symbol = r.comment || r.base_denom.substring(0, 30);
12911369
// Extract just the liquidity amount from the details string
12921370
const liqMatch = r.checks.poolLiquidity?.details?.match(/\$[\d,]+/);
12931371
const poolLiq = liqMatch ? liqMatch[0] : 'N/A';
12941372

1295-
// Format bid depth
1296-
let bidDepth = '';
1297-
if (r.checks.bidDepth?.passed) {
1298-
bidDepth = '✅ ' + r.checks.bidDepth.details;
1299-
} else {
1300-
const details = r.checks.bidDepth?.details || 'Failed';
1373+
// Collect all failure reasons
1374+
const failureReasons = [];
1375+
1376+
// Add bid depth if it failed
1377+
if (!r.checks.bidDepth?.passed) {
1378+
const details = r.checks.bidDepth?.details || 'Bid depth failed';
13011379
const cleanDetails = details
13021380
.replace(//g, '')
13031381
.replace(//g, '')
13041382
.replace(/\(need \$\d+\)/g, '')
13051383
.trim();
1306-
bidDepth = '❌ ' + cleanDetails;
1384+
failureReasons.push(`Bid depth: ${cleanDetails}`);
13071385
}
13081386

1387+
// Add other failures
13091388
const otherFails = Object.entries(r.checks)
13101389
.filter(([name, check]) => !check.passed && !check.skipped && name !== 'poolLiquidity' && name !== 'bidDepth')
1311-
.map(([name]) => name.replace(/([A-Z])/g, ' $1').trim())
1312-
.join(', ') || 'None';
1390+
.map(([name]) => name.replace(/([A-Z])/g, ' $1').trim());
1391+
1392+
failureReasons.push(...otherFails);
1393+
1394+
const failureReasonsText = failureReasons.length > 0 ? failureReasons.join(', ') : 'None';
13131395

1314-
markdown += `| ${symbol} | ${r.chain_name} | ${poolLiq} | ${bidDepth} | ${otherFails} |\n`;
1396+
markdown += `| ${symbol} | ${r.chain_name} | ${poolLiq} | ${failureReasonsText} |\n`;
13151397
});
13161398
markdown += '\n';
13171399
} else {
@@ -1398,6 +1480,24 @@ function generateMarkdownReport(verificationResults) {
13981480
} else {
13991481
markdown += `No logo failures detected. All assets have valid logos that meet the requirements.\n\n`;
14001482
}
1483+
1484+
// Killed Chain Assets subsection
1485+
markdown += `### Killed Chain Assets\n\n`;
1486+
1487+
if (killedChainAssetsVerified.length > 0) {
1488+
markdown += `These verified assets belong to killed chains and can be de-verified (excluding meme tokens):\n\n`;
1489+
markdown += `| Asset | Chain | Base Denom | Comment |\n`;
1490+
markdown += `|-------|-------|------------|----------|\n`;
1491+
1492+
killedChainAssetsVerified.forEach(r => {
1493+
const symbol = r.comment || r.base_denom.substring(0, 40);
1494+
markdown += `| ${symbol} | ${r.chain_name} | \`${r.base_denom}\` | ${r.comment || 'N/A'} |\n`;
1495+
});
1496+
markdown += '\n';
1497+
markdown += `**Note:** Meme tokens are exempt from this requirement and may remain verified on killed chains due to their historical/cultural value.\n\n`;
1498+
} else {
1499+
markdown += `No verified assets from killed chains detected. All verified assets belong to active chains.\n\n`;
1500+
}
14011501
} else {
14021502
markdown += `All assets pass verification checks!\n\n`;
14031503
}
@@ -1429,6 +1529,9 @@ function generateMarkdownReport(verificationResults) {
14291529
function generateJSONReport(verificationResults) {
14301530
const failedChecks = verificationResults.filter(r => !r.allChecksPassed && !r.currently_verified);
14311531

1532+
// Filter killed chain assets (excluding meme tokens) - only verified assets that may need de-verification
1533+
const killedChainAssetsVerified = verificationResults.filter(r => r.chainIsKilled && r.currently_verified && !r.is_meme);
1534+
14321535
// Calculate failure breakdown
14331536
const failureCounts = {
14341537
standardListing: 0,
@@ -1437,7 +1540,8 @@ function generateJSONReport(verificationResults) {
14371540
socials: 0,
14381541
logo: 0,
14391542
poolLiquidity: 0,
1440-
bidDepth: 0
1543+
bidDepth: 0,
1544+
chainStatus: 0
14411545
};
14421546

14431547
const socialsFailureReasons = {};
@@ -1488,12 +1592,20 @@ function generateJSONReport(verificationResults) {
14881592
readyForVerification: verificationResults.filter(r => r.readyForVerification).length,
14891593
alreadyVerified: verificationResults.filter(r => r.currently_verified).length,
14901594
failedChecks: failedChecks.length,
1595+
killedChainAssets: killedChainAssetsVerified.length,
14911596
totalChecked: verificationResults.length
14921597
},
14931598
analysis: {
14941599
failureBreakdown,
14951600
socialsFailureReasons,
1496-
highLiquidityFailing
1601+
highLiquidityFailing,
1602+
killedChainAssets: killedChainAssetsVerified.map(r => ({
1603+
chain_name: r.chain_name,
1604+
base_denom: r.base_denom,
1605+
comment: r.comment,
1606+
is_meme: r.is_meme,
1607+
chainIsKilled: r.chainIsKilled
1608+
}))
14971609
},
14981610
results: verificationResults
14991611
}, null, 2);

LISTING.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ Accessible liquidity of the asset on Osmosis:
4646
- This must work for all asset pairs in the pool
4747
- This would be impossible for pools with a swap fee (or spread) >=2%, which would require special consideration
4848

49+
Chain Status:
50+
- The asset's origin chain must not be marked as "killed" in the Cosmos Chain Registry
51+
- Chains may be marked as killed when they are no longer operational
52+
- Exception: Meme tokens (categorized as "meme") are exempt from this requirement and may remain verified on killed chains due to their historical/cultural value
53+
4954
Asset appearance and functionality must be validated by Osmosis Zone maintainers. This includes:
5055
- Verifying the asset's details (name, [ticker] symbol, logo, description, socials) can be seen on Osmosis Zone
5156
- Verifying that the asset has a price on Osmosis Zone

0 commit comments

Comments
 (0)