nejc.dev
← Projects

Koyo Finance

Balancer V2-based DEX on Boba Network

SolidityVyperTypeScriptRustNext.jsReactethers.jsHardhatThe GraphPython

Overview

Koyo Finance was a decentralized exchange built on the Boba Network - an Ethereum L2 - with additional deployments on Aurora, Moonriver, and Polygon. At its core it was a fork of Balancer V2, extended with a Curve-style veToken governance system and a CoW Protocol solver for MEV-protected batch auctions.

The project was roughly thirteen repositories spanning five languages: Solidity and Vyper for contracts, TypeScript for the frontend and SDKs, Rust for the order settlement backend, and Python for chain tooling.

Smart contracts

The on-chain layer was split across three packages that evolved over the project’s life.

exchange-contracts started as a direct fork of the Balancer V2 Monorepo. It contained the vault - the single contract that holds all pool balances - along with pool implementations. Pools included a three-pool and four-pool (stable math) and an fc-pool (weighted), all compiled with Hardhat. Curve’s CurveTokenV3 was used for LP tokens.

koyo held the protocol’s own token contracts, written entirely in Vyper. This included the KYO token itself (FallingTea.vy), a VotingEscrow for time-locked veKYO positions, a Minter for emission schedules, and a gauge system (GaugeController, GaugeDistributor, LiquidityGaugeV1) that directed KYO rewards to pools based on veKYO votes. The pattern was modeled after Curve DAO Contracts.

contracts-monorepo was a later unification that pulled everything together: the Balancer vault and pool math, CoW Protocol settlement contracts for the Momiji solver, GMX-style perpetuals contracts, and shared utilities. This was the package that got deployed.

The Momiji solver

Momiji was Koyo’s integration of CoW Protocol’s batch auction mechanism. Instead of executing swaps immediately against an AMM, users could submit signed orders that a solver would batch together, finding coincidences of wants (CoWs) to fill trades peer-to-peer before routing the remainder through the pools. This reduced MEV extraction and improved execution prices.

The solver ran on cow-services, a Rust backend forked from CoW Protocol Services. It consisted of several crates: an orderbook for receiving and validating signed orders, a solver for computing optimal settlements, a driver for submitting transactions, and an autopilot for orchestrating solver competitions. The order book used PostgreSQL for persistence, and the solver connected to the on-chain vault to simulate settlements before execution.

momiji-explorer was a fork of CoW Protocol Explorer, adapted to display Momiji order status, settlements, and batch auction results.

Frontend

The exchange-interface was a Next.js app that served as the primary user-facing product. It had four main sections:

  • Swap - token swaps routed through Balancer’s Smart Order Router (SOR), with an option to toggle Momiji batch auctions on or off. The SOR computed optimal multi-hop paths across all pools.
  • Deposit/Withdraw - add or remove liquidity from any pool, with proportional and single-sided options.
  • Gauges - stake LP tokens in liquidity gauges to earn KYO emissions. Cards showed APR, TVL, and pending rewards per gauge.
  • KYO Lock - lock KYO for veKYO, manage lock duration, and vote on gauge weight allocation.

Wallet connection used Rainbow Kit, state management was Redux Toolkit, and all on-chain data came through Typechain-generated typed hooks from the SDK. Subgraph data (pool stats, historical swaps) was fetched via Apollo Client and GraphQL codegen.

exchange-info was a separate analytics dashboard (React/CRA) with pages for individual pools, tokens, gauges, protocol-level stats, treasury, and fee breakdowns. It used the same subgraph data through Apollo.

exchange-api was a lightweight Next.js API that provided pool data and swap quotes, with auto-generated Swagger documentation.

SDKs and shared libraries

The sdk monorepo (Turborepo) contained the packages that both frontends depended on:

  • core-sdk - chain constants, contract addresses, token lists, and utility functions
  • exchange-sdk - typed wrappers around the vault and pool contracts
  • momiji-sdk and momiji-hooks - React hooks for interacting with the CoW Protocol solver
  • sor - a fork of Balancer SOR adapted for Koyo’s pool types
  • react-query-typechain - a bridge between React Query and Typechain-generated contract bindings for cached, typed on-chain reads

koyo-ui was a shared component library built with Rollup and Storybook, following an atomic design pattern (atoms, molecules, organisms).

Indexing

Two subgraph packages indexed on-chain events via The Graph:

  • exchange-subgraph tracked the vault - pool creation, swaps, joins/exits, gauge registrations, and daily snapshots of TVL and volume per pool.
  • subgraphs was a monorepo with additional subgraphs for block timestamps, veKYO governance events, and Momiji batch auction settlements.

Tooling

ape-bobabeam was a Python plugin for the Ape smart contract framework that added Bobabeam (Boba + Moonbeam) network definitions, published to PyPI. This made it possible to use ape console --network bobabeam:mainnet for interactive contract debugging.

Forks and upstream projects

RepositoryForked from
contracts-monorepoBalancer V2 Monorepo + CoW Protocol + GMX
exchange-contractsBalancer V2 Monorepo
koyo (veKYO/gauges)Curve DAO Contracts pattern
cow-servicesCoW Protocol Services
momiji-explorerCoW Protocol Explorer
sdk (SOR package)Balancer SOR

Tech stack

LayerTechnologies
Smart contractsSolidity, Vyper, Hardhat, ethers.js
Solver backendRust, PostgreSQL
IndexingThe Graph, AssemblyScript
FrontendNext.js, React, Tailwind CSS, Rainbow Kit, Redux, Apollo Client
AnalyticsReact (CRA), Apollo Client, GraphQL
SDKsTypeScript, Turborepo, Rollup, Typechain
APINext.js, Swagger
ToolingPython (Ape plugin), GraphQL codegen
ChainsBoba Network, Aurora, Moonriver, Polygon