Skip to content

Commit

Permalink
bulk estimation gas for claim proceeds and claim fees (#6992)
Browse files Browse the repository at this point in the history
  • Loading branch information
bthaile committed Mar 29, 2020
1 parent 67079bd commit 302945f
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 59 deletions.
2 changes: 1 addition & 1 deletion packages/augur-ui/src/modules/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ export const NEW_MARKET_GAS_ESTIMATE = createBigNumber(2000000);
export const MIGRATE_MARKET_GAS_ESTIMATE = createBigNumber(3000000); // TODO: Get actual gas estimate for migrating a market
export const CLAIM_MARKETS_PROCEEDS_GAS_ESTIMATE = createBigNumber(1121349); // Gas cost for claiming proceeds from a categorical market with 8 outcomes (worst-case gas cost)
export const CLAIM_MARKETS_PROCEEDS_GAS_LIMIT = createBigNumber(3000000);
export const CLAIM_FEES_GAS_COST = createBigNumber(250000);
export const CLAIM_FEES_GAS_COST = createBigNumber(500000);
export const BUY_PARTICIPATION_TOKENS_GAS_LIMIT = createBigNumber(290000);
export const MAX_BULK_CLAIM_MARKETS_PROCEEDS_COUNT = Math.floor(
createBigNumber(CLAIM_MARKETS_PROCEEDS_GAS_LIMIT)
Expand Down
39 changes: 33 additions & 6 deletions packages/augur-ui/src/modules/modal/containers/modal-claim-fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import {
formatGasCostToEther,
formatAttoRep,
formatAttoDai,
formatEther,
formatBlank,
} from 'utils/format-number';
import { closeModal } from 'modules/modal/actions/close-modal';
import { Proceeds } from 'modules/modal/proceeds';
import { ActionRowsProps } from 'modules/modal/common';
import {
redeemStake,
redeemStakeBatches,
redeemStakeGas,
} from 'modules/reporting/actions/claim-reporting-fees';
import {
CLAIM_FEE_WINDOWS,
Expand All @@ -37,11 +40,7 @@ import { addPendingData } from 'modules/pending-queue/actions/pending-queue-mana
const mapStateToProps = (state: AppState) => {
return {
modal: state.modal,
gasCost: formatGasCostToEther(
CLAIM_FEES_GAS_COST,
{ decimalsRounded: 4 },
getGasPrice(state)
),
gasCost: CLAIM_FEES_GAS_COST,
GsnEnabled: state.appStatus.gsnEnabled,
pendingQueue: state.pendingQueue || [],
claimReportingFees: selectReportingWinningsByMarket(state),
Expand All @@ -52,6 +51,7 @@ const mapStateToProps = (state: AppState) => {
const mapDispatchToProps = (dispatch: ThunkDispatch<void, any, Action>) => ({
closeModal: () => dispatch(closeModal()),
redeemStake: (options, callback) => redeemStake(options, callback),
redeemStakeGas: options => redeemStakeGas(options),
disavowMarket: marketId => disavowMarket(marketId),
addPendingData: (pendingId, queueName, status, hash, info) =>
dispatch(addPendingData(pendingId, queueName, status, hash, info)),
Expand All @@ -77,6 +77,8 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
};
const submitAllTxCount = redeemStakeBatches(allRedeemStakeOptions);
const claimableMarkets = claimReportingFees.claimableMarkets;
const showBreakdown = claimableMarkets.marketContracts.length > 1;
const totalRep = `${formatAttoRep(claimReportingFees.totalUnclaimedRep).formatted} REP`;

if (!participationTokensOnly) {
claimableMarkets.marketContracts.map(marketObj => {
Expand Down Expand Up @@ -159,6 +161,8 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
});
}

let daiFormatted = formatBlank();

if (claimReportingFees.participationContracts.unclaimedRep.gt(ZERO)) {
const disputeWindowsPending =
pendingQueue[CLAIM_STAKE_FEES] &&
Expand All @@ -167,7 +171,7 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
const repFormatted = formatAttoRep(
claimReportingFees.participationContracts.unclaimedRep
);
const daiFormatted = formatAttoDai(
daiFormatted = formatAttoDai(
claimReportingFees.participationContracts.unclaimedDai
);
modalRows.push({
Expand Down Expand Up @@ -213,6 +217,17 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
return {};
}

const breakdown = showBreakdown ? [
{
label: 'Total REP',
value: totalRep,
},
{
label: 'Total DAI',
value: daiFormatted,
},
] : null;

return {
title: isForking ? 'Release REP' : 'Claim Stake & Fees',
submitAllTxCount: isForking ? 0 : submitAllTxCount,
Expand Down Expand Up @@ -254,6 +269,18 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
}
dP.closeModal();
},
estimateGas: async () => {
if (breakdown) {
const gas = await dP.redeemStakeGas(allRedeemStakeOptions);
const displayfee = sP.GsnEnabled ? displayGasInDai(gas) : formatEther(gas).formattedValue;
return {
label: 'Transaction Fee',
value: String(displayfee),
};
}
return null;
},
breakdown,
buttons:
isForking || participationTokensOnly
? null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { startClaimingMarketsProceeds } from 'modules/positions/actions/claim-markets-proceeds';
import { startClaimingMarketsProceeds, claimMarketsProceedsGas } from 'modules/positions/actions/claim-markets-proceeds';
import { selectCurrentTimestampInSeconds } from 'appStore/select-state';
import { createBigNumber } from 'utils/create-big-number';
import { getGasPrice } from 'modules/auth/selectors/get-gas-price';
import {
formatGasCostToEther,
formatDai,
formatEther,
} from 'utils/format-number';
Expand All @@ -31,12 +29,6 @@ import { selectLoginAccountClaimablePositions } from 'modules/positions/selector
import { displayGasInDai } from 'modules/app/actions/get-ethToDai-rate';

const mapStateToProps = (state: AppState) => {
const gasCost = formatGasCostToEther(
CLAIM_MARKETS_PROCEEDS_GAS_ESTIMATE,
{ decimalsRounded: 4 },
getGasPrice(state)
);

const pendingQueue = state.pendingQueue || [];
const accountMarketClaimablePositions: MarketClaimablePositions = selectLoginAccountClaimablePositions(
state
Expand Down Expand Up @@ -73,6 +65,12 @@ const mapStateToProps = (state: AppState) => {
label: 'Profit',
value: unclaimedProfit.full,
},
{
label: 'Transaction Fee',
value: state.appStatus.gsnEnabled
? displayGasInDai(CLAIM_MARKETS_PROCEEDS_GAS_ESTIMATE)
: formatEther(CLAIM_MARKETS_PROCEEDS_GAS_ESTIMATE).formattedValue,
},
],
text: PROCEEDS_TO_CLAIM_TITLE,
action: null,
Expand All @@ -82,58 +80,54 @@ const mapStateToProps = (state: AppState) => {
}
return {
modal: state.modal,
gasCost,
gasCost: CLAIM_MARKETS_PROCEEDS_GAS_ESTIMATE,
currentTimestamp: selectCurrentTimestampInSeconds(state),
claimableMarkets,
totalUnclaimedProfit:
accountMarketClaimablePositions.totals.totalUnclaimedProfit,
totalUnclaimedProceeds:
accountMarketClaimablePositions.totals.totalUnclaimedProceeds,
GsnEnabled: state.appStatus.gsnEnabled,
account: state.loginAccount.address,
};
};

const mapDispatchToProps = (dispatch: ThunkDispatch<void, any, Action>) => ({
closeModal: () => dispatch(closeModal()),
startClaimingMarketsProceeds: (
marketIds: string[],
account: string,
callback: NodeStyleCallback
) => dispatch(startClaimingMarketsProceeds(marketIds, callback)),
) => startClaimingMarketsProceeds(marketIds, account, callback),
estimateGas: (
marketIds: string[],
address: string,
) => claimMarketsProceedsGas(marketIds, address),
});

const mergeProps = (sP: any, dP: any, oP: any) => {
const markets = sP.claimableMarkets;
const showBreakdown = markets.length > 1;
const totalGas = formatEther(
createBigNumber(sP.gasCost).times(markets.length)
);
const claimableMarkets = showBreakdown
? markets.map(m => ({
...m,
queueName: CLAIMMARKETSPROCEEDS,
queueId: m.marketId,
action: () => dP.startClaimingMarketsProceeds([m.marketId], () => {}),
action: () => dP.startClaimingMarketsProceeds([m.marketId], sP.account, () => {}),
}))
: markets.map(m => ({
...m,
action: () => dP.startClaimingMarketsProceeds([m.marketId], () => {}),
action: () => dP.startClaimingMarketsProceeds([m.marketId], sP.account, () => {}),
queueName: CLAIMMARKETSPROCEEDS,
queueId: m.marketId,
properties: [
...m.properties,
{
label: 'Transaction Fee',
value: sP.GsnEnabled
? displayGasInDai(totalGas.value)
: totalGas.formattedValue,
},
],
}));

const multiMarket = claimableMarkets.length > 1 ? 's' : '';
const totalUnclaimedProceedsFormatted = formatDai(sP.totalUnclaimedProceeds);
const totalUnclaimedProfitFormatted = formatDai(sP.totalUnclaimedProfit);

const submitAllTxCount = Math.ceil(
claimableMarkets.length / MAX_BULK_CLAIM_MARKETS_PROCEEDS_COUNT
);
Expand All @@ -146,6 +140,17 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
return {};
}

const breakdown = showBreakdown ? [
{
label: 'Total Proceeds',
value: totalUnclaimedProceedsFormatted.formatted,
},
{
label: 'Total Profit',
value: totalUnclaimedProfitFormatted.formatted,
},
] : null;

return {
title: PROCEEDS_TO_CLAIM_TITLE,
descriptionMessage: [
Expand All @@ -156,20 +161,18 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
],
rows: claimableMarkets,
submitAllTxCount,
breakdown: showBreakdown ? [
{
label: 'Total Proceeds',
value: totalUnclaimedProceedsFormatted.formatted,
},
{
label: 'Total Profit',
value: totalUnclaimedProfitFormatted.formatted,
},
{
label: 'Transaction Fee',
value: sP.GsnEnabled ? displayGasInDai(totalGas.value) : totalGas.formattedValue,
},
] : null,
estimateGas: async () => {
if (breakdown) {
const gas = await dP.estimateGas(claimableMarkets.map(m => m.marketId), sP.account);
const displayfee = sP.GsnEnabled ? displayGasInDai(gas) : formatEther(gas).formattedValue;
return {
label: 'Transaction Fee',
value: String(displayfee),
};
}
return null;
},
breakdown,
closeAction: () => {
if (sP.modal.cb) {
sP.modal.cb();
Expand All @@ -183,6 +186,7 @@ const mergeProps = (sP: any, dP: any, oP: any) => {
action: () => {
dP.startClaimingMarketsProceeds(
claimableMarkets.map(m => m.marketId),
sP.account,
sP.modal.cb
);
dP.closeModal();
Expand Down
23 changes: 19 additions & 4 deletions packages/augur-ui/src/modules/modal/proceeds.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';

import { DefaultButtonProps } from 'modules/common/buttons';
import {
Expand All @@ -17,6 +17,7 @@ import {

import Styles from 'modules/modal/modal.styles.less';
import { CLAIM_ALL_TITLE } from 'modules/common/constants';
import { useEffect } from 'react';

interface ProceedsProps {
closeAction: Function;
Expand All @@ -26,6 +27,7 @@ interface ProceedsProps {
submitAllTxCount: number;
breakdown?: LinearPropertyLabelProps[];
descriptionMessage?: DescriptionMessageProps;
estimateGas: Function;
}

export const Proceeds = ({
Expand All @@ -36,7 +38,20 @@ export const Proceeds = ({
submitAllTxCount,
breakdown,
descriptionMessage,
}: ProceedsProps) => (
estimateGas
}: ProceedsProps) => {
const [fullBreakdown, setBreakdown] = useState(breakdown);
useEffect(() => {
const timer = setTimeout(async () => {
const transactionFee = await estimateGas();
if (transactionFee) {
setBreakdown([...fullBreakdown, transactionFee]);
}
}, 100);
return () => clearTimeout(timer);
},[]);

return (
<div className={Styles.Proceeds}>
<Title title={title} closeAction={closeAction} />
<main>
Expand All @@ -47,7 +62,7 @@ export const Proceeds = ({
{/*
// @ts-ignore */}
{rows && <ActionRows rows={rows} />}
{breakdown && <Breakdown short rows={breakdown} />}
{breakdown && <Breakdown short rows={fullBreakdown} />}
</main>
<BulkTxLabel
buttonName={CLAIM_ALL_TITLE}
Expand All @@ -56,4 +71,4 @@ export const Proceeds = ({
/>
{buttons && <ButtonsRow buttons={buttons} />}
</div>
);
)};
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ import {
claimMarketsProceeds,
claimMarketsProceedsEstimateGas,
} from 'modules/contracts/actions/contractCalls';
import { AppState } from 'appStore';
import { NodeStyleCallback } from 'modules/types';
import { ThunkDispatch } from 'redux-thunk';
import { Action } from 'redux';
import { BigNumber } from 'utils/create-big-number';

export const startClaimingMarketsProceeds = (
marketIds: string[],
account: string,
callback: NodeStyleCallback = logError
) => (dispatch: ThunkDispatch<void, any, Action>, getState: () => AppState) => {
const { loginAccount } = getState();
if (!loginAccount.address || !marketIds || !marketIds.length)
) => {
if (!account || !marketIds || !marketIds.length)
return callback(null);

let i = 0;
Expand All @@ -29,20 +27,22 @@ export const startClaimingMarketsProceeds = (

try {
// TODO: Pass affiliate address to claimMarketsProceeds
groups.map(group => claimMarketsProceeds(group, loginAccount.address));
groups.map(group => claimMarketsProceeds(group, account));
} catch (e) {
console.error(e);
}
};

export default claimMarketsProceeds;

export const claimMarketsProceedsGas = (
export const claimMarketsProceedsGas = async (
marketIds: string[],
loginAccount: string
) => {
): Promise<BigNumber> => {
try {
return claimMarketsProceedsEstimateGas(marketIds, loginAccount);
const value = await claimMarketsProceedsEstimateGas(marketIds, loginAccount);
console.log('gas estimate', value.toString());
return value;
} catch (error) {
console.error('error could estimate gas', error);
return CLAIM_MARKETS_PROCEEDS_GAS_ESTIMATE;
Expand Down

0 comments on commit 302945f

Please sign in to comment.