Skip to content

Commit

Permalink
SOV-2182: simulate rewards claiming transaction (#2515)
Browse files Browse the repository at this point in the history
* fix: simulate rewards claiming transaction

* fix: move simulator to the claim click
  • Loading branch information
creed-victor authored Apr 3, 2023
1 parent 555fdd1 commit 7cae806
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import React, { useCallback, useMemo } from 'react';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { useTranslation } from 'react-i18next';
import { IClaimFormProps } from '../BaseClaimForm/types';
import { useAccount } from 'app/hooks/useAccount';
Expand All @@ -8,7 +14,7 @@ import { translations } from 'locales/i18n';
import { AssetRenderer } from 'app/components/AssetRenderer';
import { Asset } from 'types';
import { useCacheCallWithValue } from 'app/hooks/useCacheCallWithValue';
import { gasLimit } from 'utils/classifiers';
import { currentChainId, gasLimit } from 'utils/classifiers';
import { useMaintenance } from 'app/hooks/useMaintenance';
import { weiToNumberFormat } from 'utils/display-text/format';
import { ActionButton } from 'app/components/Form/ActionButton';
Expand All @@ -18,6 +24,11 @@ import { bignumber } from 'mathjs';
import classNames from 'classnames';
import { LoadableValue } from 'app/components/LoadableValue';
import { TransactionDialog } from 'app/components/TransactionDialog';
import { simulateTx } from 'utils/simulator/simulateTx';
import { TxTuple } from 'utils/simulator/types';
import { getContract } from 'utils/blockchain/contract-helpers';
import { Sovryn } from 'utils/sovryn';
import { toastError } from 'utils/toaster';

interface IFeesEarnedClaimRowProps extends IClaimFormProps {
rbtcValue: number;
Expand All @@ -40,10 +51,12 @@ export const FeesEarnedClaimRow: React.FC<IFeesEarnedClaimRowProps> = ({
const { checkMaintenance, States } = useMaintenance();
const claimFeesEarnedLocked = checkMaintenance(States.CLAIM_FEES_EARNED);

const controllerRef = useRef<AbortController>();

const { value: maxCheckpoints } = useCacheCallWithValue(
'feeSharingProxy',
'numTokenCheckpoints',
100,
-1,
contractAddress,
);
const { send, ...tx } = useSendContractTx('feeSharingProxy', 'withdraw');
Expand All @@ -52,12 +65,15 @@ export const FeesEarnedClaimRow: React.FC<IFeesEarnedClaimRowProps> = ({
'withdrawRBTC',
);

const [isSimulating, setIsSimulating] = useState(false);

const isClaimDisabled = useMemo(
() =>
isSimulating ||
claimFeesEarnedLocked ||
!bignumber(amountToClaim).greaterThan(0) ||
assetClaimLocked,
[claimFeesEarnedLocked, amountToClaim, assetClaimLocked],
[isSimulating, claimFeesEarnedLocked, amountToClaim, assetClaimLocked],
);

const onSubmit = useCallback(() => {
Expand All @@ -76,6 +92,64 @@ export const FeesEarnedClaimRow: React.FC<IFeesEarnedClaimRowProps> = ({
}
}, [address, asset, contractAddress, maxCheckpoints, send, withdrawRBTC]);

const handleCheckBeforeSubmit = useCallback(() => {
if (controllerRef.current) {
controllerRef.current.abort();
}
setIsSimulating(true);

controllerRef.current = new AbortController();

const args =
asset === Asset.RBTC
? [0, address]
: [contractAddress, maxCheckpoints, address];

const method = asset === Asset.RBTC ? 'withdrawRBTC' : 'withdraw';

const tx: TxTuple = [
{
to: getContract('feeSharingProxy').address,
from: address,
value: '0',
input: Sovryn.contracts['feeSharingProxy'].methods[method](
...args,
).encodeABI(),
gas_price: '0',
gas: 6_800_000,
},
];

simulateTx(currentChainId, tx, controllerRef.current.signal)
.then(([{ transaction }]) => {
console.log('simulation response', asset, transaction);
if (transaction.status) {
onSubmit();
} else {
toastError(
t(translations.rewardPage.claimForm.contractFailure, {
currency: asset,
}),
);
}
})
.catch(() => {
// error from the simulator itself
toastError(t(translations.rewardPage.claimForm.simulatorFailure));
})
.finally(() => {
setIsSimulating(false);
});
}, [address, asset, contractAddress, maxCheckpoints, onSubmit, t]);

useEffect(() => {
return () => {
if (controllerRef.current) {
controllerRef.current.abort();
}
};
}, []);

return (
<tr
className={classNames({
Expand All @@ -98,7 +172,7 @@ export const FeesEarnedClaimRow: React.FC<IFeesEarnedClaimRowProps> = ({
<td>
<ActionButton
text={t(translations.rewardPage.claimForm.cta)}
onClick={onSubmit}
onClick={handleCheckBeforeSubmit}
className={classNames(
'tw-border-none tw-px-4 xl:tw-px-2 2xl:tw-px-4',
{
Expand Down
4 changes: 3 additions & 1 deletion src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1638,7 +1638,9 @@
"cta": "CLAIM",
"note": "Claiming will simultaneously claim both liquid and vested rewards, and automatically start a vesting period for the vested rewards of 40 weeks with a maximum 4-week cliff.",
"learn": "Learn more",
"claimDisabled": "There is not enough SOV in the StakingRewardsProxy contract to facilitate a claim of rewards at this time. Therefore, to avoid a loss of gas fee by initiating a transaction that will inevitably fail, the CLAIM button has been disabled. Be assured that the team is aware and funds should be replenished shortly."
"claimDisabled": "There is not enough SOV in the StakingRewardsProxy contract to facilitate a claim of rewards at this time. Therefore, to avoid a loss of gas fee by initiating a transaction that will inevitably fail, the CLAIM button has been disabled. Be assured that the team is aware and funds should be replenished shortly.",
"contractFailure": "Due to a known issue, claiming {{currency}} transaction will fail. Work on a fix is in progress.",
"simulatorFailure": "Unknown error, please try again later."
},
"liquidClaimForm": {
"note": "Claiming your rewards automatically adds them to your SOV portfolio balance.",
Expand Down

0 comments on commit 7cae806

Please sign in to comment.