Skip to content

Commit

Permalink
feat: Add before support for add/remove/swap.
Browse files Browse the repository at this point in the history
  • Loading branch information
johngrantuk committed Jul 25, 2024
1 parent 5ade1ed commit 842943d
Show file tree
Hide file tree
Showing 9 changed files with 455 additions and 42 deletions.
15 changes: 8 additions & 7 deletions typescript/src/hooks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@ export interface HookBase {
enableHookAdjustedAmounts: boolean;

onBeforeAddLiquidity(
router: string,
pool: string,
kind: AddKind,
maxAmountsInScaled18: bigint[],
minBptAmountOut: bigint,
balancesScaled18: bigint[],
): boolean;
hookState: HookState | unknown,
): { success: boolean; hookAdjustedBalancesScaled18: bigint[] };
onAfterAddLiquidity(
kind: AddKind,
amountsInScaled18: bigint[],
Expand All @@ -43,13 +42,12 @@ export interface HookBase {
hookState: HookState | unknown,
): { success: boolean; hookAdjustedAmountsInRaw: bigint[] };
onBeforeRemoveLiquidity(
router: string,
pool: string,
kind: RemoveKind,
maxBptAmountIn: bigint,
minAmountsOutScaled18: bigint[],
balancesScaled18: bigint[],
): boolean;
hookState: HookState | unknown,
): { success: boolean; hookAdjustedBalancesScaled18: bigint[] };
onAfterRemoveLiquidity(
kind: RemoveKind,
bptAmountIn: bigint,
Expand All @@ -58,7 +56,10 @@ export interface HookBase {
balancesScaled18: bigint[],
hookState: HookState | unknown,
): { success: boolean; hookAdjustedAmountsOutRaw: bigint[] };
onBeforeSwap(params: SwapInput, poolAddress: string): boolean;
onBeforeSwap(params: SwapInput & { hookState: HookState | unknown }): {
success: boolean;
hookAdjustedBalancesScaled18: bigint[];
};
onAfterSwap(params: AfterSwapParams): {
success: boolean;
hookAdjustedAmountCalculatedRaw: bigint;
Expand Down
78 changes: 60 additions & 18 deletions typescript/src/vault/vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,23 @@ export class Vault {
poolState.tokenRates,
);

// hook: shouldCallBeforeSwap (TODO - need to handle balance changes, etc see code)
const updatedBalancesLiveScaled18 = [...poolState.balancesLiveScaled18];
if (hook.shouldCallBeforeSwap) {
throw new Error('Hook Unsupported: shouldCallBeforeSwap');
/*
Note - in SC balances and amounts are updated to reflect any rate change.
Daniel said we should not worry about this as any large rate changes will mean something has gone wrong.
We do take into account and balance changes due to hook using hookAdjustedBalancesScaled18.
*/
const { success, hookAdjustedBalancesScaled18 } = hook.onBeforeSwap(
{
...input,
hookState,
},
);
if (!success) throw new Error('BeforeSwapHookFailed');
hookAdjustedBalancesScaled18.forEach(
(a, i) => (updatedBalancesLiveScaled18[i] = a),
);
}

// hook: dynamicSwapFee
Expand All @@ -117,7 +131,7 @@ export class Vault {
const swapParams: SwapParams = {
swapKind: input.swapKind,
amountGivenScaled18,
balancesLiveScaled18: poolState.balancesLiveScaled18,
balancesLiveScaled18: updatedBalancesLiveScaled18,
indexIn: inputIndex,
indexOut: outputIndex,
};
Expand Down Expand Up @@ -184,7 +198,6 @@ export class Vault {
amountGivenScaled18,
];

const updatedBalancesLiveScaled18 = [...poolState.balancesLiveScaled18];
updatedBalancesLiveScaled18[inputIndex] += locals.balanceInIncrement;
updatedBalancesLiveScaled18[outputIndex] -= locals.balanceOutDecrement;

Expand Down Expand Up @@ -245,9 +258,26 @@ export class Vault {
poolState.tokenRates,
);

// hook: shouldCallBeforeAddLiquidity (TODO - need to handle balance changes, etc see code)
const updatedBalancesLiveScaled18 = [...poolState.balancesLiveScaled18];

if (hook.shouldCallBeforeAddLiquidity) {
throw new Error('Hook Unsupported: shouldCallBeforeAddLiquidity');
/*
Note - in SC balances and amounts are updated to reflect any rate change.
Daniel said we should not worry about this as any large rate changes will mean something has gone wrong.
We do take into account and balance changes due to hook using hookAdjustedBalancesScaled18.
*/
const { success, hookAdjustedBalancesScaled18 } =
hook.onBeforeAddLiquidity(
input.kind,
input.maxAmountsIn,
input.minBptAmountOut,
updatedBalancesLiveScaled18,
hookState,
);
if (!success) throw new Error('BeforeAddLiquidityHookFailed');
hookAdjustedBalancesScaled18.forEach(
(a, i) => (updatedBalancesLiveScaled18[i] = a),
);
}

let amountsInScaled18: bigint[];
Expand All @@ -257,7 +287,7 @@ export class Vault {
if (input.kind === AddKind.UNBALANCED) {
amountsInScaled18 = maxAmountsInScaled18;
const computed = computeAddLiquidityUnbalanced(
poolState.balancesLiveScaled18,
updatedBalancesLiveScaled18,
maxAmountsInScaled18,
poolState.totalSupply,
poolState.swapFee,
Expand All @@ -271,7 +301,7 @@ export class Vault {
amountsInScaled18 = maxAmountsInScaled18;
bptAmountOut = input.minBptAmountOut;
const computed = computeAddLiquiditySingleTokenExactOut(
poolState.balancesLiveScaled18,
updatedBalancesLiveScaled18,
tokenIndex,
bptAmountOut,
poolState.totalSupply,
Expand All @@ -288,7 +318,6 @@ export class Vault {
} else throw new Error('Unsupported AddLiquidity Kind');

const amountsInRaw: bigint[] = new Array(poolState.tokens.length);
const updatedBalancesLiveScaled18 = [...poolState.balancesLiveScaled18];
for (let i = 0; i < poolState.tokens.length; i++) {
// amountsInRaw are amounts actually entering the Pool, so we round up.
amountsInRaw[i] = this._toRawUndoRateRoundUp(
Expand All @@ -306,7 +335,7 @@ export class Vault {
);

updatedBalancesLiveScaled18[i] =
poolState.balancesLiveScaled18[i] +
updatedBalancesLiveScaled18[i] +
amountsInScaled18[i] -
aggregateSwapFeeAmountScaled18;
}
Expand Down Expand Up @@ -369,10 +398,24 @@ export class Vault {
poolState.tokenRates,
);

// hook: shouldCallBeforeRemoveLiquidity (TODO - need to handle balance changes, etc see code)
const updatedBalancesLiveScaled18 = [...poolState.balancesLiveScaled18];
if (hook.shouldCallBeforeRemoveLiquidity) {
throw new Error(
'Hook Unsupported: shouldCallBeforeRemoveLiquidity',
/*
Note - in SC balances and amounts are updated to reflect any rate change.
Daniel said we should not worry about this as any large rate changes will mean something has gone wrong.
We do take into account and balance changes due to hook using hookAdjustedBalancesScaled18.
*/
const { success, hookAdjustedBalancesScaled18 } =
hook.onBeforeRemoveLiquidity(
input.kind,
input.maxBptAmountIn,
input.minAmountsOut,
updatedBalancesLiveScaled18,
hookState,
);
if (!success) throw new Error('BeforeRemoveLiquidityHookFailed');
hookAdjustedBalancesScaled18.forEach(
(a, i) => (updatedBalancesLiveScaled18[i] = a),
);
}

Expand All @@ -387,7 +430,7 @@ export class Vault {
0n,
);
amountsOutScaled18 = computeProportionalAmountsOut(
poolState.balancesLiveScaled18,
updatedBalancesLiveScaled18,
poolState.totalSupply,
input.maxBptAmountIn,
);
Expand All @@ -396,7 +439,7 @@ export class Vault {
amountsOutScaled18 = minAmountsOutScaled18;
tokenOutIndex = this._getSingleInputIndex(input.minAmountsOut);
const computed = computeRemoveLiquiditySingleTokenExactIn(
poolState.balancesLiveScaled18,
updatedBalancesLiveScaled18,
tokenOutIndex,
input.maxBptAmountIn,
poolState.totalSupply,
Expand All @@ -414,7 +457,7 @@ export class Vault {
amountsOutScaled18 = minAmountsOutScaled18;
tokenOutIndex = this._getSingleInputIndex(input.minAmountsOut);
const computed = computeRemoveLiquiditySingleTokenExactOut(
poolState.balancesLiveScaled18,
updatedBalancesLiveScaled18,
tokenOutIndex,
amountsOutScaled18[tokenOutIndex],
poolState.totalSupply,
Expand All @@ -427,7 +470,6 @@ export class Vault {
} else throw new Error('Unsupported RemoveLiquidity Kind');

const amountsOutRaw = new Array(poolState.tokens.length);
const updatedBalancesLiveScaled18 = [...poolState.balancesLiveScaled18];

for (let i = 0; i < poolState.tokens.length; ++i) {
// amountsOut are amounts exiting the Pool, so we round down.
Expand All @@ -446,7 +488,7 @@ export class Vault {
);

updatedBalancesLiveScaled18[i] =
poolState.balancesLiveScaled18[i] -
updatedBalancesLiveScaled18[i] -
(amountsOutScaled18[i] + aggregateSwapFeeAmountScaled18);
}

Expand Down
6 changes: 3 additions & 3 deletions typescript/test/hooks/afterAddLiquidity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class CustomHook implements HookBase {
public enableHookAdjustedAmounts = true;

onBeforeAddLiquidity() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterAddLiquidity(
kind: AddKind,
Expand Down Expand Up @@ -134,13 +134,13 @@ class CustomHook implements HookBase {
};
}
onBeforeRemoveLiquidity() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterRemoveLiquidity() {
return { success: false, hookAdjustedAmountsOutRaw: [] };
}
onBeforeSwap() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterSwap() {
return { success: false, hookAdjustedAmountCalculatedRaw: 0n };
Expand Down
6 changes: 3 additions & 3 deletions typescript/test/hooks/afterRemoveLiquidity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ class CustomHook implements HookBase {
public enableHookAdjustedAmounts = true;

onBeforeAddLiquidity() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterAddLiquidity() {
return { success: false, hookAdjustedAmountsInRaw: [] };
}
onBeforeRemoveLiquidity() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterRemoveLiquidity(
kind: RemoveKind,
Expand Down Expand Up @@ -167,7 +167,7 @@ class CustomHook implements HookBase {
};
}
onBeforeSwap() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterSwap() {
return { success: false, hookAdjustedAmountCalculatedRaw: 0n };
Expand Down
6 changes: 3 additions & 3 deletions typescript/test/hooks/afterSwap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ class CustomHook implements HookBase {
public enableHookAdjustedAmounts = true;

onBeforeAddLiquidity() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterAddLiquidity() {
return { success: false, hookAdjustedAmountsInRaw: [] };
}
onBeforeRemoveLiquidity() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterRemoveLiquidity() {
return {
Expand All @@ -121,7 +121,7 @@ class CustomHook implements HookBase {
};
}
onBeforeSwap() {
return false;
return { success: false, hookAdjustedBalancesScaled18: [] };
}
onAfterSwap(params: AfterSwapParams) {
const {
Expand Down
Loading

0 comments on commit 842943d

Please sign in to comment.