ERC-8376 Conformance Test Cases v0.1
ERC-8376 Conformance Test Cases v0.1
The cases a conformant implementation MUST cover at minimum, referenced from the Test Cases section of ERC-8376.
- Score reproducibility. A fixed
SignalVectorunder the reference hard-rug profile yields a deterministic score.liquidityRemoved = 6000,lpLockedShare = 0,proceedsWithdrawnShare = 9000,lpLockRemaining = 0,deployerSellRatio = 7000,privilegedPowers = 0x0011,priorUpheldClaims = 2scores in the Conclusive band. - Protective polarity. The same vector with
lpLockedShare = 10000andlpLockRemaining = 365 daysscores materially lower. A protective signal at full strength MUST reduce the score, never raise it. - Unavailable signals excluded. Setting
priorUpheldClaims = type(uint16).maxyields the weighted mean over the remaining signals, not a score diluted by a zero contribution. - Outcome signals rejected. A report whose evidence set includes a price or market-cap field as a scored input MUST be rejected with
OutcomeSignalNotPermitted. - Honest failure scores low. A launch with locked liquidity, no deployer sales, no retained powers, and a 95 percent price decline MUST score in the None or Weak band. This is the test that decides whether the standard is deployable.
- Release schedule respected.
releaseProceedsat the midpoint releases at most half; calling repeatedly within one block releases nothing further. - Freeze halts release, and cannot be indefinite.
releaseProceedsreverts whileFrozen; a launch frozen with no adjudication withinmaxFreezeDuration()returns toReleasing. - No automatic refund. No sequence of
submitReportcalls at any score or confidence opens a refund pool without an upheld claim. - Pro-rata correctness. With three buyers at 1, 2 and 7 ether and a pool of 5 ether, entitlements are 0.5, 1 and 3.5 ether, and the pool is fully drained with no residue.
- Net contribution. A buyer who sold their entire allocation for more than they paid has an entitlement of zero and MUST NOT reduce other buyers’ shares.
- Pull, not push. A launch with 10,000 recorded buyers can open a refund pool in constant gas.
- Rejected claim forfeits bond. After
adjudicate(claimId, Rejected, 0), the launch resumes releasing and the claimant’s bond is not returned. - Guard never reverts.
checkLaunchreturns successfully for unknown launches, retracted reports, and settled launches. - Resolution from a token address.
launchesOf(token)returns the launch, andescrowOf,venueOf,deployerOfandtokenOfround-trip correctly. A consumer holding only a token address can reach the guard. - Identifier is derivable. Recomputing
keccak256(abi.encode(chainid, escrow, token, deployer, nonce))independently yields the samelaunchIdthe escrow assigned. - Relaunch does not collide. The same token relaunched by the same deployer receives a distinct
launchId, and both appear inlaunchesOf. - Deployer history is on-chain.
launchesBy(deployer)returns every launch by that address, so serial-deployer analysis needs no off-chain linkage. - Identifier is chain-bound. Deriving the same launch under a different
block.chainidyields a differentlaunchId, so an identifier cannot be replayed across networks. - Unsupported vector version is not scored. A report declaring a
vectorVersionthe consumer does not implement MUST be rejected withUnsupportedVectorVersionrather than scored as though it were version 1. - Extension signals score on identical terms. A
PATTERN_IMPERSONATIONreport whose base signals all read clean scores in the Elevated band or above onsymbolCollisionandnameSimilarityalone, and an extension field reported as unavailable is excluded from both sums exactly as a base signal is. - Extension leaves cannot collide. An evidence leaf for an extension field derived as
keccak256(abi.encode(extensionSchema, fieldName))differs from every base-signalfieldId. - Detector reward is bounded and correctly attributed. After
executeRemedy,claimDetectorRewardpaysdetectorFeeBpsof the restitution to the detector recorded against the referenced report, never to the caller and never to the relayer of asubmitAndClaim, and reverts on a claim that is notExecuted. AdetectorFeeBpsexceedingfeeBpsMUST NOT be settable. - Liquidity share is pool-agnostic. A launch on a pool minting a fungible liquidity token and one whose positions are non-fungible both yield
lpLockedSharein basis points of pool liquidity. Where a liquidity token is named it decides the value, and supplied liquidity amounts do not override it. A pool holding no liquidity, or one reporting more locked than it holds, yields the unavailability sentinel rather than zero. - Disclosure at the point of purchase. A consumer-conformant venue surfaces
abuseScore,confidenceand the report’sevidenceURIto the buyer, and presents a launch with no live report as unknown rather than as safe. - Residual bond comes home. A launch that completes with no claim against it returns its bond to the party that posted it, once
Settledand once no buyer can still claim or pull. A launch that recorded no purchases returns its bond on the same terms. Where two parties posted, what survives a slashing is apportioned in the proportions posted, and a second attempt returns nothing. - A freeze renews, and only for a reason. A second claim against a launch already frozen extends the window, and
releaseProceedsstill reverts after the first window would have lapsed. An upheld decision extends it again, so the remedy is executed against proceeds that are still there. A launch with no open claim returns toReleasingwithinmaxFreezeDuration()of the last renewal, and aSettledlaunch refuses a freeze while still accepting a claim against its bond. - Volume cannot silence a registry. One bonded address publishing padding against a launch does not change what the reads return:
activeScorestill names the genuine report and its score, and corroboration still counts the genuine detectors. Each detector counts once however many reports it holds, and a detector slashed belowminDetectorBond()stops counting toward corroboration while what it published remains visible to the guard. - The deployer is declared, never inferred. A launch whose token was created by the venue’s own factory scores against the applicant the directory records, not against the factory. Two launches from the same factory with different applicants produce different deployer-derived signals. A launch with no directory entry, or one recording no deployer, reports every deployer-derived signal as the unavailability sentinel rather than as zero, and never substitutes the creating address.
- A pool emptied by selling is a pool emptied. A launch whose liquidity token was sent to a burn address, and whose pool then went from a peak holding of the paired asset to substantially none because supply was sold into it, reports
liquidityRemovedat or near the maximum rather than zero, and reportslpLockedShareandlpLockRemainingas the unavailability sentinel rather than as total protection. The same launch with its pool intact reports the lock. A launch that never locked anything keeps its zero. - Capability is not conduct. A launch holding one named privileged power, whose other signals in a pattern’s profile are unavailable, reports that pattern as unavailable rather than as 100. A launch holding a named power and liquidity that no lock or burn address holds, with no signal of conduct established, reports the pattern no higher than the Elevated band. Adding one established conduct signal permits the full range again, and an upheld claim or an extension signal counts as conduct.
- A fragment is not a certainty. A launch establishing one of the four signals in the unlock-exit profile reports that pattern no higher than the Elevated band, whatever that signal reads. Establishing three of the four permits the full range.
- Distribution is not dilution. A launch whose supply has doubled, where the deployer and every address sharing a funding ancestor with it hold none of it, reports
supplyInflationat or near zero and does not reach the Conclusive band for mint dilution. The same doubling with the supply held by the deployer reports it in full. - A honeypot is established by sellability, not by bytecode. A launch whose pool holds paired liquidity, whose supply has not moved and which exposes none of the named privileged functions, reports
PATTERN_HONEYPOTas unavailable when scored from the base vector alone, and reaches the Conclusive band when the sellability schema reports every sampled holder blocked. The same vector with holders selling freely scores in the None band, and a schema reporting fewer than three sampled holders reports the share as the unavailability sentinel. Supplying another pattern’s schema is refused rather than read as this one’s fields. - One registry, three authorities. Two venues with separate escrows and separate remediation contracts report into one registry. A venue cannot publish a report in a detector’s name until that detector has approved it as a relay, and once approved it carries that detector’s reports at either venue and no other detector’s. No venue’s remediation contract can take a detector’s bond; only the registry’s detector adjudicator can, only over a report that detector published, and a slash naming an unknown report reverts. Forfeited bonds paid in by one remediation contract cannot be drawn by another. The registry refuses a detector bond from its own adjudicator, so the party judging whether a report was false is never a party the judgement would cost.