Skip to content

Commit

Permalink
Merge pull request #348 from balancer/buffer-support
Browse files Browse the repository at this point in the history
feat: Add buffer support to swaps.
  • Loading branch information
johngrantuk authored Aug 7, 2024
2 parents 492fdd7 + e2a8be9 commit 92abf28
Show file tree
Hide file tree
Showing 12 changed files with 659 additions and 174 deletions.
5 changes: 5 additions & 0 deletions .changeset/quick-teachers-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@balancer/sdk": minor
---

Adds buffer/boosted pool support to swaps.
25 changes: 25 additions & 0 deletions src/entities/swap/paths/pathHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export function validatePaths(paths: Path[]) {
if (paths.length === 0)
throw new Error('Invalid swap: must contain at least 1 path.');

validateBufferVersion(paths);
validateBufferLength(paths);

const protocolVersion = paths[0].protocolVersion;
if (!paths.every((p) => p.protocolVersion === protocolVersion))
throw new Error(
Expand All @@ -56,3 +59,25 @@ export function validatePaths(paths: Path[]) {
);
}
}

function validateBufferVersion(paths: Path[]) {
if (
!paths.every((p) => {
return p.isBuffer ? p.protocolVersion === 3 : true;
})
) {
throw new Error('Unsupported swap: buffers not supported in V2.');
}
}

function validateBufferLength(paths: Path[]) {
if (
!paths.every((p) => {
return p.isBuffer ? p.isBuffer.length === p.pools.length : true;
})
) {
throw new Error(
'Unsupported swap: buffers and pools must have same length.',
);
}
}
5 changes: 5 additions & 0 deletions src/entities/swap/paths/pathWithAmount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TokenApi } from './types';

export class PathWithAmount {
public readonly pools: Address[];
public readonly isBuffer: boolean[];
public readonly tokens: TokenApi[];
public readonly outputAmount: TokenAmount;
public readonly inputAmount: TokenAmount;
Expand All @@ -15,6 +16,7 @@ export class PathWithAmount {
pools: Address[],
inputAmountRaw: bigint,
outputAmountRaw: bigint,
isBuffer: boolean[] | undefined,
) {
if (pools.length === 0 || tokens.length < 2) {
throw new Error(
Expand All @@ -38,6 +40,9 @@ export class PathWithAmount {
tokens[tokens.length - 1].decimals,
);
this.pools = pools;
this.isBuffer = isBuffer
? isBuffer
: new Array(this.pools.length).fill(false);
this.tokens = tokens;
this.inputAmount = TokenAmount.fromRawAmount(tokenIn, inputAmountRaw);
this.outputAmount = TokenAmount.fromRawAmount(
Expand Down
1 change: 1 addition & 0 deletions src/entities/swap/paths/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type TokenApi = Omit<MinimalToken, 'index'>;

export type Path = {
pools: Address[] | Hex[];
isBuffer?: boolean[];
tokens: TokenApi[];
outputAmountRaw: bigint;
inputAmountRaw: bigint;
Expand Down
1 change: 1 addition & 0 deletions src/entities/swap/swaps/v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class SwapV2 implements SwapBase {
p.pools.map((pool) => pool.toLowerCase() as Address),
p.inputAmountRaw,
p.outputAmountRaw,
undefined,
),
);

Expand Down
5 changes: 3 additions & 2 deletions src/entities/swap/swaps/v3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class SwapV3 implements SwapBase {
p.pools,
p.inputAmountRaw,
p.outputAmountRaw,
p.isBuffer,
),
);

Expand Down Expand Up @@ -563,7 +564,7 @@ export class SwapV3 implements SwapBase {
return {
pool: pool,
tokenOut: p.tokens[i + 1].address,
isBuffer: false,
isBuffer: p.isBuffer[i],
};
}),
};
Expand All @@ -579,7 +580,7 @@ export class SwapV3 implements SwapBase {
return {
pool: pool,
tokenOut: p.tokens[i + 1].address,
isBuffer: false,
isBuffer: p.isBuffer[i],
};
}),
};
Expand Down
67 changes: 67 additions & 0 deletions test/entities/swaps/swap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,73 @@ describe('Swap', () => {
'Unsupported swap: all paths must start/end with same token.',
);
});
describe('buffers', () => {
const pathWithBuffers: Path = {
protocolVersion: 3,
tokens: [
{
address:
'0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8',
decimals: 18,
}, // DAI
{
address:
'0x8a88124522dbbf1e56352ba3de1d9f78c143751e',
decimals: 18,
}, // stataToken
{
address:
'0xde46e43f46ff74a23a65ebb0580cbe3dfe684a17',
decimals: 6,
}, // stataToken
{
address:
'0xFF34B3d4Aee8ddCd6F9AFFFB6Fe49bD371b8a357',
decimals: 6,
}, // USDC
],
pools: [
'0x8a88124522dbbf1e56352ba3de1d9f78c143751e', // buffer
'0x90a46864cb1f042060554592038367e9c97e17f3',
'0xde46e43f46ff74a23a65ebb0580cbe3dfe684a17', // buffer
],
isBuffer: [true, false, true],
inputAmountRaw: 1000000000000000000n,
outputAmountRaw: 1000000n,
};
test('should throw if buffers used for V2', () => {
expect(() => {
new Swap({
chainId,
paths: [
{
...pathWithBuffers,
protocolVersion: 2,
},
],
swapKind: SwapKind.GivenIn,
});
}).toThrowError(
'Unsupported swap: buffers not supported in V2.',
);
});
test('should throw if buffers not same length as pools', () => {
expect(() => {
new Swap({
chainId,
paths: [
{
...pathWithBuffers,
isBuffer: [true, false],
},
],
swapKind: SwapKind.GivenIn,
});
}).toThrowError(
'Unsupported swap: buffers and pools must have same length.',
);
});
});
});
});

Expand Down
36 changes: 18 additions & 18 deletions test/entities/swaps/v2/swapV2.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,28 +137,28 @@ describe('SwapV2', () => {
...swapParams,
swapKind: SwapKind.GivenIn,
});
await assertSwapExactIn(
vault,
await assertSwapExactIn({
contractToCall: vault,
client,
rpcUrl,
chainId,
swap,
wethIsEth,
);
});
});
test('GivenOut', async () => {
const swap = new Swap({
...swapParams,
swapKind: SwapKind.GivenOut,
});
await assertSwapExactOut(
vault,
await assertSwapExactOut({
contractToCall: vault,
client,
rpcUrl,
chainId,
swap,
wethIsEth,
);
});
});
});
describe('wethIsEth: true', () => {
Expand All @@ -170,29 +170,29 @@ describe('SwapV2', () => {
paths: [pathBalWeth],
swapKind: SwapKind.GivenIn,
});
await assertSwapExactIn(
vault,
await assertSwapExactIn({
contractToCall: vault,
client,
rpcUrl,
chainId,
swap,
wethIsEth,
);
});
});
test('GivenOut', async () => {
const swap = new Swap({
chainId,
paths: [pathBalWeth],
swapKind: SwapKind.GivenOut,
});
await assertSwapExactOut(
vault,
await assertSwapExactOut({
contractToCall: vault,
client,
rpcUrl,
chainId,
swap,
wethIsEth,
);
});
});
});
describe('eth in', () => {
Expand All @@ -206,14 +206,14 @@ describe('SwapV2', () => {
paths: [pathWethBal],
swapKind: SwapKind.GivenIn,
});
await assertSwapExactIn(
vault,
await assertSwapExactIn({
contractToCall: vault,
client,
rpcUrl,
chainId,
swap,
wethIsEth,
);
});
});
test('GivenOut', async () => {
const pathWethBal = {
Expand All @@ -225,14 +225,14 @@ describe('SwapV2', () => {
paths: [pathWethBal],
swapKind: SwapKind.GivenOut,
});
await assertSwapExactOut(
vault,
await assertSwapExactOut({
contractToCall: vault,
client,
rpcUrl,
chainId,
swap,
wethIsEth,
);
});
});
});
});
Expand Down
Loading

0 comments on commit 92abf28

Please sign in to comment.