Thetanuts Finance

A decentralised on-chain options protocol focused on altcoin options


Total Value Locked
0 M

Trading Volume
0 M

Premiums Earned
0 M

Total Users
0

MAIN PRODUCTS

Vaults

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Speculate with leverage

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Yield Magnifer

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

KEY FEATURES

Go Long or Short

Focused on Altcoin Options

Intuitive Trading

SELECTED PARTNERS

A decentralised on-chain options protocol focused on altcoin options

Learn

Documentation

FAQ

Analytics

Resources

Security

Legal

Press Kit

Quick Links

Leaderboard

Vesting

(function () { const wrapper = document.querySelector('.hero-wrapper'); if (!wrapper) return; const video = wrapper.querySelector('.hero-video'); const lines = wrapper.querySelectorAll('.line'); const NUM_LINES = lines.length; const FADE_RATIO = 0.25; const LERP_SPEED = 0.12; let duration = 0; let targetTime = 0; let currentTime = 0; let ready = false; function initVideo() { duration = video.duration; targetTime = duration; currentTime = duration; video.currentTime = duration; ready = true; } video.addEventListener('loadedmetadata', initVideo); // Load the whole video into memory and play it from a blob URL. // This removes network latency from scroll-driven seeking — on a live // server, seeking via currentTime can stall waiting for byte-range // requests, causing jerky scrubbing even though it's smooth on // localhost. With a blob URL, every frame is already local. const remoteSrc = video.dataset.src; if (remoteSrc) { fetch(remoteSrc) .then((res) => res.blob()) .then((blob) => { video.src = URL.createObjectURL(blob); }) .catch(() => { video.src = remoteSrc; }); } // Cache layout measurements instead of reading them every animation // frame. getBoundingClientRect()/offsetHeight force a synchronous layout // recalculation; doing that every frame while also writing styles every // frame (the opacity/transform updates below) causes layout thrashing — // cheap on a tiny test page, but very expensive on a full WordPress page // with hundreds of elements, which is what causes scroll jank live. let total = 0; function measure() { const rect = wrapper.getBoundingClientRect(); const offsetTop = rect.top + window.scrollY; total = offsetTop + (wrapper.offsetHeight - window.innerHeight); } measure(); window.addEventListener('resize', measure); window.addEventListener('load', measure); function getProgress() { let p = total > 0 ? window.scrollY / total : 0; return Math.min(Math.max(p, 0), 1); } function updateText(progress) { const segment = 1 / NUM_LINES; lines.forEach((line, i) => { const start = i * segment; const end = start + segment; const fade = segment * FADE_RATIO; let opacity = 0; let shift = 12; if (progress >= start && progress <= end) { if (progress < start + fade) { const t = (progress - start) / fade; opacity = t; shift = 12 * (1 - t); } else if (progress > end - fade) { const t = (end - progress) / fade; opacity = t; shift = -12 * (1 - t); } else { opacity = 1; shift = 0; } } line.style.opacity = opacity; line.style.transform = `translate(-50%, calc(-50% + ${shift}px))`; }); } function loop() { if (ready) { const progress = getProgress(); targetTime = duration * (1 - progress); currentTime += (targetTime - currentTime) * LERP_SPEED; if (Math.abs(currentTime - video.currentTime) > 0.01) { video.currentTime = currentTime; } updateText(progress); } requestAnimationFrame(loop); } requestAnimationFrame(loop); })();