Skip to content

Commit

Permalink
Merge pull request #28 from OriginProtocol:feat/routes-support
Browse files Browse the repository at this point in the history
Feat/routes-support
  • Loading branch information
toniocodo authored Sep 8, 2023
2 parents 0badb97 + c276ffa commit 7f814c7
Show file tree
Hide file tree
Showing 11 changed files with 1,520 additions and 53 deletions.
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

0 comments on commit 7f814c7

Please sign in to comment.