| """ |
| Tests for Governance Attack & Concentration Risk Detector |
| ========================================================== |
| Tests holder concentration analysis, governance parameter extraction, |
| flash-loan feasibility assessment, and risk scoring. |
| """ |
|
|
| import sys |
| from pathlib import Path |
|
|
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) |
|
|
| from app.governance_attack_detector import ( |
| DEXSCREENER_API, |
| LOW_QUORUM_PCT, |
| TOP_10_CRITICAL_PCT, |
| TOP_HOLDER_CRITICAL_PCT, |
| GovernanceParams, |
| _parse_holders, |
| _score_governance_risk, |
| ) |
|
|
|
|
| class TestHolderParsing: |
| """Holder data parsing tests.""" |
|
|
| def test_parse_empty(self): |
| holders = _parse_holders([]) |
| assert holders == [] |
|
|
| def test_parse_single_holder(self): |
| raw = [{"address": "0xabc", "percentage": "50.5"}] |
| holders = _parse_holders(raw) |
| assert len(holders) == 1 |
| assert holders[0].address == "0xabc" |
| assert holders[0].percentage == 50.5 |
|
|
| def test_parse_exchange_label(self): |
| raw = [ |
| {"address": "0xbinance1", "percentage": "10.0", "label": "Binance"}, |
| {"address": "0xrandom", "percentage": "5.0", "label": ""}, |
| ] |
| holders = _parse_holders(raw) |
| assert holders[0].is_exchange is True |
| assert holders[1].is_exchange is False |
|
|
| def test_parse_sorted(self): |
| raw = [ |
| {"address": "0xsmall", "percentage": "1.0"}, |
| {"address": "0xbig", "percentage": "50.0"}, |
| {"address": "0xmedium", "percentage": "10.0"}, |
| ] |
| holders = _parse_holders(raw) |
| assert holders[0].address == "0xbig" |
| assert holders[1].address == "0xmedium" |
| assert holders[2].address == "0xsmall" |
|
|
| def test_parse_etherscan_format(self): |
| raw = [{"TokenHolderAddress": "0xdef", "TokenHolderQuantity": "25.0"}] |
| holders = _parse_holders(raw) |
| assert len(holders) == 1 |
| assert holders[0].address == "0xdef" |
| assert holders[0].percentage == 25.0 |
|
|
| def test_parse_contract_flag(self): |
| raw = [{"address": "0xcontract", "percentage": 30, "is_contract": True}] |
| holders = _parse_holders(raw) |
| assert holders[0].is_contract is True |
|
|
| def test_parse_malformed_pct(self): |
| raw = [{"address": "0xbad", "percentage": "N/A"}] |
| holders = _parse_holders(raw) |
| assert holders[0].percentage == 0.0 |
|
|
|
|
| class TestRiskScoring: |
| """Governance risk scoring tests.""" |
|
|
| def test_no_holders_no_gov(self): |
| score, level, _flags = _score_governance_risk(0.0, 0.0, None) |
| assert score >= 0 |
| assert level in ("LOW", "MEDIUM") |
|
|
| def test_critical_top_holder(self): |
| score, level, flags = _score_governance_risk(51.0, 60.0, None) |
| assert score >= 35 |
| assert level == "CRITICAL" or level == "HIGH" |
| assert any("CRITICAL" in f for f in flags) |
|
|
| def test_high_top_holder(self): |
| score, level, _flags = _score_governance_risk(35.0, 55.0, None) |
| assert score >= 20 |
| assert level == "HIGH" or level == "MEDIUM" |
|
|
| def test_top_10_cartel(self): |
| score, _level, flags = _score_governance_risk(10.0, 85.0, None) |
| assert score >= 20 |
| assert any("cartel" in f.lower() for f in flags) |
|
|
| def test_no_timelock_critical(self): |
| params = GovernanceParams(is_governance_contract=True, has_timelock=False) |
| score, _level, flags = _score_governance_risk(5.0, 10.0, params) |
| assert score >= 25 |
| assert any("CRITICAL" in f or "No timelock" in f for f in flags) |
|
|
| def test_low_quorum(self): |
| params = GovernanceParams( |
| is_governance_contract=True, |
| has_timelock=True, |
| quorum_threshold_pct=0.5, |
| timelock_delay_seconds=86400, |
| ) |
| score, _level, flags = _score_governance_risk(5.0, 10.0, params) |
| assert score >= 20 |
| assert any("quorum" in f.lower() for f in flags) |
| assert any("flash" in f.lower() for f in flags) |
|
|
| def test_safe_governance(self): |
| params = GovernanceParams( |
| is_governance_contract=True, |
| has_timelock=True, |
| quorum_threshold_pct=4.0, |
| timelock_delay_seconds=172800, |
| voting_period_blocks=50000, |
| proposal_threshold_pct=1.0, |
| ) |
| score, level, _flags = _score_governance_risk(5.0, 20.0, params) |
| assert score < 30 |
| assert level == "LOW" or level == "MEDIUM" |
|
|
| def test_very_short_voting(self): |
| params = GovernanceParams( |
| is_governance_contract=True, |
| has_timelock=True, |
| voting_period_blocks=50, |
| quorum_threshold_pct=5.0, |
| timelock_delay_seconds=86400, |
| ) |
| score, _level, flags = _score_governance_risk(5.0, 10.0, params) |
| assert score >= 15 |
| assert any("voting period" in f.lower() for f in flags) |
|
|
| def test_short_timelock(self): |
| params = GovernanceParams( |
| is_governance_contract=True, |
| has_timelock=True, |
| timelock_delay_seconds=3600, |
| quorum_threshold_pct=5.0, |
| ) |
| _score, _level, flags = _score_governance_risk(5.0, 20.0, params) |
| assert any("timelock" in f.lower() for f in flags) |
|
|
| def test_flash_loan_flag(self): |
| params = GovernanceParams( |
| is_governance_contract=True, |
| has_timelock=True, |
| quorum_threshold_pct=0.3, |
| timelock_delay_seconds=86400, |
| ) |
| score, _level, flags = _score_governance_risk(5.0, 15.0, params) |
| |
| assert any("flash-loan" in f.lower() for f in flags) |
| assert score >= 30 |
|
|
| def test_score_capped_at_100(self): |
| params = GovernanceParams( |
| is_governance_contract=True, |
| has_timelock=False, |
| quorum_threshold_pct=0.1, |
| timelock_delay_seconds=0, |
| voting_period_blocks=50, |
| proposal_threshold_pct=0.01, |
| ) |
| score, level, _flags = _score_governance_risk(TOP_HOLDER_CRITICAL_PCT + 10, TOP_10_CRITICAL_PCT + 10, params) |
| assert score <= 100 |
| assert level == "CRITICAL" |
|
|
|
|
| class TestGovernanceParams: |
| """Governance parameters data class tests.""" |
|
|
| def test_defaults(self): |
| p = GovernanceParams() |
| assert p.has_timelock is False |
| assert p.timelock_delay_seconds == 0 |
| assert p.quorum_threshold_pct == 0.0 |
| assert p.voting_period_blocks == 0 |
|
|
| def test_governance_contract_detected(self): |
| p = GovernanceParams( |
| is_governance_contract=True, |
| quorum_threshold_pct=4.0, |
| voting_period_blocks=10000, |
| ) |
| assert p.is_governance_contract is True |
| assert p.quorum_threshold_pct > 0 |
| assert p.voting_period_blocks > 0 |
|
|
|
|
| class TestConstants: |
| """Constant threshold tests.""" |
|
|
| def test_low_quorum_under_1_pct(self): |
| assert LOW_QUORUM_PCT == 1.0 |
|
|
| def test_critical_holder_50_pct(self): |
| assert TOP_HOLDER_CRITICAL_PCT == 50.0 |
|
|
| def test_top_10_critical_80_pct(self): |
| assert TOP_10_CRITICAL_PCT == 80.0 |
|
|
|
|
| class TestEndpointReferences: |
| """Verify API endpoint constants are well-formed.""" |
|
|
| def test_dexscreener_url(self): |
| assert "{}" in DEXSCREENER_API |
| assert DEXSCREENER_API.startswith("https://") |
|
|