Skip to content

Commit 7a12159

Browse files
committed
Add verification check for killed chains
1 parent 139c1d1 commit 7a12159

File tree

2 files changed

+147
-3
lines changed

2 files changed

+147
-3
lines changed

.github/workflows/utility/checkVerificationCriteria.mjs

Lines changed: 142 additions & 3 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
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,15 @@ 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)
1257+
const killedChainAssetsVerified = verificationResults.filter(r => r.chainIsKilled && r.currently_verified && !r.is_meme);
1258+
const killedChainAssetsUnverified = verificationResults.filter(r => r.chainIsKilled && !r.currently_verified && !r.is_meme);
1259+
11821260
markdown += `## Summary\n\n`;
11831261
markdown += `- **Ready for Verification**: ${readyForVerification.length}\n`;
11841262
markdown += `- **Failed Checks**: ${failedChecks.length}\n`;
1263+
markdown += `- **Killed Chain Assets (Verified)**: ${killedChainAssetsVerified.length} (require de-verification)\n`;
1264+
markdown += `- **Killed Chain Assets (Unverified)**: ${killedChainAssetsUnverified.length} (cannot be verified)\n`;
11851265
markdown += `- **Total Checked**: ${verificationResults.length}\n\n`;
11861266

11871267
// Ready for Verification section with asset links
@@ -1423,12 +1503,52 @@ function generateMarkdownReport(verificationResults) {
14231503
});
14241504
}
14251505

1506+
// Killed Chain Assets Section
1507+
if (killedChainAssetsVerified.length > 0 || killedChainAssetsUnverified.length > 0) {
1508+
markdown += `## ⚠️ Killed Chain Assets Requiring De-verification\n\n`;
1509+
markdown += `Assets from chains marked as "killed" in the chain registry (excluding meme tokens):\n\n`;
1510+
1511+
// Currently Verified subsection
1512+
if (killedChainAssetsVerified.length > 0) {
1513+
markdown += `### Currently Verified (${killedChainAssetsVerified.length})\n\n`;
1514+
markdown += `These verified assets belong to killed chains and should be de-verified:\n\n`;
1515+
markdown += `| Asset | Chain | Base Denom | Comment |\n`;
1516+
markdown += `|-------|-------|------------|----------|\n`;
1517+
1518+
killedChainAssetsVerified.forEach(r => {
1519+
const symbol = r.comment || r.base_denom.substring(0, 40);
1520+
markdown += `| ${symbol} | ${r.chain_name} | \`${r.base_denom}\` | ${r.comment || 'N/A'} |\n`;
1521+
});
1522+
markdown += '\n';
1523+
}
1524+
1525+
// Unverified subsection
1526+
if (killedChainAssetsUnverified.length > 0) {
1527+
markdown += `### Unverified (${killedChainAssetsUnverified.length})\n\n`;
1528+
markdown += `These unverified assets belong to killed chains and cannot be verified:\n\n`;
1529+
markdown += `| Asset | Chain | Base Denom | Comment |\n`;
1530+
markdown += `|-------|-------|------------|----------|\n`;
1531+
1532+
killedChainAssetsUnverified.forEach(r => {
1533+
const symbol = r.comment || r.base_denom.substring(0, 40);
1534+
markdown += `| ${symbol} | ${r.chain_name} | \`${r.base_denom}\` | ${r.comment || 'N/A'} |\n`;
1535+
});
1536+
markdown += '\n';
1537+
}
1538+
1539+
markdown += `**Note:** Meme tokens are exempt from this requirement and may remain verified on killed chains due to their historical/cultural value.\n\n`;
1540+
}
1541+
14261542
return markdown;
14271543
}
14281544

14291545
function generateJSONReport(verificationResults) {
14301546
const failedChecks = verificationResults.filter(r => !r.allChecksPassed && !r.currently_verified);
14311547

1548+
// Filter killed chain assets (excluding meme tokens)
1549+
const killedChainAssetsVerified = verificationResults.filter(r => r.chainIsKilled && r.currently_verified && !r.is_meme);
1550+
const killedChainAssetsUnverified = verificationResults.filter(r => r.chainIsKilled && !r.currently_verified && !r.is_meme);
1551+
14321552
// Calculate failure breakdown
14331553
const failureCounts = {
14341554
standardListing: 0,
@@ -1437,7 +1557,8 @@ function generateJSONReport(verificationResults) {
14371557
socials: 0,
14381558
logo: 0,
14391559
poolLiquidity: 0,
1440-
bidDepth: 0
1560+
bidDepth: 0,
1561+
chainStatus: 0
14411562
};
14421563

14431564
const socialsFailureReasons = {};
@@ -1488,12 +1609,30 @@ function generateJSONReport(verificationResults) {
14881609
readyForVerification: verificationResults.filter(r => r.readyForVerification).length,
14891610
alreadyVerified: verificationResults.filter(r => r.currently_verified).length,
14901611
failedChecks: failedChecks.length,
1612+
killedChainAssetsVerified: killedChainAssetsVerified.length,
1613+
killedChainAssetsUnverified: killedChainAssetsUnverified.length,
14911614
totalChecked: verificationResults.length
14921615
},
14931616
analysis: {
14941617
failureBreakdown,
14951618
socialsFailureReasons,
1496-
highLiquidityFailing
1619+
highLiquidityFailing,
1620+
killedChainAssets: {
1621+
verified: killedChainAssetsVerified.map(r => ({
1622+
chain_name: r.chain_name,
1623+
base_denom: r.base_denom,
1624+
comment: r.comment,
1625+
is_meme: r.is_meme,
1626+
chainIsKilled: r.chainIsKilled
1627+
})),
1628+
unverified: killedChainAssetsUnverified.map(r => ({
1629+
chain_name: r.chain_name,
1630+
base_denom: r.base_denom,
1631+
comment: r.comment,
1632+
is_meme: r.is_meme,
1633+
chainIsKilled: r.chainIsKilled
1634+
}))
1635+
}
14971636
},
14981637
results: verificationResults
14991638
}, 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)