Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/routes-support #28

Merged
merged 3 commits into from
Sep 8, 2023
Merged
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
3 changes: 1 addition & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
VITE_SUBSQUID_URL="https://squid.subsquid.io/origin-squid/v/v4/graphql"
# VITE_CUSTOM_RPC="https://rpc.tenderly.co/fork/751e79c6-6420-4ea9-ac13-1f6b20f318bc"
# VITE_CUSTOM_RPC="http://127.0.0.1:8545"
VITE_CUSTOM_RPC=
VITE_WALLET_CONNECT_PROJECT_ID=
VITE_ALCHEMY_ID=
8 changes: 7 additions & 1 deletion libs/oeth/swap/src/actions/defaultApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ const estimateRoute: EstimateRoute = async (
return { ...route, estimatedAmount, gas, rate: 0 };
};

const swap: Swap = async (_tokenIn, _tokenOut, _amountIn, _route) => {
const swap: Swap = async (
_tokenIn,
_tokenOut,
_amountIn,
_route,
_slippage,
) => {
console.log('Route swap operation not implemented');
};

Expand Down
180 changes: 152 additions & 28 deletions libs/oeth/swap/src/actions/mintVault.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import { queryClient } from '@origin/oeth/shared';
import { contracts } from '@origin/shared/contracts';
import { isNilOrEmpty } from '@origin/shared/utils';
import { getAccount, getPublicClient, readContract } from '@wagmi/core';
import { formatUnits } from 'viem';

import type { EstimateGas, EstimateRoute } from '../types';
import {
erc20ABI,
getAccount,
getPublicClient,
prepareWriteContract,
readContract,
readContracts,
waitForTransaction,
writeContract,
} from '@wagmi/core';
import { formatUnits, parseUnits } from 'viem';

import type { EstimateGas, EstimateRoute, Swap } from '../types';
import type { EstimateAmount } from '../types';

const estimateAmount: EstimateAmount = async (tokenIn, _tokenOut, amountIn) => {
const estimateAmount: EstimateAmount = async (tokenIn, tokenOut, amountIn) => {
if (amountIn === 0n) {
return 0n;
}
Expand All @@ -18,43 +28,85 @@ const estimateAmount: EstimateAmount = async (tokenIn, _tokenOut, amountIn) => {
args: [tokenIn.address],
});

return amountIn * data;
return parseUnits(
(
+formatUnits(amountIn, tokenIn.decimals) *
+formatUnits(data, tokenIn.decimals)
).toString(),
tokenOut.decimals,
);
};

const estimateGas: EstimateGas = async (
_tokenIn,
_tokenOut,
tokenIn,
tokenOut,
amountIn,
slippage,
amountOut,
) => {
let gasEstimate = 0n;

const publicClient = getPublicClient();

if (amountIn === 0n) {
return gasEstimate;
}

const publicClient = getPublicClient();
const { address } = getAccount();

if (!isNilOrEmpty(address)) {
try {
gasEstimate = await publicClient.estimateContractGas({
address: contracts.mainnet.WOETH.address,
abi: contracts.mainnet.WOETH.abi,
functionName: 'deposit',
args: [amountIn, address],
account: address,
});

return gasEstimate;
} catch {}
}
const minAmountOut = parseUnits(
(
+formatUnits(amountOut, tokenOut.decimals) -
+formatUnits(amountOut, tokenOut.decimals) * slippage
).toString(),
tokenOut.decimals,
);

try {
gasEstimate = 0n;
gasEstimate = await publicClient.estimateContractGas({
address: contracts.mainnet.OETHVaultCore.address,
abi: contracts.mainnet.OETHVaultCore.abi,
functionName: 'mint',
args: [tokenIn.address, amountIn, minAmountOut],
account: address,
});

return gasEstimate;
} catch {}

try {
const [rebaseThreshold, autoAllocateThreshold] =
await queryClient.fetchQuery({
queryKey: ['vault-info', tokenOut.address],
queryFn: () =>
readContracts({
contracts: [
{
address: contracts.mainnet.OETHVaultCore.address,
abi: contracts.mainnet.OETHVaultCore.abi,
functionName: 'rebaseThreshold',
},
{
address: contracts.mainnet.OETHVaultCore.address,
abi: contracts.mainnet.OETHVaultCore.abi,
functionName: 'autoAllocateThreshold',
},
],
}),
staleTime: Infinity,
});

// TODO check validity
gasEstimate = 220000n;
if (amountIn > autoAllocateThreshold?.result) {
gasEstimate = 2900000n;
} else if (amountIn > rebaseThreshold?.result) {
gasEstimate = 510000n;
}
} catch (e) {
// TODO trigger notification
console.error(`mint vault gas estimate error!\n${e.message}`);
}

return gasEstimate;
};

Expand All @@ -69,10 +121,14 @@ const estimateRoute: EstimateRoute = async (
return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 };
}

const [estimatedAmount, gas] = await Promise.all([
estimateAmount(tokenIn, tokenOut, amountIn),
estimateGas(tokenIn, tokenOut, amountIn, slippage),
]);
const estimatedAmount = await estimateAmount(tokenIn, tokenOut, amountIn);
const gas = await estimateGas(
tokenIn,
tokenOut,
amountIn,
slippage,
estimatedAmount,
);

return {
...route,
Expand All @@ -84,8 +140,76 @@ const estimateRoute: EstimateRoute = async (
};
};

const swap: Swap = async (
tokenIn,
tokenOut,
amountIn,
_route,
slippage,
amountOut,
) => {
const { address } = getAccount();

if (amountIn === 0n || isNilOrEmpty(address)) {
return;
}

const allowance = await readContract({
address: tokenIn.address,
abi: erc20ABI,
functionName: 'allowance',
args: [address, contracts.mainnet.OETHVaultCore.address],
});

if (allowance < amountIn) {
try {
const { request } = await prepareWriteContract({
address: tokenIn.address,
abi: erc20ABI,
functionName: 'approve',
args: [contracts.mainnet.OETHVaultCore.address, amountIn],
});
const { hash } = await writeContract(request);
await waitForTransaction({ hash });

// TODO trigger notification
console.log(`mint vault approval done!`);
} catch (e) {
// TODO trigger notification
console.error(`mint vault approval error!\n${e.message}`);
return;
}
}

const minAmountOut = parseUnits(
(
+formatUnits(amountOut, tokenOut.decimals) -
+formatUnits(amountOut, tokenOut.decimals) * slippage
).toString(),
tokenOut.decimals,
);

try {
const { request } = await prepareWriteContract({
address: contracts.mainnet.OETHVaultCore.address,
abi: contracts.mainnet.OETHVaultCore.abi,
functionName: 'mint',
args: [tokenIn.address, amountIn, minAmountOut],
});
const { hash } = await writeContract(request);
await waitForTransaction({ hash });

// TODO trigger notification
console.log('mint vault done!');
} catch (e) {
// TODO trigger notification
console.error(`mint vault error!\n${e.message}`);
}
};

export default {
estimateAmount,
estimateGas,
estimateRoute,
swap,
};
Loading