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

Merge #137

Merged
merged 12 commits into from
Jan 30, 2024
7 changes: 4 additions & 3 deletions packages/sdk/tasks/market/risk/borrow-caps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default task("market:set-borrow-cap", "Set borrow cap on market")
.addParam("maxBorrow", "Maximum amount of tokens that can be borrowed", undefined, types.string)
.setAction(async ({ admin, market, maxBorrow }, { ethers }) => {
const signer = await ethers.getNamedSigner(admin);
console.log("signer: ", signer.address);

const ionicSdkModule = await import("../../ionicSdk");
const sdk = await ionicSdkModule.getOrCreateIonic(signer);
Expand All @@ -15,7 +16,7 @@ export default task("market:set-borrow-cap", "Set borrow cap on market")
const comptroller = await cToken.callStatic.comptroller();
const pool = sdk.createComptroller(comptroller, signer);

const currentBorrowCap = await pool.callStatic.supplyCaps(cToken.address);
const currentBorrowCap = await pool.callStatic.borrowCaps(cToken.address);
console.log(`Current borrow cap is ${currentBorrowCap}`);

const newBorrowCap = ethers.BigNumber.from(maxBorrow);
Expand All @@ -27,8 +28,8 @@ export default task("market:set-borrow-cap", "Set borrow cap on market")
const tx: providers.TransactionResponse = await pool._setMarketBorrowCaps([cToken.address], [newBorrowCap]);
await tx.wait();

const newSupplyCapSet = await pool.callStatic.supplyCaps(cToken.address);
console.log(`New supply cap set: ${newSupplyCapSet.toNumber()}`);
const newBorrowCapset = await pool.callStatic.borrowCaps(cToken.address);
console.log(`New borrow cap set: ${newBorrowCapset.toString()}`);
});

task("market:set-borrow-cap-whitelist", "Pauses borrowing on a market")
Expand Down
18 changes: 15 additions & 3 deletions packages/ui/app/_components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ export default function Navbar() {

// },[pathname])
return (
<nav className="fixed z-50 flex items-center justify-between w-full py-4 pt-8 px-[4%] text-lg text-white/50 transition-all duration-300 ease-linear -translate-x-1/2 bg-transparent backdrop-blur-sm font-inter top-0 left-1/2 rounded-xl">
<nav className="fixed z-50 flex items-center justify-between w-full py-4 px-[4%] text-lg text-white/50 transition-all duration-300 ease-linear -translate-x-1/2 bg-transparent backdrop-blur-sm font-inter top-0 left-1/2 rounded-xl">
<div className="absolute w-full top-full left-0 bg-lime text-center p-2 text-darkone text-sm">
Hello, Mode! Ionic is open for deposits! Supply ETH, USDC, or USDT to
earn Ionic points. Borrowing will be open soon...
</div>
<Link
href={'/'}
className={`flex items-center pr-10 `}
Expand Down Expand Up @@ -95,15 +99,23 @@ export default function Navbar() {
Borrow
</p>
</Link>
<Link href={'/points'}>
*/}

<Link
href={'/'}
className="pointer-events-none relative"
>
<span className="absolute px-[5px] top-[90%] right-[50%] translate-x-1/2 bg-lime rounded-lg text-xxs text-darkone whitespace-nowrap ">
Soon!
</span>
<p
className={`${
pathname == '/points' ? 'text-accent' : null
} px-4 text-center transition-all duration-200 ease-linear rounded-md cursor-pointer `}
>
Points
</p>
</Link> */}
</Link>
</div>

<div
Expand Down
5 changes: 3 additions & 2 deletions packages/ui/app/_components/markets/PoolRows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ const PoolRows = ({
Supply / Withdraw
</Link>
<Link
href={`/?popmode=BORROW`}
className={`rounded-lg border text-white/50 border-white/50 py-1.5 px-3`}
// href={`/?popmode=BORROW`}
href={`/`}
className={`rounded-lg border text-white/50 border-white/50 py-1.5 px-3 opacity-30 pointer-events-none `}
onClick={() => setSelectedSymbol(asset)}
>
Borrow / Repay
Expand Down
273 changes: 273 additions & 0 deletions packages/ui/app/_components/popup/Swap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
'use client';
import { useMultiMidas } from '@ui/context/MultiIonicContext';
import React, { useMemo, useReducer, useState } from 'react';
import { useBalance } from 'wagmi';
import ResultHandler from '../ResultHandler';
import { BigNumber, Contract } from 'ethers';
import { getContract } from 'sdk/dist/cjs/src/IonicSdk/utils';
import { WETHAbi } from 'sdk/dist/cjs/src';
import TransactionStepsHandler, {
TransactionStep
} from './TransactionStepHandler';
import { useQueryClient } from '@tanstack/react-query';
import { useSwapAmount } from '@ui/hooks/useSwapAmount';

export type SwapProps = {
close: () => void;
};

export default function Swap({ close }: SwapProps) {
const { address, currentSdk } = useMultiMidas();
const enabledOutputTokens = useMemo<string[]>(
() => [...(currentSdk ? [currentSdk?.chainSpecificAddresses.W_TOKEN] : [])],
[currentSdk]
);
const [amount, setAmount] = useState<number>();
const [currentOutputToken, setCurrentOutputToken] = useState<
string | undefined
>(enabledOutputTokens.length ? enabledOutputTokens[0] : undefined);
const {
data: ethBalance,
isLoading: isLoadingEthBalance,
refetch: refetchEthBalance
} = useBalance({ address: address as any });
const {
data: wethBalance,
isLoading: wethBalanceLoading,
refetch: refetchwethBalance
} = useBalance({ address: address as any, token: currentOutputToken as any });
const queryClient = useQueryClient();
const WTokenContract = useMemo<Contract | undefined>(() => {
if (!currentSdk) {
return;
}

return getContract(
currentSdk.chainSpecificAddresses.W_TOKEN,
WETHAbi.abi,
currentSdk.signer
);
}, [currentSdk]);
// const { data } = useSwapAmount(
// currentSdk?.chainSpecificAddresses.STABLE_TOKEN,
// BigNumber.from('1000'),
// currentSdk?.chainSpecificAddresses.W_TOKEN,
// BigNumber.from('10000')
// );
// console.log(data);
const maxAmount = useMemo<number>(
() => parseFloat(ethBalance?.formatted ?? '0'),
[ethBalance]
);
const [transactionSteps, upsertTransactionStep] = useReducer(
(
prevState: TransactionStep[],
updatedStep:
| { transactionStep: TransactionStep; index: number }
| undefined
): TransactionStep[] => {
if (!updatedStep) {
return [];
}

const currentSteps = prevState.slice();

currentSteps[updatedStep.index] = {
...currentSteps[updatedStep.index],
...updatedStep.transactionStep
};

if (
updatedStep.transactionStep.error &&
updatedStep.index + 1 < currentSteps.length
) {
for (let i = updatedStep.index + 1; i < currentSteps.length; i++) {
currentSteps[i] = {
...currentSteps[i],
error: true
};
}
}

return currentSteps;
},
[]
);
const amountAsBInt = useMemo<BigNumber>(
() =>
BigNumber.from(
Math.round((amount ?? 0) * Math.pow(10, ethBalance?.decimals ?? 1))
),
[amount]
);

function handlInpData(e: React.ChangeEvent<HTMLInputElement>) {
const currentValue =
e.target.value.trim() === '' ? undefined : parseFloat(e.target.value);

setAmount(
currentValue && currentValue > maxAmount ? maxAmount : currentValue
);
}

function handleMax(val: number) {
setAmount(val);
}

const addStepsForAction = (steps: TransactionStep[]) => {
steps.forEach((step, i) =>
upsertTransactionStep({ transactionStep: step, index: i })
);
};
const swapAmount = async () => {
if (amountAsBInt && amountAsBInt.gt('0') && WTokenContract) {
let currentTransactionStep = 0;

addStepsForAction([
{
message: 'Swapping ETH -> WETH',
success: false,
error: false
}
]);

try {
const tx = await WTokenContract.deposit({
value: amountAsBInt
});

upsertTransactionStep({
transactionStep: {
...transactionSteps[currentTransactionStep],
txHash: tx.hash
},
index: currentTransactionStep
});

await tx.wait();

upsertTransactionStep({
transactionStep: {
...transactionSteps[currentTransactionStep],
success: true
},
index: currentTransactionStep
});
} catch (error) {
console.error(error);

upsertTransactionStep({
transactionStep: {
...transactionSteps[currentTransactionStep],
error: true
},
index: currentTransactionStep
});
}
}
};

const refetchUsedQueries = () => {
queryClient.invalidateQueries({ queryKey: ['useFusePoolData'] });
queryClient.invalidateQueries({ queryKey: ['useBorrowMinimum'] });
queryClient.invalidateQueries({ queryKey: ['useUsdPrice'] });
queryClient.invalidateQueries({ queryKey: ['useAllUsdPrices'] });
queryClient.invalidateQueries({ queryKey: ['useTotalSupplyAPYs'] });
queryClient.invalidateQueries({ queryKey: ['useUpdatedUserAssets'] });
queryClient.invalidateQueries({ queryKey: ['useMaxSupplyAmount'] });
queryClient.invalidateQueries({ queryKey: ['useMaxWithdrawAmount'] });
queryClient.invalidateQueries({ queryKey: ['useMaxBorrowAmount'] });
queryClient.invalidateQueries({ queryKey: ['useMaxRepayAmount'] });
queryClient.invalidateQueries({
queryKey: ['useSupplyCapsDataForPool']
});
queryClient.invalidateQueries({
queryKey: ['useBorrowCapsDataForAsset']
});
refetchEthBalance();
};

return (
<div
className={` z-40 fixed top-0 right-0 w-full min-h-screen bg-black/25 flex items-center justify-center`}
>
<div
className={`w-[45%] max-w-[450px] relative p-6 bg-grayUnselect rounded-xl max-h-[65vh] overflow-x-hidden overflow-y-scroll scrollbar-hide`}
>
<img
src="/img/assets/close.png"
alt="close"
className={` h-5 z-10 absolute right-4 top-3 cursor-pointer `}
onClick={() => close()}
/>

<div className="text-center text-lg font-bold mb-2">Swap Tokens</div>

<div className="flex justify-center items-center">
<img
src="/img/symbols/32/color/eth.png"
width="30"
height="30"
/>
<div className="mx-1">{' -> '}</div>
<img
src="/img/symbols/32/color/weth.png"
width="30"
height="30"
/>
</div>

<div className={` w-full h-[1px] bg-white/30 mx-auto my-3`}></div>

<div className="flex text-center">
<div className="relative w-1/2 mx-auto">
<input
type="number"
placeholder="ETH Amount"
value={amount}
onChange={(e) => handlInpData(e)}
className={`focus:outline-none w-full h-12 amount-field font-bold text-center bg-zinc-900 rounded-md`}
/>

<div className="flex w-full justify-center items-center mt-1 text-[10px] text-white/50">
<ResultHandler
width="15"
height="15"
isLoading={!ethBalance}
>
<span>{ethBalance?.formatted}</span>
<button
onClick={() => handleMax(maxAmount)}
className={`text-accent pl-2`}
>
MAX
</button>
</ResultHandler>
</div>
</div>
</div>

<div className="pt-4 text-center">
{transactionSteps.length > 0 ? (
<div className="flex justify-center text-left">
<TransactionStepsHandler
transactionSteps={transactionSteps}
resetTransactionSteps={() => {
upsertTransactionStep(undefined);
refetchUsedQueries();
}}
/>
</div>
) : (
<button
className={`px-6 rounded-md py-1 transition-colors bg-accent text-darkone`}
onClick={() => swapAmount()}
>
SWAP
</button>
)}
</div>
</div>
</div>
);
}
Loading
Loading