Skip to content

Commit

Permalink
fix: withdraw and deposit actions
Browse files Browse the repository at this point in the history
  • Loading branch information
marthendalnunes committed Dec 13, 2024
1 parent 1c3c14a commit 7587f98
Show file tree
Hide file tree
Showing 14 changed files with 2,520 additions and 104 deletions.
92 changes: 92 additions & 0 deletions apps/api-delegations/src/processing/limit-order/get-actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { stablecoinTokenList } from 'universal-data';
import type { Address, Hex } from 'viem';
import {
getDepositAaveV3HookData,
getWithdrawAaveV3HookData,
} from './protocols/aave-v3.js';
import {
getDepositPoolTogetherV5HookData,
getWithdrawPoolTogetherV5HookData,
} from './protocols/pool-together-v5.js';
import { getDepositUnderlyingAssetHookData } from './protocols/underlying-asset.js';

type HookActions = {
target: Address;
value: bigint;
callData: Hex;
}[];

type GetHookActionsParams = {
tokenIn: Address;
tokenOut: Address;
amountIn: bigint;
amountOut: bigint;
delegator: Address;
};

type GetHookActionsReturnType = {
withdrawActions: HookActions;
depositActions: HookActions;
};

export function getHookActions({
tokenIn,
tokenOut,
amountIn,
amountOut,
delegator,
}: GetHookActionsParams): GetHookActionsReturnType {
let withdrawActions: HookActions = [];
let depositActions: HookActions = [];

const tokenInData = stablecoinTokenList.tokens.find(
(token) => token.address.toLowerCase() === tokenIn.toLowerCase(),
);
const tokenOutData = stablecoinTokenList.tokens.find(
(token) => token.address.toLowerCase() === tokenOut.toLowerCase(),
);

if (!tokenInData || !tokenOutData) {
throw new Error('Token not found');
}

// Withdraw actions
if (tokenOutData.extensions?.protocol === 'aave-v3') {
withdrawActions = getWithdrawAaveV3HookData({
amountIn,
tokenIn,
});
} else if (tokenOutData.extensions?.protocol === 'pool-together-v5') {
withdrawActions = getWithdrawPoolTogetherV5HookData({
amountOut,
tokenOut,
});
}

// Deposit actions
if (tokenInData.extensions?.protocol === 'aave-v3') {
depositActions = getDepositAaveV3HookData({
amountIn,
delegator,
tokenOut,
});
} else if (tokenInData.extensions?.protocol === 'pool-together-v5') {
depositActions = getDepositPoolTogetherV5HookData({
amountIn,
delegator,
tokenIn,
tokenOut,
});
} else if (!tokenInData.extensions?.protocol) {
depositActions = getDepositUnderlyingAssetHookData({
amountIn,
delegator,
tokenIn,
});
}

return {
withdrawActions,
depositActions,
};
}
76 changes: 27 additions & 49 deletions apps/api-delegations/src/processing/limit-order/index.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,60 @@
import type { Delegation, DelegationExecution } from 'universal-types';
import {
decodeERC20BalanceGteWrapEnforcerTerms,
decodeEnforcerERC20TransferAmount,
encodeDelegation,
encodeExternalCallEnforcerArgs,
encodeSingleExecution,
getERC20BalanceGteWrapEnforcerFromDelegation,
getErc20TransferAmountEnforcerFromDelegation,
getExternalHookEnforcerFromDelegation,
} from './utils.js';
import { getResolverWalletClient } from '../../resolver/resolver-wallet-client.js';
import type { ValidChain } from 'universal-data';
import {
SINGLE_EXECUTION_MODE,
aaveV3PoolAbi,
delegationManagerAbi,
multicallAbi,
universalDeployments,
} from 'universal-data';
import { encodeFunctionData, type Address, type Hex, erc20Abi } from 'viem';
import { multicallAbi } from 'universal-data';

const AAVE_V3_POOL_BASE = '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5';

function getDepositAaveV3HookData({
amount,
delegator,
token,
}: { amount: bigint; delegator: Address; token: Address }): Hex {
return encodeFunctionData({
abi: multicallAbi,
functionName: 'multicall',
args: [
[
// Approves the token to the Aave Pool
{
target: token,
value: 0n,
callData: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: [AAVE_V3_POOL_BASE, amount],
}),
},
// Deposits the token to the Aave Pool on behalf of the delegator
{
target: AAVE_V3_POOL_BASE,
value: 0n,
callData: encodeFunctionData({
abi: aaveV3PoolAbi,
functionName: 'supply',
args: [token, amount, delegator, 0],
}),
},
],
],
});
}
import { encodeFunctionData, erc20Abi } from 'viem';
import { getHookActions } from './get-actions.js';

export async function processLimitOrderDelegation({
chainId,
delegation,
}: { chainId: ValidChain['id']; delegation: Delegation }) {
const { erc20TransferAmountEnforcer } =
getErc20TransferAmountEnforcerFromDelegation(delegation);
const { token, amount } = decodeEnforcerERC20TransferAmount(
erc20TransferAmountEnforcer.terms,
);
const { token: tokenOut, amount: amountOut } =
decodeEnforcerERC20TransferAmount(erc20TransferAmountEnforcer.terms);

const { erc20BalanceGteWrapEnforcer } =
getERC20BalanceGteWrapEnforcerFromDelegation(delegation);

const { token: tokenIn, amount: amountIn } =
decodeERC20BalanceGteWrapEnforcerTerms(erc20BalanceGteWrapEnforcer.terms);

const { externalHookEnforcer, index: externalHookEnforcerIndex } =
getExternalHookEnforcerFromDelegation(delegation);

const { withdrawActions, depositActions } = getHookActions({
amountIn,
amountOut,
delegator: delegation.delegator,
tokenIn,
tokenOut,
});

delegation.caveats[externalHookEnforcerIndex] = {
...externalHookEnforcer,
// Update the args of the external hook enforcer to include the data for the Aave V3 deposit
args: encodeExternalCallEnforcerArgs({
target: universalDeployments.Multicall,
callData: getDepositAaveV3HookData({
amount,
token,
delegator: delegation.delegator,
callData: encodeFunctionData({
abi: multicallAbi,
functionName: 'multicall',
args: [[...withdrawActions, ...depositActions]],
}),
}),
};
Expand All @@ -87,11 +65,11 @@ export async function processLimitOrderDelegation({
// Set the delegation execution to transfer the delegator tokens to the multicall contract
const execution: DelegationExecution = {
value: 0n,
target: token,
target: tokenOut,
calldata: encodeFunctionData({
abi: erc20Abi,
functionName: 'transfer',
args: [universalDeployments.Multicall, amount],
args: [universalDeployments.Multicall, amountOut],
}),
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { encodeFunctionData, erc20Abi, type Address, type Hex } from 'viem';
import { aaveV3PoolAbi, universalDeployments } from 'universal-data';

const AAVE_V3_POOL_BASE = '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5';

type GetDepositAaveV3HookDataReturnType = {
target: Address;
value: bigint;
callData: Hex;
}[];

export function getDepositAaveV3HookData({
amountIn,
delegator,
tokenOut,
}: {
amountIn: bigint;
delegator: Address;
tokenOut: Address;
}): GetDepositAaveV3HookDataReturnType {
return [
// Approves the token to the Aave Pool
{
target: tokenOut,
value: 0n,
callData: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: [AAVE_V3_POOL_BASE, amountIn],
}),
},
// Deposits the token to the Aave Pool on behalf of the delegator
{
target: AAVE_V3_POOL_BASE,
value: 0n,
callData: encodeFunctionData({
abi: aaveV3PoolAbi,
functionName: 'supply',
args: [tokenOut, amountIn, delegator, 0],
}),
},
];
}

type GetWithdrawAaveV3HookDataReturnType = GetDepositAaveV3HookDataReturnType;
export function getWithdrawAaveV3HookData({
amountIn,
tokenIn,
}: {
amountIn: bigint;
tokenIn: Address;
}): GetWithdrawAaveV3HookDataReturnType {
return [
// Withdraws the token from the Aave Pool on behalf of the delegator
{
target: AAVE_V3_POOL_BASE,
value: 0n,
callData: encodeFunctionData({
abi: aaveV3PoolAbi,
functionName: 'withdraw',
args: [tokenIn, amountIn, universalDeployments.Multicall],
}),
},
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { encodeFunctionData, erc20Abi, type Address, type Hex } from 'viem';
import { multicallAbi } from 'universal-data';
import { compoundV3Abi } from 'universal-data';

export function getDepositCompoundV3HookData({
amountIn,
delegator,
tokenOut,
tokenIn,
}: {
amountIn: bigint;
delegator: Address;
tokenIn: Address;
tokenOut: Address;
}): Hex {
return encodeFunctionData({
abi: multicallAbi,
functionName: 'multicall',
args: [
[
// Approves the token to the Compound Pool
{
target: tokenOut,
value: 0n,
callData: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: [tokenIn, amountIn],
}),
},
// Deposits the token to the Compound Pool on behalf of the delegator
{
target: tokenIn,
value: 0n,
callData: encodeFunctionData({
abi: compoundV3Abi,
functionName: 'supplyTo',
args: [delegator, tokenOut, amountIn],
}),
},
],
],
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { encodeFunctionData, erc20Abi, type Address, type Hex } from 'viem';
import { poolTogetherV5Abi, universalDeployments } from 'universal-data';

type GetDepositPoolTogetherV5HookDataReturnType = {
target: Address;
value: bigint;
callData: Hex;
}[];

export function getDepositPoolTogetherV5HookData({
amountIn,
delegator,
tokenOut,
tokenIn,
}: {
amountIn: bigint;
delegator: Address;
tokenIn: Address;
tokenOut: Address;
}): GetDepositPoolTogetherV5HookDataReturnType {
return [
// Approves the token to the Prize vault
{
target: tokenOut,
value: 0n,
callData: encodeFunctionData({
abi: erc20Abi,
functionName: 'approve',
args: [tokenIn, amountIn],
}),
},
// Deposits the token to the Prize vault on behalf of the delegator
{
target: tokenIn,
value: 0n,
callData: encodeFunctionData({
abi: poolTogetherV5Abi,
functionName: 'deposit',
args: [amountIn, delegator],
}),
},
];
}

type GetWithdrawPoolTogetherV5HookDataReturnType =
GetDepositPoolTogetherV5HookDataReturnType;

export function getWithdrawPoolTogetherV5HookData({
amountOut,

tokenOut,
}: {
amountOut: bigint;

tokenOut: Address;
}): GetWithdrawPoolTogetherV5HookDataReturnType {
return [
// Deposits the token to the Prize vault on behalf of the delegator
{
target: tokenOut,
value: 0n,
callData: encodeFunctionData({
abi: poolTogetherV5Abi,
functionName: 'redeem',
args: [
amountOut,
universalDeployments.Multicall,
universalDeployments.Multicall,
],
}),
},
];
}
Loading

0 comments on commit 7587f98

Please sign in to comment.