Ethene Labs is a venture studio focused on token advisory and token GTM.

Token Advisory

Token economics design, market maker strategy, and exchange listing strategy.

GTM

Supercharging growth for Web3 teams.

Agency

Distribution of high-engagement community campaigns through KOLs.

VALIDATORS

Participating in consensus of top Layer-1 blockchains.

Team

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

ETHENE LABS

Selected Clients

tWITTER

LINKEDLIN

Selected Clients

tWITTER

LINKEDLIN

(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); })();