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

fix(vapordex): incorrect startblock and make address lowercase DEV-723 #8

Merged
merged 14 commits into from
Jun 28, 2024
Merged
15 changes: 9 additions & 6 deletions ponder.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ export default createConfig({
abi: DexAggregatorAbi,
network: {
avalanche: {
address: addresses.DexAggregator?.avalanche,
startBlock: 42346292,
address: [
addresses.DexAggregator?.avalanche!,
addresses.DexAggregatorV2?.avalanche!,
],
startBlock: 43508160,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The startBlock value needs updating in one instance

The startBlock value of 43508160 is consistent across all instances in the ponder.config.ts file, except for one line that includes a TODO comment indicating it needs to be updated.

  • ponder.config.ts: startBlock: 43508160, // TODO: Update this

Please ensure this startBlock value is updated as per the required configuration.

Analysis chain

Ensure the updated startBlock value is correct and consistent across all contracts.

Also applies to: 46-46, 57-57, 68-68, 79-79

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the updated startBlock values in the configuration file.

# Test: Search for the startBlock definition. Expect: The startBlock should match 43508160.
rg --type ts 'startBlock' | rg '43508160'

Length of output: 305



Script:

#!/bin/bash
# Description: Verify if there are any other `startBlock` values in the configuration file that might indicate inconsistencies or pending updates.

# Test: Search for all instances of `startBlock` in the configuration file.
rg --type ts 'startBlock'

Length of output: 291

maxBlockRange,
},
},
Expand All @@ -40,7 +43,7 @@ export default createConfig({
network: {
avalanche: {
address: addresses.Stratosphere?.avalanche,
startBlock: 20310567,
startBlock: 43508160,
maxBlockRange,
},
},
Expand All @@ -51,7 +54,7 @@ export default createConfig({
network: {
avalanche: {
address: addresses.LiquidMining?.avalanche,
startBlock: 32271032,
startBlock: 43508160,
maxBlockRange,
},
},
Expand All @@ -62,7 +65,7 @@ export default createConfig({
network: {
avalanche: {
address: addresses.VapeStaking?.avalanche,
startBlock: 32271032,
startBlock: 43508160,
maxBlockRange,
},
},
Expand All @@ -73,7 +76,7 @@ export default createConfig({
network: {
avalanche: {
address: addresses.RewardsController?.avalanche,
startBlock: 43805790, // TODO: Update this
startBlock: 43508160, // TODO: Update this
maxBlockRange,
},
},
Expand Down
8 changes: 8 additions & 0 deletions ponder.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ const generateLMSeasonEnum = (numSeasons: number) => {
*/
const pointsSource = [
"stratosphere_enrollment",
"chain_first_wallet",
"dex_aggregator_swap",
"dex_aggregator_first_swap",
"dex_aggregator_1k_swaps",
"dex_aggregator_10k_swaps",
"dex_aggregator_100k_swaps",
Expand Down Expand Up @@ -85,12 +87,16 @@ export default createSchema((p) => ({
chainId: p.int(),
LMSeasons: p.bigint().list(), // If the array is empty, the user has not participated in any season
depositInVS: p.boolean(),
chainFirstWallet: p.boolean(),
firstWalletInVPNDLM: p.boolean(),
firstWalletInVAPELM: p.boolean(),
LMOneSeasonPointsClaimed: p.boolean(),
LMThreeSeasonsPointsClaimed: p.boolean(),
LMSixSeasonsPointsClaimed: p.boolean(),
LMOneYearPointsClaimed: p.boolean(),
usdValueOfSwaps: p.bigint(),
swaps: p.bigint(),
firstSwap: p.boolean(),
first1kSwaps: p.boolean(),
first10kSwaps: p.boolean(),
first100kSwaps: p.boolean(),
Expand All @@ -104,6 +110,8 @@ export default createSchema((p) => ({
chainId: p.int(),
}),

AllProtocols: p.createTable({ id: p.string(), firstWallet: p.string() }),

// @dev: Id is the seasonId
LiquidMining: p.createTable({
id: p.bigint(),
Expand Down
3 changes: 3 additions & 0 deletions src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ export const addresses: AddressMap = {
DexAggregator: {
[Chains.AVALANCHE]: "0xDef9ee39FD82ee57a1b789Bc877E2Cbd88fd5caE",
},
DexAggregatorV2: {
[Chains.AVALANCHE]: "0x55477d8537ede381784b448876AfAa98aa450E63",
},
LiquidMining: {
[Chains.AVALANCHE]: "0xAe950fdd0CC79DDE64d3Fffd40fabec3f7ba368B",
},
Expand Down
49 changes: 46 additions & 3 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
BIGINT_ONE,
BIGINT_ZERO,
deployedBlockTimestamps,
pointsMap,
} from "./config/constants";
import axios from "axios";

Expand Down Expand Up @@ -57,6 +58,40 @@ export function getMonthlyID(
return monthlyID + 1n;
}

export const handleChainFirstWallet = async (
context: Context,
chainId: number,
userAddressLowerCase: string,
userData: any,
event: any
): Promise<UserHistory> => {
const { AllProtocols, UserHistory, Points } = context.db;
let allProtocols = await AllProtocols.findUnique({ id: "protocols" });
if (!allProtocols) {
allProtocols = await AllProtocols.create({
id: "protocols",
data: { firstWallet: userAddressLowerCase },
});
await Points.create({
id: `${userAddressLowerCase}-chain-first-wallet`,
data: {
userDataId: `${userAddressLowerCase}-${chainId}`,
userHistoryId: `${userAddressLowerCase}-${chainId}`,
pointsSource: "chain_first_wallet",
points: pointsMap.ChainFirstWallet,
chainId: chainId,
timestamp: event?.block?.timestamp,
},
});

userData = await UserHistory.update({
id: `${userAddressLowerCase}-${chainId}`,
data: { chainFirstWallet: true },
});
}
return userData;
};
Comment on lines +61 to +93
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for database operations.

The function handleChainFirstWallet does not handle potential errors that might occur during database operations. This could lead to unhandled exceptions and potential data inconsistencies.

+ try {
    let allProtocols = await AllProtocols.findUnique({ id: "protocols" });
    if (!allProtocols) {
      allProtocols = await AllProtocols.create({
        id: "protocols",
        data: { firstWallet: userAddressLowerCase },
      });
      await Points.create({
        id: `${userAddressLowerCase}-chain-first-wallet`,
        data: {
          userDataId: `${userAddressLowerCase}-${chainId}`,
          userHistoryId: `${userAddressLowerCase}-${chainId}`,
          pointsSource: "chain_first_wallet",
          points: pointsMap.ChainFirstWallet,
          chainId: chainId,
          timestamp: event?.block?.timestamp,
        },
      });
      userData = await UserHistory.update({
        id: `${userAddressLowerCase}-${chainId}`,
        data: { chainFirstWallet: true },
      });
    }
  } catch (error) {
    console.error("Error handling chain first wallet:", error);
    throw new Error("Failed to handle chain first wallet");
  }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
export const handleChainFirstWallet = async (
context: Context,
chainId: number,
userAddressLowerCase: string,
userData: any,
event: any
): Promise<UserHistory> => {
const { AllProtocols, UserHistory, Points } = context.db;
let allProtocols = await AllProtocols.findUnique({ id: "protocols" });
if (!allProtocols) {
allProtocols = await AllProtocols.create({
id: "protocols",
data: { firstWallet: userAddressLowerCase },
});
await Points.create({
id: `${userAddressLowerCase}-chain-first-wallet`,
data: {
userDataId: `${userAddressLowerCase}-${chainId}`,
userHistoryId: `${userAddressLowerCase}-${chainId}`,
pointsSource: "chain_first_wallet",
points: pointsMap.ChainFirstWallet,
chainId: chainId,
timestamp: event?.block?.timestamp,
},
});
userData = await UserHistory.update({
id: `${userAddressLowerCase}-${chainId}`,
data: { chainFirstWallet: true },
});
}
return userData;
};
export const handleChainFirstWallet = async (
context: Context,
chainId: number,
userAddressLowerCase: string,
userData: any,
event: any
): Promise<UserHistory> => {
const { AllProtocols, UserHistory, Points } = context.db;
try {
let allProtocols = await AllProtocols.findUnique({ id: "protocols" });
if (!allProtocols) {
allProtocols = await AllProtocols.create({
id: "protocols",
data: { firstWallet: userAddressLowerCase },
});
await Points.create({
id: `${userAddressLowerCase}-chain-first-wallet`,
data: {
userDataId: `${userAddressLowerCase}-${chainId}`,
userHistoryId: `${userAddressLowerCase}-${chainId}`,
pointsSource: "chain_first_wallet",
points: pointsMap.ChainFirstWallet,
chainId: chainId,
timestamp: event?.block?.timestamp,
},
});
userData = await UserHistory.update({
id: `${userAddressLowerCase}-${chainId}`,
data: { chainFirstWallet: true },
});
}
} catch (error) {
console.error("Error handling chain first wallet:", error);
throw new Error("Failed to handle chain first wallet");
}
return userData;
};


/**
* Retrieves or creates user data based on the provided parameters.
* @param context - The context object containing the database connection.
Expand Down Expand Up @@ -97,6 +132,10 @@ export async function getOrCreateUserData(
first10kSwaps: false,
first100kSwaps: false,
chainId: chainId,
firstWalletInVPNDLM: false,
firstSwap: false,
firstWalletInVAPELM: false,
chainFirstWallet: false,
Comment on lines +135 to +138
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for database operations.

The function getOrCreateUserData does not handle potential errors that might occur during database operations. This could lead to unhandled exceptions and potential data inconsistencies.

+ try {
    let userHistory = await UserHistory.findUnique({
      id: `${address}-${chainId}`,
    });

    let mainWallet = await getTokenIdOwner(tokenId, context);

    if (!userHistory) {
      userHistory = await UserHistory.create({
        id: `${address}-${chainId}`,
        data: {
          LMSeasons: [],
          depositInVS: false,
          LMOneSeasonPointsClaimed: false,
          LMThreeSeasonsPointsClaimed: false,
          LMSixSeasonsPointsClaimed: false,
          LMOneYearPointsClaimed: false,
          usdValueOfSwaps: BIGINT_ZERO,
          swaps: BIGINT_ZERO,
          first1kSwaps: false,
          first10kSwaps: false,
          first100kSwaps: false,
          chainId: chainId,
          firstWalletInVPNDLM: false,
          firstSwap: false,
          firstWalletInVAPELM: false,
          chainFirstWallet: false,
        },
      });

      await UserData.create({
        id: `${address}-${chainId}`,
        data: {
          linkedToTokenId: tokenId,
          isMainWallet: address === mainWallet,
          chainId: chainId,
        },
      });
    }
  } catch (error) {
    console.error("Error creating or retrieving user data:", error);
    throw new Error("Failed to create or retrieve user data");
  }
  return userHistory;

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
firstWalletInVPNDLM: false,
firstSwap: false,
firstWalletInVAPELM: false,
chainFirstWallet: false,
firstWalletInVPNDLM: false,
firstSwap: false,
firstWalletInVAPELM: false,
chainFirstWallet: false,

},
});

Expand All @@ -122,7 +161,8 @@ export async function getOrCreateUserData(
export async function queryQuote(
quoteParams: QueryWithAmountIn,
context: Context,
blockNumber: bigint
blockNumber: bigint,
aggregatorAddress: `0x${string}`
Comment on lines +164 to +165
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error message for better debugging.

The function queryQuote handles errors within the loop, but the error message could be more descriptive to aid in debugging.

- } catch (e) {
+ } catch (error) {
+   console.error(`Error in findBestPath: ${error.message}`, error);
    quoteParams.maxSteps -= BIGINT_ONE;
    continue;
  }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
blockNumber: bigint,
aggregatorAddress: `0x${string}`
blockNumber: bigint,
aggregatorAddress: `0x${string}`

): Promise<bigint> {
const { client, network, contracts } = context;

Expand All @@ -132,7 +172,7 @@ export async function queryQuote(
try {
quote = await client.readContract({
abi: contracts.DexAggregator.abi,
address: addresses.DexAggregator![network.name] as `0x${string}`,
address: aggregatorAddress,
functionName: "findBestPath",
args: [
quoteParams.amountIn,
Expand Down Expand Up @@ -292,7 +332,10 @@ export async function getOrUpdateTokenIdData(
const { chainId, name } = context.network;

const deployedBlockTimestamp = deployedBlockTimestamps[name].Stratosphere;
const weeklyId = `${tokenId}-${chainId}-${getWeeklyID(timestamp, deployedBlockTimestamp)}`;
const weeklyId = `${tokenId}-${chainId}-${getWeeklyID(
timestamp,
deployedBlockTimestamp
)}`;
Comment on lines +335 to +338
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for database operations.

The function getOrUpdateTokenIdData does not handle potential errors that might occur during database operations. This could lead to unhandled exceptions and potential data inconsistencies.

+ try {
    const weeklyId = `${tokenId}-${chainId}-${getWeeklyID(
      timestamp,
      deployedBlockTimestamp
    )}`;

    let tokenIdData = await TokenIdData.findUnique({
      id: `${tokenId}-${chainId}`,
    });
    let tokenIdDataWeekly = await TokenIdDataWeekly.findUnique({ id: weeklyId });

    if (!tokenIdData) {
      tokenIdData = await TokenIdData.create({
        id: `${tokenId}-${chainId}`,
        data: {
          tokenId,
          chainId,
          pointsEarned: BIGINT_ZERO,
          pointsClaimed: BIGINT_ZERO,
          pointsSpent: BIGINT_ZERO,
          lastUpdated: timestamp,
        },
      });
    }

    if (!tokenIdDataWeekly) {
      tokenIdDataWeekly = await TokenIdDataWeekly.create({
        id: weeklyId,
        data: {
          tokenId,
          chainId,
          pointsEarned: BIGINT_ZERO,
          pointsClaimed: BIGINT_ZERO,
          pointsSpent: BIGINT_ZERO,
          lastUpdated: timestamp,
        },
      });
    }

    tokenIdData = await TokenIdData.update({
      id: `${tokenId}-${chainId}`,
      data: ({ current }) => ({
        pointsEarned: current.pointsEarned + pointsEarned,
        pointsClaimed: current.pointsClaimed + pointsClaimed,
        pointsSpent: current.pointsSpent + pointsSpent,
        lastUpdated: timestamp,
      }),
    });

    tokenIdDataWeekly = await TokenIdDataWeekly.update({
      id: weeklyId,
      data: ({ current }) => ({
        pointsEarned: current.pointsEarned + pointsEarned,
        pointsClaimed: current.pointsClaimed + pointsClaimed,
        pointsSpent: current.pointsSpent + pointsSpent,
        lastUpdated: timestamp,
      }),
    });
  } catch (error) {
    console.error("Error updating token ID data:", error);
    throw new Error("Failed to update token ID data");
  }

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
const weeklyId = `${tokenId}-${chainId}-${getWeeklyID(
timestamp,
deployedBlockTimestamp
)}`;
try {
const weeklyId = `${tokenId}-${chainId}-${getWeeklyID(
timestamp,
deployedBlockTimestamp
)}`;
let tokenIdData = await TokenIdData.findUnique({
id: `${tokenId}-${chainId}`,
});
let tokenIdDataWeekly = await TokenIdDataWeekly.findUnique({ id: weeklyId });
if (!tokenIdData) {
tokenIdData = await TokenIdData.create({
id: `${tokenId}-${chainId}`,
data: {
tokenId,
chainId,
pointsEarned: BIGINT_ZERO,
pointsClaimed: BIGINT_ZERO,
pointsSpent: BIGINT_ZERO,
lastUpdated: timestamp,
},
});
}
if (!tokenIdDataWeekly) {
tokenIdDataWeekly = await TokenIdDataWeekly.create({
id: weeklyId,
data: {
tokenId,
chainId,
pointsEarned: BIGINT_ZERO,
pointsClaimed: BIGINT_ZERO,
pointsSpent: BIGINT_ZERO,
lastUpdated: timestamp,
},
});
}
tokenIdData = await TokenIdData.update({
id: `${tokenId}-${chainId}`,
data: ({ current }) => ({
pointsEarned: current.pointsEarned + pointsEarned,
pointsClaimed: current.pointsClaimed + pointsClaimed,
pointsSpent: current.pointsSpent + pointsSpent,
lastUpdated: timestamp,
}),
});
tokenIdDataWeekly = await TokenIdDataWeekly.update({
id: weeklyId,
data: ({ current }) => ({
pointsEarned: current.pointsEarned + pointsEarned,
pointsClaimed: current.pointsClaimed + pointsClaimed,
pointsSpent: current.pointsSpent + pointsSpent,
lastUpdated: timestamp,
}),
});
} catch (error) {
console.error("Error updating token ID data:", error);
throw new Error("Failed to update token ID data");
}


let tokenIdData = await TokenIdData.findUnique({
id: `${tokenId}-${chainId}`,
Expand Down
Loading