testing framework for simulating DeFi vault operations on the Saga chain using both Anvil (Ethereum fork) and TEVM (TypeScript EVM) implementations.
This project provides two different approaches to simulate vault rebalancing operations:
- Anvil Simulation (
anvilSimulation.ts
) - Uses Ethereum forking via Anvil to simulate transactions on a local fork of the Saga chain - TEVM Simulation (
tevmSimulation.ts
) - Uses TEVM (TypeScript EVM) for lightweight, fast simulation without forking
src/
βββ anvilSimulation.ts # Anvil-based simulation using Ethereum forking
βββ tevmSimulation.ts # TEVM-based simulation using TypeScript EVM
βββ index.ts # Main entry point with test functions
βββ test-runner.ts # Test orchestration and reporting
βββ utils/
β βββ fork-manager/ # Anvil fork management utilities
β β βββ anvil-manager.ts # Anvil process and fork management
β β βββ fork-manager.ts # Main fork management interface
β β βββ port-manager.ts # Port availability checking
β βββ contract-abils.ts # Contract ABIs for various protocols
β βββ tevmUtils.ts # TEVM client utilities
β βββ TransactionDebugger.ts # Enhanced transaction debugging
β βββ types/ # TypeScript type definitions
βββ viem-config/ # Viem chain configuration
- Node.js >= 18.0.0
- Yarn package manager
- Anvil CLI (for Anvil simulations)
# macOS (using Homebrew)
brew install foundry
# Or install directly
curl -L https://foundry.paradigm.xyz | bash
foundryup
yarn install
# Test TEVM simulation only
yarn test:tevm
# Test Anvil simulation only
yarn test:anvil
# Test both simulations
yarn test:both
# Run all simulations (default)
yarn test:simulations
# Use the test runner for detailed reporting
yarn test:runner
# Run specific test via runner
yarn test:runner:tevm
yarn test:runner:anvil
# Run Jest tests
yarn test
yarn test:watch
# Build TypeScript
yarn build
# Run in development mode
yarn dev
# Linting
yarn lint
yarn lint:fix
The project is configured for the Saga chain (Chain ID: 5464) by default.
// src/utils/consts.ts
export enum ChainId {
Saga = 5464,
}
- Anvil: Uses local fork of Saga RPC at
https://sagaevm-archive.jsonrpc.sagarpc.io
- TEVM: Uses TEVM's built-in chain simulation
// Vault Address
const vaultAddress = "0x6bc03924746062aef6a6f0c9d4ff1fff1eee1986";
// Orchestrator Address
const orchestratorAddress = "0xE49eC79eBA9A523e8350Eb3d427C92b4273ACf46";
// Steer Periphery Address
const steerPeripheryAddress = "0x0F71cFFAd6F80Ff440ba368231126104091747Ae";
// Liquidity Positions
const liquidityPositions = {
lowerTick: [-207728],
upperTick: [-188268],
relativeWeight: [100],
};
yarn test:tevm
What it does:
- Creates a TEVM memory client
- Simulates vault operations without forking
- Executes
tend
operation on the vault - Returns vault snapshot with fees and balances
Expected Output:
π Starting Saga chain simulation test...
[5464] π Starting vault supply check...
[5464] π¬ Processing vaults in batches...
β
TEVM Simulation completed successfully!
π Results: [...]
yarn test:anvil
What it does:
- Creates a local Anvil fork of the Saga chain
- Simulates vault operations on the forked chain
- Executes
tend
operation with full transaction simulation - Returns detailed transaction logs and results
Expected Output:
π Starting Anvil chain simulation test...
βΉοΈ Using manually started Anvil at http://localhost:3000
π οΈ Manual Anvil mode enabled.
π Please run this in another terminal:
anvil --fork-url https://sagaevm-archive.jsonrpc.sagarpc.io --port 3000 --fork-block-number <block_number>
Proceeding assuming Anvil is or will be available on port 3000...
β
Anvil Simulation completed successfully!
yarn test:both
Runs both TEVM and Anvil simulations sequentially for comparison.
The Anvil simulation requires manual setup due to the fork manager configuration:
# In a separate terminal, run:
anvil --fork-url https://sagaevm-archive.jsonrpc.sagarpc.io --port 3000 --fork-block-number <block_number>
Parameters:
--fork-url
: Saga chain RPC endpoint--port
: Local port (fixed to 3000)--fork-block-number
: Block number to fork from (get current from RPC)
# In your main terminal:
yarn test:anvil
Returns VaultSnapshot[]
with:
- Vault address and chain ID
- Token amounts (totalAmount0, totalAmount1)
- Fees earned (fees0Earned, fees1Earned)
- Pool state (sqrtPriceX96, totalSupply)
- Block information (blockNumber, blockTimestamp)
Returns transaction receipt with:
- Transaction hash and status
- Gas used and effective gas price
- Event logs (FeesEarned, Snapshot events)
- Detailed transaction execution data
# Check what's using port 3000
lsof -i :3000
# Kill the process
kill -9 <PID>
# Or use a different port (update anvil-manager.ts)
# Verify RPC endpoint is accessible
curl -X POST https://sagaevm-archive.jsonrpc.sagarpc.io \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# Clear node_modules and reinstall
rm -rf node_modules yarn.lock
yarn install
Enable detailed logging by setting environment variables:
DEBUG=* yarn test:anvil
DEBUG=* yarn test:tevm
- Update test parameters in
src/index.ts
- Ensure vault addresses are valid on Saga chain
- Verify contract ABIs in
src/utils/contract-abils.ts
- Add chain ID to
src/utils/consts.ts
- Update RPC endpoints in simulation files
- Verify chain-specific contract addresses
Edit the test data in the respective test functions:
testSagaSimulation()
for TEVMtestAnvilSimulation()
for Anvil
class SimulateVaultRebalanceAnvil {
constructor(chainId: number, protocol: string, orchestratorAddress: string, steerPeripheryAddress: string)
async initializeForkManager(): Promise<void>
async processVaultForSnapshot(vaultAddress: string, liquidityPositions: any): Promise<TendResult>
async deleteFork(): Promise<void>
}
async function simulateTendWithTevm(
chainId: number,
textInputsTevmSimulation: TextInputsTevmSimulation
): Promise<VaultSnapshot[]>