Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions python/src/pools/buffer/buffer_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class BufferState:
# Immutable fields
pool_address: str
tokens: List[str]
scaling_factor: int
# Mutable fields
rate: int
max_deposit: Optional[int] = None
Expand All @@ -19,5 +20,6 @@ def map_buffer_state(pool_state: dict) -> BufferState:
return BufferState(
pool_address=pool_state["poolAddress"],
tokens=pool_state["tokens"],
scaling_factor=pool_state["scalingFactor"],
rate=pool_state["rate"],
)
31 changes: 28 additions & 3 deletions python/src/pools/buffer/erc4626_buffer_wrap_or_unwrap.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from src.common.types import SwapInput
from src.common.types import SwapInput, SwapKind
from src.common.utils import is_same_address
from src.pools.buffer.buffer_data import BufferState
from src.pools.buffer.buffer_math import calculate_buffer_amounts
Expand All @@ -20,9 +20,34 @@ def erc4626_buffer_wrap_or_unwrap(swap_input: SwapInput, pool_state: BufferState
else WrappingDirection.WRAP
)

return calculate_buffer_amounts(
scaling_factor = pool_state.scaling_factor

# Scale underlying amounts up before 18-decimal math
amount_for_calc = swap_input.amount_raw
if (
wrapping_direction == WrappingDirection.WRAP
and swap_input.swap_kind == SwapKind.GIVENIN
) or (
wrapping_direction == WrappingDirection.UNWRAP
and swap_input.swap_kind == SwapKind.GIVENOUT
):
amount_for_calc = swap_input.amount_raw * scaling_factor

result = calculate_buffer_amounts(
wrapping_direction,
swap_input.swap_kind,
swap_input.amount_raw,
amount_for_calc,
pool_state.rate,
)

# Scale results back down to underlying decimals
if (
wrapping_direction == WrappingDirection.WRAP
and swap_input.swap_kind == SwapKind.GIVENOUT
) or (
wrapping_direction == WrappingDirection.UNWRAP
and swap_input.swap_kind == SwapKind.GIVENIN
):
return result // scaling_factor

return result
1 change: 1 addition & 0 deletions rust/src/pools/buffer/buffer_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct BufferMutable {
pub struct BufferImmutable {
pub pool_address: String,
pub tokens: Vec<String>,
pub scaling_factor: U256,
}

/// Buffer pool state
Expand Down
31 changes: 27 additions & 4 deletions rust/src/pools/buffer/erc4626_buffer_wrap_or_unwrap.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! ERC4626 Buffer wrap or unwrap function

use crate::common::types::SwapInput;
use crate::common::types::{SwapInput, SwapKind};
use crate::pools::buffer::buffer_data::BufferState;
use crate::pools::buffer::buffer_math::calculate_buffer_amounts;
use crate::pools::buffer::enums::WrappingDirection;
Expand Down Expand Up @@ -35,14 +35,37 @@ pub fn erc4626_buffer_wrap_or_unwrap(
WrappingDirection::Wrap
};

calculate_buffer_amounts(
let scaling_factor = &pool_state.immutable.scaling_factor;

// Scale underlying amounts up before 18-decimal math
let amount_for_calc = if (wrapping_direction == WrappingDirection::Wrap
&& swap_input.swap_kind == SwapKind::GivenIn)
|| (wrapping_direction == WrappingDirection::Unwrap
&& swap_input.swap_kind == SwapKind::GivenOut)
{
swap_input.amount_raw * *scaling_factor
} else {
swap_input.amount_raw
};

let result = calculate_buffer_amounts(
wrapping_direction,
swap_input.swap_kind.clone(),
&swap_input.amount_raw,
&amount_for_calc,
&pool_state.mutable.rate,
pool_state.mutable.max_deposit.as_ref(),
pool_state.mutable.max_mint.as_ref(),
)
)?;

// Scale results back down to underlying decimals
if (wrapping_direction == WrappingDirection::Wrap && swap_input.swap_kind == SwapKind::GivenOut)
|| (wrapping_direction == WrappingDirection::Unwrap
&& swap_input.swap_kind == SwapKind::GivenIn)
{
Ok(result / *scaling_factor)
} else {
Ok(result)
}
}

/// Check if two addresses are the same (case-insensitive)
Expand Down
11 changes: 11 additions & 0 deletions rust/tests/utils/read_test_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ pub struct BufferImmutable {
#[serde(rename = "poolAddress")]
pub pool_address: String,
pub tokens: Vec<String>,
#[serde(rename = "scalingFactor")]
pub scaling_factor: U256,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -483,6 +485,8 @@ struct RawPool {
pub max_deposit: Option<String>,
#[serde(rename = "maxMint")]
pub max_mint: Option<String>,
#[serde(rename = "scalingFactor")]
pub scaling_factor_buffer: Option<String>,
// ReClamm specific fields
#[serde(rename = "lastVirtualBalances")]
pub last_virtual_balances: Option<Vec<String>>,
Expand Down Expand Up @@ -1381,6 +1385,12 @@ fn map_pool(raw_pool: RawPool) -> Result<SupportedPool, Box<dyn std::error::Erro
.map(|m| m.parse::<U256>())
.transpose()?;

let scaling_factor = raw_pool
.scaling_factor_buffer
.as_ref()
.ok_or("Buffer pool missing scalingFactor")?
.parse::<U256>()?;

// Buffer pools have minimal required fields, use defaults for missing ones
let buffer_state = BufferState {
base: BasePoolState {
Expand All @@ -1407,6 +1417,7 @@ fn map_pool(raw_pool: RawPool) -> Result<SupportedPool, Box<dyn std::error::Erro
immutable: BufferImmutable {
pool_address: raw_pool.pool_address.clone(),
tokens: raw_pool.tokens.clone(),
scaling_factor,
},
};
Ok(SupportedPool::Buffer(BufferPool {
Expand Down
1 change: 1 addition & 0 deletions rust/tests/utils/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ pub fn convert_to_pool_state(pool: &SupportedPool) -> PoolStateOrBuffer {
immutable: BufferImmutable {
pool_address: buffer_pool.state.immutable.pool_address.clone(),
tokens: buffer_pool.state.immutable.tokens.clone(),
scaling_factor: buffer_pool.state.immutable.scaling_factor,
},
};
PoolStateOrBuffer::Buffer(Box::new(buffer_state))
Expand Down
24 changes: 23 additions & 1 deletion testData/src/buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import {
type Address,
type Chain,
erc4626Abi,
erc20Abi,
} from 'viem';
import { CHAINS, VAULT_V3 } from '@balancer/sdk';
import { TransformBigintToString } from './types';

export type BufferImmutable = {
tokens: Address[];
scalingFactor: bigint;
};

type BufferMutable = {
Expand Down Expand Up @@ -43,20 +45,40 @@ export class BufferPool {
blockNumber,
});

const [mainDecimals, underlyingDecimals] = await Promise.all([
this.client.readContract({
address,
abi: erc20Abi,
functionName: 'decimals',
blockNumber,
}),
this.client.readContract({
address: asset,
abi: erc20Abi,
functionName: 'decimals',
blockNumber,
}),
]);

const scalingFactor = 10n ** BigInt(mainDecimals - underlyingDecimals);

return {
tokens: [address, asset],
scalingFactor: scalingFactor.toString(),
};
}

async fetchMutableData(
address: Address,
blockNumber: bigint,
scalingFactor: bigint,
): Promise<TransformBigintToString<BufferMutable>> {
const convertToAssetsInput = 1000000000000000000n * scalingFactor;
const rate = await this.client.readContract({
address,
abi: erc4626Abi,
functionName: 'convertToAssets',
args: [1000000000000000000n],
args: [convertToAssetsInput],
blockNumber,
});
return {
Expand Down
15 changes: 11 additions & 4 deletions testData/src/getPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,17 @@ export async function getPool(
poolAddress,
blockNumber,
);
const mutable = await poolData[poolType].fetchMutableData(
poolAddress,
blockNumber,
);
const mutable =
poolType === 'Buffer'
? await (poolData[poolType] as BufferPool).fetchMutableData(
poolAddress,
blockNumber,
BigInt(immutable.scalingFactor),
)
: await poolData[poolType].fetchMutableData(
poolAddress,
blockNumber,
);
console.log('Done');

// Fetch hook data for all pools except Buffer pools (which don't support hooks)
Expand Down
3 changes: 2 additions & 1 deletion testData/testData/1-21671845-Buffer-csUSDC.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"0x7204B7Dbf9412567835633B6F00C3Edc3a8D6330",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
],
"rate": "1005205"
"scalingFactor": "1000000000000",
"rate": "1005205772403674748"
}
}
1 change: 1 addition & 0 deletions testData/testData/1-21671845-Buffer-waEthLidoWETH.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"0x0FE906e030a44eF24CA8c7dC7B7c53A6C4F00ce9",
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
],
"scalingFactor": "1",
"rate": "1010169874970004409"
}
}
1 change: 1 addition & 0 deletions testData/testData/1-21671845-Buffer-waEthUSDC.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"0xD4fa2D31b7968E448877f69A96DE69f5de8cD23E",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
],
"scalingFactor": "1",
"rate": "1115987637915440452"
}
}
1 change: 1 addition & 0 deletions testData/testData/buffer-manual.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"0x8a88124522dbbf1e56352ba3de1d9f78c143751e",
"0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8"
],
"scalingFactor": "1",
"rate": "1026429645525566689"
}
}
1 change: 1 addition & 0 deletions typescript/src/buffer/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type BufferMutable = {
export type BufferImmutable = {
poolAddress: string;
tokens: string[];
scalingFactor: bigint;
};

/**
Expand Down
31 changes: 28 additions & 3 deletions typescript/src/buffer/erc4626BufferWrapOrUnwrap.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BufferState } from '../buffer/data';
import { isSameAddress } from '../vault/utils';
import { SwapInput } from '../vault/types';
import { SwapInput, SwapKind } from '../vault/types';
import { calculateBufferAmounts } from './bufferMath';
import { WrappingDirection } from './types';

Expand All @@ -23,12 +23,37 @@ export function erc4626BufferWrapOrUnwrap(
? WrappingDirection.UNWRAP
: WrappingDirection.WRAP;

return calculateBufferAmounts(
const { scalingFactor } = poolState;

// Scale underlying amounts up before 18-decimal math
let amountForCalc = input.amountRaw;
if (
(wrappingDirection === WrappingDirection.WRAP &&
input.swapKind === SwapKind.GivenIn) ||
(wrappingDirection === WrappingDirection.UNWRAP &&
input.swapKind === SwapKind.GivenOut)
) {
amountForCalc = input.amountRaw * scalingFactor;
}

const result = calculateBufferAmounts(
wrappingDirection,
input.swapKind,
input.amountRaw,
amountForCalc,
poolState.rate,
poolState.maxDeposit,
poolState.maxMint,
);

// Scale results back down to underlying decimals
if (
(wrappingDirection === WrappingDirection.WRAP &&
input.swapKind === SwapKind.GivenOut) ||
(wrappingDirection === WrappingDirection.UNWRAP &&
input.swapKind === SwapKind.GivenIn)
) {
return result / scalingFactor;
}

return result;
}
4 changes: 4 additions & 0 deletions typescript/test/bufferPool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('buffer pool', () => {
'0xd4fa2d31b7968e448877f69a96de69f5de8cd23e',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
],
scalingFactor: 1n,
maxDeposit: 1900471418535512n,
maxMint: 1692675790387594n,
};
Expand All @@ -40,6 +41,7 @@ describe('buffer pool', () => {
'0xd4fa2d31b7968e448877f69a96de69f5de8cd23e',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
],
scalingFactor: 1n,
maxDeposit: 1900471418535512n,
maxMint: 1692675790387594n,
};
Expand Down Expand Up @@ -68,6 +70,7 @@ describe('buffer pool', () => {
'0xd4fa2d31b7968e448877f69a96de69f5de8cd23e',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
],
scalingFactor: 1n,
maxDeposit: 1900471418535512n,
maxMint: 1692675790387594n,
};
Expand All @@ -94,6 +97,7 @@ describe('buffer pool', () => {
'0xd4fa2d31b7968e448877f69a96de69f5de8cd23e',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
],
scalingFactor: 1n,
maxDeposit: 1900471418535512n,
maxMint: 1692675790387594n,
};
Expand Down
1 change: 1 addition & 0 deletions typescript/test/utils/readTestData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ function mapPool(
return {
...pool,
rate: BigInt(pool.rate),
scalingFactor: BigInt(pool.scalingFactor),
};
}
if (pool.poolType === 'GYROE') {
Expand Down
Loading