Skip to content

Commit

Permalink
feat: capture analytic events
Browse files Browse the repository at this point in the history
  • Loading branch information
therealemjy committed Aug 22, 2023
1 parent 1496914 commit fa71323
Show file tree
Hide file tree
Showing 43 changed files with 566 additions and 209 deletions.
6 changes: 3 additions & 3 deletions src/clients/api/__mocks__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,9 @@ export const repayVai = vi.fn();
export const useRepayVai = (options?: MutationObserverOptions) =>
useMutation(FunctionKey.REPAY_VAI, repayVai, options);

export const enterMarkets = vi.fn();
export const useEnterMarkets = (options?: MutationObserverOptions) =>
useMutation(FunctionKey.ENTER_MARKETS, enterMarkets, options);
export const enterMarket = vi.fn();
export const useEnterMarket = (options?: MutationObserverOptions) =>
useMutation(FunctionKey.ENTER_MARKET, enterMarket, options);

export const exitMarket = vi.fn();
export const useExitMarket = (options?: MutationObserverOptions) =>
Expand Down
6 changes: 3 additions & 3 deletions src/clients/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export { default as repayVai } from './mutations/repayVai';
export * from './mutations/repayVai';
export { default as useRepayVai } from './mutations/repayVai/useRepayVai';

export { default as enterMarkets } from './mutations/enterMarkets';
export * from './mutations/enterMarkets';
export { default as useEnterMarkets } from './mutations/enterMarkets/useEnterMarkets';
export { default as enterMarket } from './mutations/enterMarket';
export * from './mutations/enterMarket';
export { default as useEnterMarket } from './mutations/enterMarket/useEnterMarket';

export { default as exitMarket } from './mutations/exitMarket';
export * from './mutations/exitMarket';
Expand Down
20 changes: 18 additions & 2 deletions src/clients/api/mutations/borrow/useBorrow.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { MutationObserverOptions, useMutation } from 'react-query';
import { VToken } from 'types';
import { callOrThrow } from 'utilities';
import { callOrThrow, convertWeiToTokens } from 'utilities';

import { BorrowInput, BorrowOutput, borrow, queryClient } from 'clients/api';
import FunctionKey from 'constants/functionKey';
import { useAnalytics } from 'context/Analytics';
import useGetVTokenContract from 'hooks/useGetVTokenContract';

type TrimmedBorrowInput = Omit<BorrowInput, 'vTokenContract'>;
type Options = MutationObserverOptions<BorrowOutput, Error, TrimmedBorrowInput>;

const useBorrow = ({ vToken }: { vToken: VToken }, options?: Options) => {
const useBorrow = (
{ vToken, poolName }: { vToken: VToken; poolName: string },
options?: Options,
) => {
const vTokenContract = useGetVTokenContract(vToken);
const { captureAnalyticEvent } = useAnalytics();

return useMutation(
[FunctionKey.BORROW, { vToken }],
Expand All @@ -24,6 +29,17 @@ const useBorrow = ({ vToken }: { vToken: VToken }, options?: Options) => {
{
...options,
onSuccess: async (...onSuccessParams) => {
const { amountWei } = onSuccessParams[1];

captureAnalyticEvent('Tokens borrowed', {
poolName,
tokenSymbol: vToken.underlyingToken.symbol,
tokenAmountTokens: convertWeiToTokens({
token: vToken.underlyingToken,
valueWei: amountWei,
}).toNumber(),
});

const accountAddress = await vTokenContract?.signer.getAddress();

queryClient.invalidateQueries(FunctionKey.GET_V_TOKEN_BALANCES_ALL);
Expand Down
4 changes: 3 additions & 1 deletion src/clients/api/mutations/claimRewards/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Vi from 'vitest';

import fakeAddress from '__mocks__/models/address';
import fakeContractReceipt from '__mocks__/models/contractReceipt';
import { TESTNET_TOKENS } from 'constants/tokens';
import {
checkForComptrollerTransactionError,
checkForTokenTransactionError,
Expand All @@ -22,7 +23,7 @@ const fakeClaims: Claim[] = [
},
{
contract: 'xvsVestingVault',
rewardTokenAddress: '0xB9e0E753630434d7863528cc73CB7AC638a7c8ff',
rewardToken: TESTNET_TOKENS.xvs,
poolIndex: 0,
},
{
Expand All @@ -36,6 +37,7 @@ const fakeClaims: Claim[] = [
{
contract: 'rewardsDistributor',
contractAddress: '0xc0ffee254729296a45a3885639AC7E10F9d54979',
comptrollerContractAddress: '0x19Hfee254729296a45a3885639AC7E10F9d54979',
vTokenAddressesWithPendingReward: [
'0x37a0ac901578a7f05379fc43330b3d1e39d0c40c',
'0x75a10f0c415dccca275e8cdd8447d291a6b86f06',
Expand Down
2 changes: 1 addition & 1 deletion src/clients/api/mutations/claimRewards/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const claimRewards = async ({

const callData = executingInterface.encodeFunctionData('claim(address,address,uint256)', [
accountAddress,
claim.rewardTokenAddress,
claim.rewardToken.address,
claim.poolIndex,
]);

Expand Down
4 changes: 3 additions & 1 deletion src/clients/api/mutations/claimRewards/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ContractReceipt } from 'ethers';
import { ContractTypeByName } from 'packages/contracts';
import { Token } from 'types';

export interface VaiVaultClaim {
contract: 'vaiVault';
}

export interface XvsVestingVaultClaim {
contract: 'xvsVestingVault';
rewardTokenAddress: string;
rewardToken: Token;
poolIndex: number;
}

Expand All @@ -19,6 +20,7 @@ export interface MainPoolComptrollerClaim {
export interface RewardsDistributorClaim {
contract: 'rewardsDistributor';
contractAddress: string;
comptrollerContractAddress: string;
vTokenAddressesWithPendingReward: string[];
}

Expand Down
24 changes: 24 additions & 0 deletions src/clients/api/mutations/claimRewards/useClaimRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { callOrThrow } from 'utilities';

import { ClaimRewardsInput, ClaimRewardsOutput, claimRewards, queryClient } from 'clients/api';
import FunctionKey from 'constants/functionKey';
import { useAnalytics } from 'context/Analytics';
import useGetUniqueContract from 'hooks/useGetUniqueContract';
import useGetUniqueContractAddress from 'hooks/useGetUniqueContractAddress';

Expand Down Expand Up @@ -33,6 +34,8 @@ const useClaimRewards = (options?: Options) => {
name: 'xvsVault',
});

const { captureAnalyticEvent } = useAnalytics();

return useMutation(
FunctionKey.CLAIM_REWARDS,
(input: TrimmedClaimRewardsInput) =>
Expand All @@ -52,6 +55,27 @@ const useClaimRewards = (options?: Options) => {
{
...options,
onSuccess: (_data, variables) => {
variables.claims.forEach(claim => {
if (claim.contract === 'mainPoolComptroller') {
captureAnalyticEvent('Pool reward claimed', {
comptrollerAddress: mainPoolComptrollerContractAddress!,
vTokenAddressesWithPendingReward: claim.vTokenAddressesWithPendingReward,
});
} else if (claim.contract === 'rewardsDistributor') {
captureAnalyticEvent('Pool reward claimed', {
comptrollerAddress: claim.comptrollerContractAddress,
vTokenAddressesWithPendingReward: claim.vTokenAddressesWithPendingReward,
});
} else if (claim.contract === 'vaiVault') {
captureAnalyticEvent('VAI vault reward claimed', undefined);
} else if (claim.contract === 'xvsVestingVault') {
captureAnalyticEvent('XVS vesting vault reward claimed', {
poolIndex: claim.poolIndex,
rewardTokenSymbol: claim.rewardToken.symbol,
});
}
});

queryClient.invalidateQueries([FunctionKey.GET_PENDING_REWARDS, variables.accountAddress]);
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { checkForComptrollerTransactionError } from 'errors';
import { ContractTypeByName } from 'packages/contracts';

import fakeContractReceipt from '__mocks__/models/contractReceipt';
import { TESTNET_VBEP_TOKENS } from 'constants/tokens';

import enterMarkets from '.';
import enterMarket from '.';

vi.mock('errors/transactionErrors');

describe('api/mutation/enterMarkets', () => {
describe('api/mutation/enterMarket', () => {
test('returns contract receipt when request succeeds', async () => {
const vTokenAddresses = ['0x3d759121234cd36F8124C21aFe1c6852d2bEd848'];
const vToken = TESTNET_VBEP_TOKENS['0x08e0a5575de71037ae36abfafb516595fe68e5e4'];

const waitMock = vi.fn(async () => fakeContractReceipt);
const enterMarketsMock = vi.fn(() => ({
Expand All @@ -20,14 +21,14 @@ describe('api/mutation/enterMarkets', () => {
enterMarkets: enterMarketsMock,
} as unknown as ContractTypeByName<'mainPoolComptroller'>;

const response = await enterMarkets({
const response = await enterMarket({
comptrollerContract: fakeContract,
vTokenAddresses,
vToken,
});

expect(response).toBe(fakeContractReceipt);
expect(enterMarketsMock).toHaveBeenCalledTimes(1);
expect(enterMarketsMock).toHaveBeenCalledWith(vTokenAddresses);
expect(enterMarketsMock).toHaveBeenCalledWith([vToken.address]);
expect(waitMock).toBeCalledTimes(1);
expect(waitMock).toHaveBeenCalledWith(1);
expect(checkForComptrollerTransactionError).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { checkForComptrollerTransactionError } from 'errors';
import { ContractReceipt } from 'ethers';
import { ContractTypeByName } from 'packages/contracts';
import { VToken } from 'types';

export interface EnterMarketsInput {
export interface EnterMarketInput {
comptrollerContract: ContractTypeByName<'mainPoolComptroller' | 'isolatedPoolComptroller'>;
vTokenAddresses: string[];
vToken: VToken;
}

export type EnterMarketsOutput = ContractReceipt;
export type EnterMarketOutput = ContractReceipt;

const enterMarkets = async ({
const enterMarket = async ({
comptrollerContract,
vTokenAddresses,
}: EnterMarketsInput): Promise<EnterMarketsOutput> => {
const transaction = await comptrollerContract.enterMarkets(vTokenAddresses);
vToken,
}: EnterMarketInput): Promise<EnterMarketOutput> => {
const transaction = await comptrollerContract.enterMarkets([vToken.address]);
const receipt = await transaction.wait(1);
return checkForComptrollerTransactionError(receipt);
};

export default enterMarkets;
export default enterMarket;
42 changes: 42 additions & 0 deletions src/clients/api/mutations/enterMarket/useEnterMarket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import BigNumber from 'bignumber.js';
import { MutationObserverOptions, useMutation } from 'react-query';

import { EnterMarketInput, EnterMarketOutput, enterMarket, queryClient } from 'clients/api';
import FunctionKey from 'constants/functionKey';
import { useAnalytics } from 'context/Analytics';

const useEnterMarket = (
options?: MutationObserverOptions<EnterMarketOutput, Error, EnterMarketInput>,
) => {
const { captureAnalyticEvent } = useAnalytics();

const wrappedEnterMarket: (
input: EnterMarketInput & {
// These properties will be used for analytic purposes only
poolName: string;
userSupplyBalanceTokens: BigNumber;
},
) => Promise<EnterMarketOutput> = enterMarket;

return useMutation(FunctionKey.ENTER_MARKET, wrappedEnterMarket, {
...options,
onSuccess: (...onSuccessParams) => {
const { poolName, vToken, userSupplyBalanceTokens } = onSuccessParams[1];

captureAnalyticEvent('Tokens collateralized', {
poolName,
tokenSymbol: vToken.symbol,
userSupplyBalanceTokens: userSupplyBalanceTokens.toNumber(),
});

queryClient.invalidateQueries(FunctionKey.GET_MAIN_ASSETS_IN_ACCOUNT);
queryClient.invalidateQueries(FunctionKey.GET_ISOLATED_POOLS);

if (options?.onSuccess) {
options.onSuccess(...onSuccessParams);
}
},
});
};

export default useEnterMarket;
21 changes: 0 additions & 21 deletions src/clients/api/mutations/enterMarkets/useEnterMarkets.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from 'clients/api';
import FunctionKey from 'constants/functionKey';
import { TOKENS } from 'constants/tokens';
import { useAnalytics } from 'context/Analytics';
import useGetUniqueContract from 'hooks/useGetUniqueContract';

type TrimmedExecuteWithdrawalFromXvsVaultInput = Omit<
Expand All @@ -29,6 +30,7 @@ const useExecuteWithdrawalFromXvsVault = (
const xvsVaultContract = useGetUniqueContract({
name: 'xvsVault',
});
const { captureAnalyticEvent } = useAnalytics();

return useMutation(
FunctionKey.REQUEST_WITHDRAWAL_FROM_XVS_VAULT,
Expand All @@ -43,6 +45,12 @@ const useExecuteWithdrawalFromXvsVault = (
...options,
onSuccess: async (...onSuccessParams) => {
const { poolIndex } = onSuccessParams[1];

captureAnalyticEvent('Token withdrawals executed from XVS vault', {
poolIndex,
rewardTokenSymbol: TOKENS.xvs.symbol,
});

const accountAddress = await xvsVaultContract?.signer.getAddress();

// Invalidate cached user info
Expand Down
7 changes: 4 additions & 3 deletions src/clients/api/mutations/exitMarket/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { checkForComptrollerTransactionError } from 'errors';
import { ContractTypeByName } from 'packages/contracts';

import fakeContractReceipt from '__mocks__/models/contractReceipt';
import { TESTNET_VBEP_TOKENS } from 'constants/tokens';

import exitMarket from '.';

vi.mock('errors/transactionErrors');

describe('api/mutation/exitMarket', () => {
test('returns contract receipt when request succeeds', async () => {
const vTokenAddress = '0x3d759121234cd36F8124C21aFe1c6852d2bEd848';
const vToken = TESTNET_VBEP_TOKENS['0x08e0a5575de71037ae36abfafb516595fe68e5e4'];

const waitMock = vi.fn(async () => fakeContractReceipt);
const exitMarketMock = vi.fn(() => ({
Expand All @@ -22,12 +23,12 @@ describe('api/mutation/exitMarket', () => {

const response = await exitMarket({
comptrollerContract: fakeContract,
vTokenAddress,
vToken,
});

expect(response).toBe(fakeContractReceipt);
expect(exitMarketMock).toHaveBeenCalledTimes(1);
expect(exitMarketMock).toHaveBeenCalledWith(vTokenAddress);
expect(exitMarketMock).toHaveBeenCalledWith(vToken.address);
expect(waitMock).toBeCalledTimes(1);
expect(waitMock).toHaveBeenCalledWith(1);
expect(checkForComptrollerTransactionError).toHaveBeenCalledTimes(1);
Expand Down
7 changes: 4 additions & 3 deletions src/clients/api/mutations/exitMarket/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { checkForComptrollerTransactionError } from 'errors';
import { ContractReceipt } from 'ethers';
import { ContractTypeByName } from 'packages/contracts';
import { VToken } from 'types';

export interface ExitMarketInput {
comptrollerContract: ContractTypeByName<'mainPoolComptroller' | 'isolatedPoolComptroller'>;
vTokenAddress: string;
vToken: VToken;
}

export type ExitMarketOutput = ContractReceipt;

const exitMarket = async ({
comptrollerContract,
vTokenAddress,
vToken,
}: ExitMarketInput): Promise<ExitMarketOutput> => {
const transaction = await comptrollerContract.exitMarket(vTokenAddress);
const transaction = await comptrollerContract.exitMarket(vToken.address);
const receipt = await transaction.wait(1);
return checkForComptrollerTransactionError(receipt);
};
Expand Down
Loading

0 comments on commit fa71323

Please sign in to comment.