Skip to content

Commit

Permalink
Deploy new DebtRepayer contract (#71)
Browse files Browse the repository at this point in the history
* Deploy debt repayer

* Update block number for base

* Adjust anvil params and timeouts

* No need for XL

* Wait longer for initial data load

* Fix wonky withdrawal that failed because cypress was clicking submit too fast
  • Loading branch information
noisekit authored Nov 28, 2024
1 parent f7baf82 commit 575b6f0
Show file tree
Hide file tree
Showing 27 changed files with 216 additions and 203 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ jobs:
e2e:
docker:
- image: cimg/node:<< pipeline.parameters.node-version >>
resource_class: xlarge
resource_class: large
parallelism: 3
steps:
- checkout
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ and all transactions will be automatically signed, without any popups

```sh
# Mainnets
anvil --auto-impersonate --chain-id 1 --fork-url wss://mainnet.infura.io/ws/v3/$INFURA_KEY --no-rate-limit --steps-tracing --fork-block-number 21233424
anvil --auto-impersonate --chain-id 8453 --fork-url wss://base-mainnet.infura.io/ws/v3/$INFURA_KEY --no-rate-limit --steps-tracing --fork-block-number 22946353
anvil --auto-impersonate --chain-id 42161 --fork-url wss://arbitrum-mainnet.infura.io/ws/v3/$INFURA_KEY --no-rate-limit --steps-tracing --fork-block-number 271813668
anvil --auto-impersonate --chain-id 1 --fork-url wss://mainnet.infura.io/ws/v3/$INFURA_KEY --fork-block-number 21233424
anvil --auto-impersonate --chain-id 8453 --fork-url wss://base-mainnet.infura.io/ws/v3/$INFURA_KEY --fork-block-number 22991081
anvil --auto-impersonate --chain-id 42161 --fork-url wss://arbitrum-mainnet.infura.io/ws/v3/$INFURA_KEY --fork-block-number 271813668
# Testnets
anvil --auto-impersonate --chain-id 11155111 --fork-url wss://sepolia.infura.io/ws/v3/$INFURA_KEY --no-rate-limit --steps-tracing
anvil --auto-impersonate --chain-id 84532 --fork-url wss://base-sepolia.infura.io/ws/v3/$INFURA_KEY --no-rate-limit --steps-tracing
anvil --auto-impersonate --chain-id 421614 --fork-url wss://arbitrum-sepolia.infura.io/ws/v3/$INFURA_KEY --no-rate-limit --steps-tracing
anvil --auto-impersonate --chain-id 11155111 --fork-url wss://sepolia.infura.io/ws/v3/$INFURA_KEY
anvil --auto-impersonate --chain-id 84532 --fork-url wss://base-sepolia.infura.io/ws/v3/$INFURA_KEY
anvil --auto-impersonate --chain-id 421614 --fork-url wss://arbitrum-sepolia.infura.io/ws/v3/$INFURA_KEY
```

2. Run Liquidity app locally
Expand Down
6 changes: 6 additions & 0 deletions contracts/close-position-arbitrum/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,10 @@ forge verify-contract \
--etherscan-api-key $ETHERSCAN_API_KEY \
0x800B12D24ebb639BCe7280861b05149F0D60F99e \
src/ClosePosition.sol:ClosePosition

forge verify-contract \
--verifier-url "https://api.arbiscan.io/api" \
--etherscan-api-key $ARBISCAN_API_KEY \
0x800B12D24ebb639BCe7280861b05149F0D60F99e \
src/DebtRepayer.sol:DebtRepayer
```
4 changes: 4 additions & 0 deletions contracts/close-position-arbitrum/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ allow_paths = [
"../../node_modules"
]
fs_permissions = [{ access = "read", path = "./" }, { access = "read", path = "../../node_modules" }]

optimizer = true
optimizer_runs = 200
compiler.version = "0.8.27+commit.40a35a09"
25 changes: 25 additions & 0 deletions contracts/debt-repayer-base-andromeda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,32 @@ forge create \
--rpc-url https://base-mainnet.infura.io/v3/$INFURA_API_KEY \
--chain 8453 \
--private-key $MAINNET_DEPLOYER_PRIVATE_KEY \
--verifier-url "https://api.basescan.org/api" \
--etherscan-api-key $BASESCAN_API_KEY \
--verify \
src/DebtRepayer.sol:DebtRepayer
```

## Verify contract

If something went wrong verifying first time

```sh
forge verify-contract \
--watch \
--chain 84532 \
--verifier etherscan \
--verifier-url "https://api-sepolia.basescan.org/api" \
--etherscan-api-key $BASESCAN_API_KEY \
0xe4b0233F06a308B4732282e24ce7aE0c87bdEcbc \
src/DebtRepayer.sol:DebtRepayer

forge verify-contract \
--watch \
--chain 8453 \
--verifier etherscan \
--verifier-url "https://api.basescan.org/api" \
--etherscan-api-key $BASESCAN_API_KEY \
0x624f2aB0f1DFF2297b9eca320898381Fbba4E3E3 \
src/DebtRepayer.sol:DebtRepayer
```
6 changes: 5 additions & 1 deletion contracts/debt-repayer-base-andromeda/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ libs = [
allow_paths = [
"../../node_modules"
]
fs_permissions = [{ access = "read", path = "./" }, { access = "read", path = "../../node_modules" }]
fs_permissions = [{ access = "read", path = "./" }, { access = "read", path = "../../node_modules" }]

optimizer = true
optimizer_runs = 200
compiler.version = "0.8.27+commit.40a35a09"
215 changes: 93 additions & 122 deletions liquidity/components/WithdrawModal/WithdrawModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,120 +10,22 @@ import { useAccountCollateral } from '@snx-v3/useAccountCollateral';
import { useDefaultProvider, useNetwork, useWallet } from '@snx-v3/useBlockchain';
import { useCollateralType } from '@snx-v3/useCollateralTypes';
import { useContractErrorParser } from '@snx-v3/useContractErrorParser';
import { LiquidityPosition } from '@snx-v3/useLiquidityPosition';
import { useLiquidityPosition } from '@snx-v3/useLiquidityPosition';
import { useParams } from '@snx-v3/useParams';
import { useStaticAaveUSDC } from '@snx-v3/useStaticAaveUSDC';
import { useSystemToken } from '@snx-v3/useSystemToken';
import { useUnwrapStataUSDC } from '@snx-v3/useUnwrapStataUSDC';
import { useWithdraw } from '@snx-v3/useWithdraw';
import { useWithdrawBaseAndromeda } from '@snx-v3/useWithdrawBaseAndromeda';
import { Wei } from '@synthetixio/wei';
import { useQueryClient } from '@tanstack/react-query';
import { ethers } from 'ethers';
import React, { FC, useContext, useState } from 'react';
import React, { useContext, useState } from 'react';
import { LiquidityPositionUpdated } from '../../ui/src/components/Manage/LiquidityPositionUpdated';

export const WithdrawModalUi: FC<{
amount: Wei;
isOpen: boolean;
onClose: () => void;
symbol?: string;
state: {
step: number;
status: string;
};
onSubmit: () => void;
isDebtWithdrawal: boolean;
isStataUSDC: boolean;
}> = ({ isStataUSDC, isDebtWithdrawal, amount, isOpen, onClose, onSubmit, state, symbol }) => {
if (isOpen) {
if (state.status === 'success') {
return (
<LiquidityPositionUpdated
onClose={onSubmit}
title={(isDebtWithdrawal ? 'Debt' : 'Collateral') + ' successfully Withdrawn'}
subline={
<>
Your <b>{isDebtWithdrawal ? 'Debt' : 'Collateral'}</b> has been withdrawn, read more
about it in the{' '}
<Link
href="https://docs.synthetix.io/v/synthetix-v3-user-documentation"
target="_blank"
color="cyan.500"
>
Synthetix V3 Documentation
</Link>
</>
}
alertText={(isDebtWithdrawal ? 'Debt' : 'Collateral') + ' successfully Withdrawn'}
/>
);
}

return (
<div data-cy="withdraw multistep">
<Text color="gray.50" fontSize="20px" fontWeight={700}>
<ArrowBackIcon cursor="pointer" onClick={onClose} mr={2} />
Manage {isDebtWithdrawal ? 'Debt' : 'Collateral'}
</Text>
<Divider my={4} />

<Multistep
step={1}
title="Withdraw"
subtitle={<Amount value={amount} suffix={` ${symbol} will be withdrawn`} />}
status={{
failed: state.step === 1 && state.status === 'error',
success: state.step > 1,
loading: state.step === 1 && state.status === 'pending',
}}
/>
{isStataUSDC && (
<Multistep
step={2}
title="Unwrap"
subtitle={<Text as="div">unwrap Static aUSDC into USDC</Text>}
status={{
failed: state.step === 2 && state.status === 'error',
success: state.status === 'success',
loading: state.step === 2 && state.status === 'pending',
}}
/>
)}

<Button
isDisabled={state.status === 'pending'}
onClick={onSubmit}
width="100%"
mt="6"
data-cy="withdraw confirm button"
>
{(() => {
switch (true) {
case state.status === 'error':
return 'Retry';
case state.status === 'pending':
return 'Processing...';
case state.status === 'success':
return 'Done';
default:
return 'Execute Transaction';
}
})()}
</Button>
</div>
);
}
};

export function WithdrawModal({
liquidityPosition,
onClose,
isOpen,
isDebtWithdrawal = false,
}: {
liquidityPosition?: LiquidityPosition;
isOpen: boolean;
onClose: () => void;
isDebtWithdrawal?: boolean;
}) {
Expand All @@ -143,29 +45,34 @@ export function WithdrawModal({

const { data: collateralType } = useCollateralType(params.collateralSymbol);
const errorParser = useContractErrorParser();
const accountId = liquidityPosition?.accountId;

const { data: liquidityPosition } = useLiquidityPosition({
tokenAddress: collateralType?.tokenAddress,
accountId: params.accountId,
poolId: params.poolId,
});

const isBase = isBaseAndromeda(network?.id, network?.preset);
const isStataUSDC =
collateralType?.address.toLowerCase() === getWrappedStataUSDCOnBase(network?.id).toLowerCase();

const { data: systemToken } = useSystemToken();
const { data: systemTokenBalance } = useAccountCollateral(accountId, systemToken?.address);
const { data: systemTokenBalance } = useAccountCollateral(params.accountId, systemToken?.address);

const { data: StaticAaveUSDC } = useStaticAaveUSDC();

const { mutateAsync: unwrapStata } = useUnwrapStataUSDC();

const { mutation: withdrawMain } = useWithdraw({
amount: withdrawAmount,
accountId,
accountId: params.accountId,
collateralTypeAddress: isDebtWithdrawal
? systemToken?.address
: liquidityPosition?.accountCollateral?.tokenAddress,
});

const { mutation: withdrawAndromeda } = useWithdrawBaseAndromeda({
accountId,
accountId: params.accountId,
availableCollateral: liquidityPosition?.accountCollateral.availableCollateral || ZEROWEI,
snxUSDCollateral: systemTokenBalance?.availableCollateral || ZEROWEI,
amountToWithdraw: withdrawAmount,
Expand Down Expand Up @@ -230,20 +137,16 @@ export function WithdrawModal({
}

queryClient.invalidateQueries({
queryKey: [`${network?.id}-${network?.preset}`, 'LiquidityPosition', { accountId }],
queryKey: [`${network?.id}-${network?.preset}`, 'LiquidityPosition'],
});
queryClient.invalidateQueries({
queryKey: [`${network?.id}-${network?.preset}`, 'AccountSpecificCollateral', { accountId }],
queryKey: [`${network?.id}-${network?.preset}`, 'AccountSpecificCollateral'],
});
queryClient.invalidateQueries({
queryKey: [`${network?.id}-${network?.preset}`, 'LiquidityPositions', { accountId }],
queryKey: [`${network?.id}-${network?.preset}`, 'LiquidityPositions'],
});
queryClient.invalidateQueries({
queryKey: [
`${network?.id}-${network?.preset}`,
'AccountCollateralUnlockDate',
{ accountId },
],
queryKey: [`${network?.id}-${network?.preset}`, 'AccountCollateralUnlockDate'],
});
queryClient.invalidateQueries({
queryKey: [`${network?.id}-${network?.preset}`, 'TokenBalance'],
Expand Down Expand Up @@ -276,16 +179,84 @@ export function WithdrawModal({
}
};

const amount = withdrawAmount;
const symbol = isDebtWithdrawal ? systemToken?.symbol : collateralType?.displaySymbol;
const state = txState;

if (state.status === 'success') {
return (
<LiquidityPositionUpdated
onClose={onSubmit}
title={(isDebtWithdrawal ? 'Debt' : 'Collateral') + ' successfully Withdrawn'}
subline={
<>
Your <b>{isDebtWithdrawal ? 'Debt' : 'Collateral'}</b> has been withdrawn, read more
about it in the{' '}
<Link
href="https://docs.synthetix.io/v/synthetix-v3-user-documentation"
target="_blank"
color="cyan.500"
>
Synthetix V3 Documentation
</Link>
</>
}
alertText={(isDebtWithdrawal ? 'Debt' : 'Collateral') + ' successfully Withdrawn'}
/>
);
}

return (
<WithdrawModalUi
amount={withdrawAmount}
isOpen={isOpen}
onClose={onClose}
symbol={isDebtWithdrawal ? systemToken?.symbol : collateralType?.displaySymbol}
state={txState}
onSubmit={onSubmit}
isDebtWithdrawal={isDebtWithdrawal}
isStataUSDC={isStataUSDC}
/>
<div data-cy="withdraw multistep">
<Text color="gray.50" fontSize="20px" fontWeight={700}>
<ArrowBackIcon cursor="pointer" onClick={onClose} mr={2} />
Manage {isDebtWithdrawal ? 'Debt' : 'Collateral'}
</Text>
<Divider my={4} />

<Multistep
step={1}
title="Withdraw"
subtitle={<Amount value={amount} suffix={` ${symbol} will be withdrawn`} />}
status={{
failed: state.step === 1 && state.status === 'error',
success: state.step > 1,
loading: state.step === 1 && state.status === 'pending',
}}
/>
{isStataUSDC && (
<Multistep
step={2}
title="Unwrap"
subtitle={<Text as="div">unwrap Static aUSDC into USDC</Text>}
status={{
failed: state.step === 2 && state.status === 'error',
success: state.status === 'success',
loading: state.step === 2 && state.status === 'pending',
}}
/>
)}

<Button
isDisabled={state.status === 'pending' || !Boolean(provider && StaticAaveUSDC)}
onClick={onSubmit}
width="100%"
mt="6"
data-cy="withdraw confirm button"
>
{(() => {
switch (true) {
case state.status === 'error':
return 'Retry';
case state.status === 'pending':
return 'Processing...';
case state.status === 'success':
return 'Done';
default:
return 'Execute Transaction';
}
})()}
</Button>
</div>
);
}
1 change: 0 additions & 1 deletion liquidity/components/WithdrawModal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"@snx-v3/useUnwrapStataUSDC": "workspace:*",
"@snx-v3/useWithdraw": "workspace:*",
"@snx-v3/useWithdrawBaseAndromeda": "workspace:*",
"@synthetixio/wei": "^2.74.4",
"@tanstack/react-query": "^5.8.3",
"ethers": "^5.7.2",
"react": "^18.2.0"
Expand Down
6 changes: 4 additions & 2 deletions liquidity/cypress/cypress/e2e/1-main/SNX_Deposit.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ describe(__filename, () => {

cy.visit(`/#/positions/SNX/1?manageAction=deposit&accountId=${Cypress.env('accountId')}`);

cy.get('[data-cy="deposit and lock collateral form"]', { timeout: 180_000 }).should('exist');
cy.get('[data-cy="balance amount"]').should('exist').and('include.text', 'Max');
cy.get('[data-cy="deposit and lock collateral form"]').should('exist');
cy.get('[data-cy="balance amount"]', { timeout: 180_000 })
.should('exist')
.and('include.text', 'Max');

cy.get('[data-cy="deposit amount input"]').type('101');
cy.get('[data-cy="deposit submit"]').should('be.enabled');
Expand Down
Loading

0 comments on commit 575b6f0

Please sign in to comment.