feat(frontend): treasury available-supply accounting, protocol-token CR haircut, and gated color tiers #16
Labels
No labels
bug
docs
documentation
duplicate
enhancement
frontend
good first issue
help wanted
invalid
missing-implementation
priority
medium
product
QA
question
testing
UX
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/ustr-cmm#16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fix
/treasuryso collateralization cannot be inflated by ecosystem-issued tokens (UST1, USTR, cUSTC, cLUNC) — the same distortion as a company counting treasury stock as an asset. Haircut those legs out of LP NAV used for CR. Replace issuance mint/burn/circ with + Outstanding − CMM-owned liquidity = Available Supply, and use UST1 available supply as the CR denominator. Gate Key Ratios: show numbered ratios and the ECONOMICS color only when every CR-relevant price is loaded; otherwise the section is only the messageprices not loaded, cannot display key ratios.Depends on #11 (liability CR) and #14 (LP reserve NAV). This issue revises both: UST1/USTR LP legs leave the CR numerator; the CR denominator becomes available supply, not raw
total_supply.Current codebase
frontend/src/pages/TreasuryPage.tsxIssuanceCards +RatiosCard. Copy still says wrap LP legs are omitted because native already counts — UST1/USTR LP legs still enter CR.frontend/src/utils/constants.tsTREASURY_HOLDING_SKIP_SYMBOLSUSTR|UST1|CLUNC|CUSTC. Raw protocol CW20s are not treasury asset rows (#11/#14).frontend/src/hooks/useTreasury.tsisRawProtocolHolding— does not even query treasury balances of UST1/USTR/cLUNC/cUSTC. Issuance is CW20token_info.total_supplyonly (minted = supply,burned = 0). CR denominator = full outstanding UST1.frontend/src/utils/lpNav.ts,lpEligibility.tsisCrEligibleLeg: ust1, ustr, other = yes; wrap/unknown = no. UST1 LP leg valued at$1(UST1_LIABILITY_USD). Wrap legs haircut fromcrUsdbut still indisplayUsd. Fixture: UST1/USTR 10% → CR $200; UST1/cUSTC → CR $100 (UST1 kept).frontend/src/utils/treasuryRatios.tsCR% = (priced assets USD + LP crUsd) / whole outstanding UST1 × 100. Incomplete prices: omit + banner, still render numbers.∞iff outstanding UST1 query succeeded and supply=== 0.frontend/src/components/treasury/IssuanceCard.tsxtotal_supply. No CMM-owned line.frontend/src/components/treasury/RatiosCard.tsxCR_TIERS), USTC per UST1, Assets/Liabilities, USTR Backing. Incomplete banner + N/A. No named RED/YELLOW/GREEN/BLUE status or operational copy. Color still paints the CR number even when prices are incomplete.useTreasury.tswhole USTC / whole USTR outstanding— not priced assets, not available USTR.CR_TIERSredBelow: 95,yellowBelow: 110,greenAtMost: 190. Matches ECONOMICS bands, not the swap/staking copy below.docs/ECONOMICS.mdskills/frontend-ust1-ratios/SKILL.md,skills/frontend-treasury-lp-nav/SKILL.mdMainnet pins (do not invent):
terra16j5u6ey7a84g40sr3gd94nzg5w5fm45046k9s2347qhfpwm5fr6sem3lr2terra1f0eqgy9w7e5e7up97vjudqwx38tesf8ylx75x2lv3nwm0clry0pqmgfy72terra1vy3kc0swag2rhn7jz6n72jp0l2ns0p6r6ez5grxq5uhj2rvs97fqfsetxvterra1437qslye72t7qmmahn4t5chz50r8a62g45phwkquwpyu2l62u6ksqssgdgterra1nap4dxh9tv35v0ynd9m4k6zt6c0dq6weszc4j5m564kjls56hu7qcr56chhttps://finder.terraclassic.community/columbus-5Why this is needed
Treasury stock distortion. Counting UST1 (the liability) or USTR (ecosystem-issued) as assets, including the UST1/USTR share of an LP, inflates CR the same way a company booking its own shares as assets inflates equity ratios. #14 currently intends that netting (UST1 leg at $1 vs circulating supply). That still books protocol tokens on the asset side and uses gross outstanding as the liability. If CMM owns a large LP, CR looks healthier than the float available to the market.
Wrap / native double-count is only half-fixed. Raw cLUNC/cUSTC are skipped and wrap LP legs are haircut, but UST1/USTR LP legs still enter
crUsd. AUST1/cUSTCpool today contributes the UST1 side to CR. Under this issue it must contribute neither protocol leg — only a true external quote (vFDUSD, LUNC, ALPHA, …).Issuance cards lie about float. CW20 has no lifetime mint/burn. Showing Outstanding / Burned=0 / Circulating=
total_supplyhides how much of that supply sits in CMM (treasury spot + LP claims). Operators and users need Available Supply = outstanding − CMM-owned liquidity. That available UST1 is the CR denominator.Key Ratios are unsafe when prices are partial. Incomplete mode still paints a colored CR from a partial numerator. A missing ALPHA/vFDUSD/LUNC print can show GREEN/BLUE while real CR is RED. If any CR-relevant price is missing, do not display ratios at all.
Tier meaning on the page must match product behavior (swap + staking rewards), not only a number color:
< 95%95% ≤ CR < 110%110% ≤ CR ≤ 190%> 190%(incl.∞)Constraints / guardrails
uluna/uusdare assets (they are not ecosystem-issued CW20s).otheronly (LUNC, USTC, ALPHA, vFDUSD, other tokenlist underlyings).ust1,ustr,wrap,unknown→ out ofcrUsd.unknownstill fail-closed for that LP (crUsd = null, incomplete — which then hides Key Ratios per the price gate).floor(reserve_i × lp_balance / total_share)across allowlistedtype: "lp"pins only. Holder address = pinned treasury. Do not crawl window / wrap-mapper / airdrop /all_accounts/ LCD txs (quota + abuse). Do not invent other “CMM” wallets.outstanding − cmm_owned, clamp display at0if a bug would go negative; fail closed (issuance + CR incomplete / hidden), never a negative float. Outstanding = CW20token_info.total_supplyviagetTokenInfoStrict(never swallow errors as supply0).∞only when UST1 supply query and CMM-owned query succeeded and available supply=== 0. Query failure → Key Ratios hidden or N/A path under the price/data gate — never∞.$1for the ratio (CR% = assetsUsd / available_UST1 × 100). Do not put UST1 into the numerator at $1 anymore.balance > 0, and every LPotherleg that would entercrUsd). Price queries still loading, CEX/DEX/oracle miss, orincomplete === true→ replace the entire Key Ratios card body with exactly:prices not loaded, cannot display key ratios. No CR number, no N/A tiles, no incomplete banner, no color, no USTC-per-UST1, no A/L, no USTR backing.$0or$1. vFDUSD still session oracle (#10). Do notsimulate_swapLP mints.rawToWholeNumberonly.UST1-USTRis notUST1.type: "lp"never uses the raw-protocol skip.frontend-ust1-ratiosandfrontend-treasury-lp-navskills (UST1/USTR legs out of CR; available supply). Aligndocs/ECONOMICS.mdtreasury-facing tier copy with the table above or explicitly mark auction wording as historical — do not leave the page saying “healthy GREEN” while ECONOMICS still says GREEN is “redemption auctions” without a pointer.contractServiceLCD spacing; no faster poll than current treasury refetch.Relevant files
frontend/src/hooks/useTreasury.tsfrontend/src/utils/treasuryRatios.ts(+.test.ts)frontend/src/utils/lpEligibility.ts(+.test.ts)isCrEligibleLeg→otheronlyfrontend/src/utils/lpNav.ts(+.test.ts)frontend/src/services/treasuryLp.tsfrontend/src/types/treasury.tsfrontend/src/components/treasury/IssuanceCard.tsxfrontend/src/components/treasury/RatiosCard.tsxfrontend/src/components/treasury/TreasuryAssetsCard.tsxfrontend/src/pages/TreasuryPage.tsxfrontend/src/utils/constants.tsCR_TIERS+ skip list (keep); drop/repurposeUST1_LIABILITY_USDfor CR legsfrontend/src/hooks/usePrices.tsuseTreasury)skills/frontend-ust1-ratios/SKILL.md,skills/frontend-treasury-lp-nav/SKILL.mddocs/ECONOMICS.md,docs/ARCHITECTURE.mdRecommended direction
Protocol inventory (not asset rows) — in
fetchTreasuryData, query treasury CW20 balances for pinned UST1, USTR, cLUNC, cUSTC. Keep them out ofassets/ the holdings grid.CMM-owned from LPs — for each allowlisted LP with
lp_balance > 0and valid reserves, addclaim_rawof each protocol leg to that token’scmmOwned. Fail closed if pool query fails but LP balance> 0(cannot certify available supply).IssuanceCard — replace the three mint/burn/circ rows with:
+ Outstanding=total_supply− CMM-owned liquidity= spot + LP claimsisCrEligibleLeg— return true only forkind === 'other'. UpdatelpNavfixtures: UST1/USTR →crUsd = 0(display may still be $200); UST1/cUSTC →crUsd = 0; UST1/vFDUSD → CR = vFDUSD side only; cLUNC/LUNC → CR = LUNC side only (unchanged).computeTreasuryRatios— takeust1AvailableRaw. Numerator = spot non-protocol USD + LPcrUsd. Denominator = whole available UST1. Keep∞/NaNrules with available supply. Redefine or remove USTR Backing: do not keep USTC/USTR outstanding as a “backing” number. Prefer dropping that tile in favor of the named CR color + operational lines (swap / rewards / system state). Keep USTC per available UST1 and Assets/Liabilitiesx.RatiosCardprice gate —pricesReady && !incomplete && ust1SupplyStatus !== 'unknown'(and CMM-owned known). Else single message, nothing else. When ready: color the CR number and show the tier name (RED/YELLOW/GREEN/BLUE) with the three operational bullets from the table.∞→ BLUE.Boundaries (inclusive as implemented today):
< 95RED;[95, 110)YELLOW;[110, 190]GREEN;> 190BLUE.Acceptance criteria
crUsdexcludes UST1, USTR, cUSTC, and cLUNC legs; only non-protocol (other) legs enter CR.+ Outstanding,− CMM-owned liquidity, Available Supply (not minted/burned/circ).pool {}+ balance math.otherNAV.0(queries succeeded) → ratios∞and BLUE only if prices are fully loaded.prices not loaded, cannot display key ratios.$0/$1; no LP mintsimulate_swap; skip-list still exact.Test plan (all paths)
Holdings / haircut
UST1-USTRLP row still appears when treasury LP balance> 0;crUsd = 0.UST1/cUSTC: display may include both;crUsd = 0.cLUNC/LUNC:crUsd= LUNC claim USD only.USTR/LUNC:crUsd= LUNC only (USTR out — regression vs #14).UST1/vFDUSD:crUsd= vFDUSD claim USD only; vFDUSD from session oracle.cUSTCaddress in an unlisted pair: not in CR. Unknown leg on a pinned LP →crUsd = null→ Key Ratios hidden.total_share == 0/lp_balance > total_share/ failed pool: fail closed for that LP and for CMM-owned of its protocol legs.Available supply
token_info.total_supply.XUST1, no LP → CMM-ownedX, availablesupply − X.100(floor).0→ available = outstanding.getTokenInfofailure → no fake∞; Key Ratios hidden or gated.CR math
crUsd = 100_000→ CR numerator +100k only.rawToWholeNumberonly.Key Ratios UI
> 0→ only the not-loaded message (no partial GREEN CR).94.99RED;95YELLOW;109.99YELLOW;110GREEN;190GREEN;190.01BLUE;∞BLUE.Integration
cd frontend && npm test— update #14 fixtures that expected UST1/USTR incrUsd.Test plan (attack, hack, abuse)
crUsd; grepisCrEligibleLegonlyotheruusdcUSTC/UST1UST1-USTRskipped as holdingpairspaginationgetTokenPriceUsd(lpAddress)getTokenInfoswallow 0∞/ BLUEgetTokenInfoStrict; failure hides ratiosNumber(bigint)rawToWholeNumberisTerraContractAddressnoopenerVerification criteria
CR = (Σ non-protocol spot USD + Σ LP other-leg NAV) / whole(UST1 available) × 100matches the page when prices are complete.total_supply − treasury_spot_UST1 − Σ LP UST1 claims; same for USTR/cLUNC/cUSTC on their cards.isCrEligibleLegdoes not return true forust1orustr; no protocol symbol in the CR asset loop except as LP display / CMM-owned inventory.prices not loaded, cannot display key ratios— no colored %, no N/A grid.∞→ BLUE.cd frontend && npm testgreen with updated fixtures.marked as related to #11
marked as related to #14
Also need to check treasury holdings as its receiving tokens from cl8y dex, so should load token list and possibly use indexer data from cl8y dex to speed up page loads and reduce lcd/rpc calls. Protocol tokens such as cUSTC, cLUNC, USTR and UST1 held by treasury should not be included in the CR in either numerator or denominator to prevent double counting
mentioned in commit
77c4a4ea0dmentioned in merge request !34
mentioned in merge request !35
mentioned in commit
f4319ae280mentioned in commit
c121ff58eaMerge verification for !35 (merged into
masterasf4319ae).Acceptance criteria (code + unit tests): all 11 PASS. Combined tree after stacking !36 is
80/80frontend tests green (availableSupply,treasuryRatios,lpNav,lpEligibility,crTiers).Problems / leftover (not merge-blocking):
(non-protocol spot USD + LP other NAV) / available UST1) still needs a post-deploy check onust1cmm.com.prices not loaded, cannot display key ratios. Matches the skill, but the string is imprecise for inventory failures.On-chain CR / swap / staking-reward enforcement remains explicitly out of scope (page copy is status display only).
mentioned in issue #18
marked as related to #18
Post-merge leftovers tracked in #18 (live CR calculator, CL8Y holdings/indexer, Key Ratios copy nit).
mentioned in merge request !39