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

feat(explorer): fee breakdown #5024

Draft
wants to merge 10 commits into
base: develop
Choose a base branch
from
11 changes: 8 additions & 3 deletions apps/cowswap-frontend/src/legacy/state/orders/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ export type OrderInfoApi = Pick<
| 'executedSellAmount'
| 'executedSellAmountBeforeFees'
| 'executedFeeAmount'
| 'executedSurplusFee'
| 'executedFee'
| 'executedFeeToken'
| 'totalFee'
| 'invalidated'
| 'ethflowData'
| 'onchainOrderData'
Expand Down Expand Up @@ -139,6 +141,7 @@ export interface AddPendingOrderParams {
order: SerializedOrder
isSafeWallet: boolean
}

export type ChangeOrderStatusParams = { id: UID; chainId: ChainId }
export type SetOrderCancellationHashParams = ChangeOrderStatusParams & { hash: string }

Expand Down Expand Up @@ -177,11 +180,13 @@ export interface BatchOrdersUpdateParams {
}

export type PresignedOrdersParams = BatchOrdersUpdateParams

export interface UpdatePresignGnosisSafeTxParams {
orderId: UID
chainId: ChainId
safeTransaction: SafeMultisigTransactionResponse
}

export type ExpireOrdersBatchParams = BatchOrdersUpdateParams
export type InvalidateOrdersBatchParams = BatchOrdersUpdateParams
export type CancelOrdersBatchParams = BatchOrdersUpdateParams
Expand All @@ -196,7 +201,7 @@ export const fulfillOrdersBatch = createAction<FulfillOrdersBatchParams>('order/
export const preSignOrders = createAction<PresignedOrdersParams>('order/presignOrders')

export const updatePresignGnosisSafeTx = createAction<UpdatePresignGnosisSafeTxParams>(
'order/updatePresignGnosisSafeTx'
'order/updatePresignGnosisSafeTx',
)

export const expireOrdersBatch = createAction<ExpireOrdersBatchParams>('order/expireOrdersBatch')
Expand All @@ -214,7 +219,7 @@ export const deleteOrders = createAction<DeleteOrdersParams>('order/deleteOrders
export const clearOrders = createAction<{ chainId: ChainId }>('order/clearOrders')

export const updateLastCheckedBlock = createAction<{ chainId: ChainId; lastCheckedBlock: number }>(
'order/updateLastCheckedBlock'
'order/updateLastCheckedBlock',
)

export const clearOrdersStorage = createAction('order/clearOrdersStorage')
Expand Down
17 changes: 9 additions & 8 deletions apps/cowswap-frontend/src/legacy/state/orders/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export function getDefaultNetworkState(chainId: ChainId): OrdersStateNetwork {
// makes sure there's always an object at state[chainId], state[chainId].pending | .fulfilled
function prefillState(
state: Writable<OrdersState>,
{ payload: { chainId } }: PayloadAction<PrefillStateRequired>
{ payload: { chainId } }: PayloadAction<PrefillStateRequired>,
): asserts state is Required<OrdersState> {
const stateAtChainId = state[chainId]

Expand Down Expand Up @@ -174,7 +174,7 @@ function addOrderToState(
id: string,
status: OrderTypeKeys,
order: SerializedOrder,
isSafeWallet: boolean
isSafeWallet: boolean,
): void {
// Attempt to fix `TypeError: Cannot add property <x>, object is not extensible`
// seen on https://user-images.githubusercontent.com/34510341/138450105-bb94a2d1-656e-4e15-ae99-df9fb33c8ca4.png
Expand All @@ -200,7 +200,7 @@ function cancelOrderInState(
state: Required<OrdersState>,
chainId: ChainId,
orderObject: OrderObject,
isSafeWallet: boolean
isSafeWallet: boolean,
) {
const id = orderObject.id

Expand Down Expand Up @@ -368,12 +368,13 @@ export default createReducer(initialState, (builder) =>

orderObject.order.apiAdditionalInfo = {
creationDate: order.creationDate,
availableBalance: order.availableBalance,
executedBuyAmount: order.executedBuyAmount,
executedSellAmount: order.executedSellAmount,
executedSellAmountBeforeFees: order.executedSellAmountBeforeFees,
executedFeeAmount: order.executedFeeAmount,
executedSurplusFee: order.executedSurplusFee,
executedFee: order.executedFee,
executedFeeToken: order.executedFeeToken,
totalFee: order.totalFee,
invalidated: order.invalidated,
ethflowData: order.ethflowData,
onchainOrderData: order.onchainOrderData,
Expand Down Expand Up @@ -458,7 +459,7 @@ export default createReducer(initialState, (builder) =>
const allOrdersMap = flatOrdersStateNetwork(state[chainId])

const children = Object.values(allOrdersMap).filter(
(item) => item?.order.composableCowInfo?.parentId === id
(item) => item?.order.composableCowInfo?.parentId === id,
)

children.forEach((child) => {
Expand Down Expand Up @@ -544,12 +545,12 @@ export default createReducer(initialState, (builder) =>
orderListByChain[status] = ordersCleaned
})
})
})
}),
)

function reClassifyOrder(
newOrder: SerializedOrder,
existingOrder: OrderObject | undefined
existingOrder: OrderObject | undefined,
): { status: OrderStatus; isCancelling: boolean | undefined } {
// Onchain cancellations are considered final
// Still, the order classification at apps/cowswap-frontend/src/legacy/state/orders/utils.ts can't tell
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,42 @@ import * as styledEl from './styled'

export type Props = { order: ParsedOrder }

// TODO: get rid of this once https://github.com/cowprotocol/services/pull/3184 is complete
const HAS_BACKEND_MIGRATED = false

function getFeeToken(order: ParsedOrder) {
if (!HAS_BACKEND_MIGRATED) {
return order.inputToken
}

const { inputToken, outputToken } = order
const { executedFeeToken } = order.executionData

if (inputToken?.address.toLowerCase() === executedFeeToken?.toLowerCase()) {
return inputToken
}
if (outputToken?.address.toLowerCase() === executedFeeToken?.toLowerCase()) {
return outputToken
}
return undefined
}

export function FeeField({ order }: Props): JSX.Element | null {
const { inputToken } = order
const { executedFeeAmount, executedSurplusFee } = order.executionData
const { totalFee } = order.executionData
const feeToken = getFeeToken(order)

if (!inputToken) return <styledEl.Value></styledEl.Value>
if (!feeToken) return <styledEl.Value></styledEl.Value>

// TODO: use the value from SDK
const totalFee = CurrencyAmount.fromRawAmount(inputToken, (executedSurplusFee ?? executedFeeAmount) || 0)
const quoteSymbol = inputToken.symbol
const totalFeeAmount = CurrencyAmount.fromRawAmount(feeToken, totalFee || 0)
const quoteSymbol = feeToken.symbol

return (
<styledEl.Value>
{!quoteSymbol || !totalFee ? (
<span>-</span>
) : (
<span>
<TokenAmount amount={totalFee} tokenSymbol={inputToken} />
<TokenAmount amount={totalFeeAmount} tokenSymbol={feeToken} />
</span>
)}
</styledEl.Value>
Expand Down
12 changes: 9 additions & 3 deletions apps/cowswap-frontend/src/utils/orderUtils/parseOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export interface ParsedOrderExecutionData {
surplusAmount: BigNumber
surplusPercentage: BigNumber
executedFeeAmount: string | undefined
executedSurplusFee: string | null
executedFee: string | null
executedFeeToken: string | null
totalFee: string | null
filledPercentDisplay: string
executedPrice: Price<Currency, Currency> | null
activityId: string | undefined
Expand Down Expand Up @@ -60,7 +62,9 @@ export const parseOrder = (order: Order): ParsedOrder => {
const { executedBuyAmount, executedSellAmount } = getOrderExecutedAmounts(order)
const expirationTime = new Date(Number(order.validTo) * 1000)
const executedFeeAmount = order.apiAdditionalInfo?.executedFeeAmount
const executedSurplusFee = order.apiAdditionalInfo?.executedSurplusFee || null
const executedFee = order.apiAdditionalInfo?.executedFee || null
const executedFeeToken = order.apiAdditionalInfo?.executedFeeToken || null
const totalFee = order.apiAdditionalInfo?.totalFee || null
const creationTime = new Date(order.creationTime)
const fullyFilled = isOrderFilled(order)
const partiallyFilled = isPartiallyFilled(order)
Expand All @@ -80,6 +84,7 @@ export const parseOrder = (order: Order): ParsedOrder => {
const activityTitle = showCreationTxLink ? 'Creation transaction' : 'Order ID'

const executionData: ParsedOrderExecutionData = {
executedFeeToken,
executedBuyAmount,
executedSellAmount,
filledAmount,
Expand All @@ -88,7 +93,8 @@ export const parseOrder = (order: Order): ParsedOrder => {
surplusAmount,
surplusPercentage,
executedFeeAmount,
executedSurplusFee,
executedFee,
totalFee,
executedPrice,
fullyFilled,
partiallyFilled,
Expand Down
18 changes: 14 additions & 4 deletions apps/explorer/src/api/operator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ export type RawOrder = EnrichedOrder
*/
export type Order = Pick<
RawOrder,
'owner' | 'uid' | 'appData' | 'kind' | 'partiallyFillable' | 'signature' | 'class' | 'fullAppData'
| 'owner'
| 'uid'
| 'appData'
| 'kind'
| 'partiallyFillable'
| 'signature'
| 'class'
| 'fullAppData'
| 'executedFeeToken'
> & {
receiver: string
txHash?: string
Expand All @@ -35,8 +43,10 @@ export type Order = Pick<
executedSellAmount: BigNumber
feeAmount: BigNumber
executedFeeAmount: BigNumber
executedSurplusFee: BigNumber | null
executedFee: BigNumber | null
totalFee: BigNumber
networkCosts?: BigNumber
protocolFees?: BigNumber
cancelled: boolean
status: OrderStatus
partiallyFilled: boolean
Expand All @@ -55,12 +65,12 @@ export type RawTrade = TradeMetaData
/**
* Enriched Trade type
*/
export type Trade = Pick<RawTrade, 'blockNumber' | 'logIndex' | 'owner' | 'txHash'> & {
export type Trade = Pick<RawTrade, 'blockNumber' | 'logIndex' | 'owner' | 'txHash' | 'executedProtocolFees'> & {
orderId: string
kind?: OrderKind
buyAmount: BigNumber
sellAmount: BigNumber
executedSurplusFee?: BigNumber
executedFee?: BigNumber
sellAmountBeforeFees: BigNumber
buyToken?: TokenErc20 | null
buyTokenAddress: string
Expand Down
Loading
Loading