WeftWebsite audit · 9 Sep 2026
▸ Audit

Website audit

An independent-style technical review of the public website at useweft.ink: how it is delivered, how it is protected, how fast it loads, how accessible it is and how it behaves when things go wrong. Findings are listed with their status. Everything measured here is reproducible with the tools named below.

Scope

The web application served at useweft.ink: HTML, JavaScript, CSS, fonts, images, the read-only /api/chain proxy and the HTTP layer in front of them.

Out of scope: the smart contracts the site talks to (perpetual, index registry, token) and the wallet software you connect with. This page makes no claims about them. It is not a security audit of on-chain code.

Method: Lighthouse 12 (desktop and simulated mobile), axe-core 4.10 against WCAG 2.1 A/AA, HTTP header and delivery inspection, manual review of loading, empty and error states. Run on 9 September 2026 against the current release.

Scores

Lighthouse, landing page. Mobile is a simulated mid-range phone on throttled 4G, which is why it is lower than desktop.

Performance · desktop100
Performance · mobile88–90
Accessibility100
Best practices96
SEO100
Markets page · mobile95
MetricDesktopMobile (simulated)
First contentful paint0.5 s2.5 s
Largest contentful paint0.6 s3.0 s
Total blocking time0 ms110–160 ms
Cumulative layout shift0.0070.075
Time to first byte (edge, cold)~0.3 s

Findings

Severity reflects impact on visitors, not exploitability. "Fixed" means the change is in the current release.

Sev.AreaFindingStatus
HighDeliveryThe main script (790 KB) and stylesheets were served uncompressed. Now Brotli or gzip depending on the browser: the script is 223 KB on the wire.Fixed
HighDeliveryNo cache headers on any asset, so every visit re-downloaded everything. Hashed assets, fonts and logos are now cached for a year as immutable; HTML revalidates on every load.Fixed
HighSecurityNo security headers. Added a Content Security Policy (scripts only from this origin, connections only to this origin and the chain RPC, no framing), X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy and HSTS for one year.Fixed
MedSecurityThe site could be embedded in third-party frames, which matters for anything that talks to a wallet. Framing is now refused at both the CSP and X-Frame-Options level.Fixed
MedAccessibilityLow-contrast text: secondary captions, the ticker strip and footer labels were between 2.3:1 and 4.5:1. Colours adjusted; every page now passes WCAG AA contrast with zero axe violations.Fixed
MedAccessibilityThe duplicated ticker strip (marked hidden for screen readers) still contained keyboard-focusable links. Removed from the tab order.Fixed
MedAccessibilityPages had no h1, and the landing page jumped from h1 to h3. Headline elements now carry the correct levels.Fixed
MedSEONo robots.txt or sitemap, and unknown URLs returned 200 with the landing page (soft 404). Both files exist now, and unknown paths return a real 404 with a designed page.Fixed
MedSEONo Open Graph or Twitter Card metadata and no canonical URL, so shared links had no preview. Added, with a 1200×630 preview image.Fixed
LowPerformanceThe font stylesheet was a separate render-blocking request. It is now inlined in the HTML; font files are self-hosted.Fixed
LowPerformanceResponses from the /api/chain proxy (up to 10 KB of hex) were uncompressed. Now gzipped above 1 KB.Fixed
LowReliabilityTwo tickers without a logo produced 404 requests on every page that showed them. Placeholder monograms are served instead.Fixed
LowReliabilityLoading states were plain dashes and a line of text with no upper bound. Skeleton placeholders now stand in for content, and a "still reading" notice appears after nine seconds if the chain has not answered.Fixed
MedPerformanceSingle 790 KB script bundle with roughly 145 KB unused on the landing page. Splitting it by route needs a source-level build change, not a delivery tweak. Mobile largest-contentful-paint of about 3 s is mostly script start-up on a throttled CPU.Open
LowPerformanceCompany logos are served as 128 px PNGs into 22 px slots (about 4 KB each, cached). Smaller variants would save a few kilobytes per page.Open
LowDeliverywww.useweft.ink does not resolve. Visitors who type it get nothing rather than a redirect. Needs a DNS record and a redirect to the apex domain.Open
LowBest practicesNo source maps are published, which costs a few Lighthouse points and makes production errors harder to read. Deliberate for now.Accepted
LowSecurityThe CSP allows inline styles ('unsafe-inline' for style-src) because the application sets styles from JavaScript. Scripts remain restricted to this origin.Accepted

Privacy and third parties

Reliability

Response headers

As served by the current release.

content-security-policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';
  img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' https://rpc.mainnet.chain.robinhood.com;
  frame-ancestors 'none'; object-src 'none'; base-uri 'self'; form-action 'self'
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=(), payment=()
cross-origin-opener-policy: same-origin
cache-control: public, max-age=31536000, immutable   (hashed assets, fonts, logos)
content-encoding: br                                (text assets, gzip fallback)

How to reproduce

This page is updated with each release that changes delivery, headers or accessibility. Last run: 9 September 2026.