Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Picodes committed Nov 9, 2023
1 parent 376d9bc commit 88c636d
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 13 deletions.
10 changes: 8 additions & 2 deletions src/bot/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,14 @@ export const checkHolderValidity: Step = async ({ onChainProvider }, report) =>
const { startTree, endTree } = report;
holdersReport = await validateHolders(onChainProvider, startTree, endTree);
const negativeDiffs = holdersReport.negativeDiffs;

if (negativeDiffs.length > 0) throw negativeDiffs.join('\n');
const overDistributed = holdersReport.overDistributed;

if (negativeDiffs.length > 0) {
return Result.Error({ code: BotError.NegativeDiff, reason: negativeDiffs.join('\n'), report: { ...report, holdersReport } });
}
if (overDistributed.length > 0) {
return Result.Error({ code: BotError.OverDistributed, reason: overDistributed.join('\n'), report: { ...report, holdersReport } });
}

return Result.Success({ ...report, holdersReport });
} catch (reason) {
Expand Down
28 changes: 24 additions & 4 deletions src/bot/validity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AggregatedRewardsType, Int256 } from '@angleprotocol/sdk';
import { BigNumber } from 'ethers';

import { HOUR } from '../constants';
import { round } from '../helpers';
import OnChainProvider from '../providers/on-chain/OnChainProvider';
import { DistributionChanges, HolderClaims, HolderDetail, HoldersReport, UnclaimedRewards } from '../types/holders';
Expand Down Expand Up @@ -32,14 +33,18 @@ export async function validateHolders(
endTree: AggregatedRewardsType
): Promise<HoldersReport> {
const holders = gatherHolders(startTree, endTree);
const activeDistributions = await onChainProvider.fetchActiveDistributions();
const activeDistributions = await onChainProvider.fetchActiveDistributionsBetween(
startTree.lastUpdateEpoch * HOUR,
endTree.lastUpdateEpoch * HOUR
);

const poolName = {};

const details: HolderDetail[] = [];
const changePerDistrib: DistributionChanges = {};
const unclaimed: UnclaimedRewards = {};
const negativeDiffs: string[] = [];
const overDistributed: string[] = [];

for (const holder of holders) {
unclaimed[holder] = {};
Expand Down Expand Up @@ -110,15 +115,30 @@ export async function validateHolders(
l.percent = (l?.diff / changePerDistrib[l?.distribution]?.diff) * 100;
}

return { details, changePerDistrib, unclaimed, negativeDiffs };
for (const k of Object.keys(changePerDistrib)) {
const solidityDist = activeDistributions?.find((d) => d.base.rewardId === k);

// Either the distributed amount is less than what would be distributed since the distrib start and there is no dis in the start tree
// Either it's less than what would be distributed since the startTree update
if (
(!!startTree.rewards[k]?.lastUpdateEpoch &&
changePerDistrib[k].epoch > endTree.rewards[k].lastUpdateEpoch - startTree.rewards[k].lastUpdateEpoch) ||
(!startTree.rewards[k]?.lastUpdateEpoch &&
changePerDistrib[k].epoch > endTree.rewards[k].lastUpdateEpoch - solidityDist.base.epochStart / HOUR)
) {
overDistributed.push(k);
}
}

return { details, changePerDistrib, unclaimed, negativeDiffs, overDistributed };
}

export async function validateClaims(onChainProvider: OnChainProvider, holdersReport: HoldersReport): Promise<HoldersReport> {
const { details, unclaimed } = holdersReport;
const alreadyClaimed: HolderClaims = await onChainProvider.fetchClaimed(details);

const overclaimed: string[] = [];

// Sort details by distribution and format numbers
const expandedDetails = await Promise.all(
details
Expand All @@ -128,7 +148,7 @@ export async function validateClaims(onChainProvider: OnChainProvider, holdersRe
.map(async (d) => {
const alreadyClaimedValue = round(Int256.from(alreadyClaimed[d.holder][d.tokenAddress], d.decimals).toNumber(), 2);
const totalCumulated = round(unclaimed[d.holder][d.symbol].toNumber(), 2);

if (totalCumulated < alreadyClaimedValue) {
overclaimed.push(`${d.holder}: ${alreadyClaimedValue} / ${totalCumulated} ${d.symbol}`);
}
Expand Down
15 changes: 8 additions & 7 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const buildMerklTree = (
/**
* 3 - Build the tree
*/
const elements = [];
const leaves = [];
for (const u of users) {
for (const t of tokens) {
let sum = BigNumber.from(0);
Expand All @@ -108,14 +108,15 @@ export const buildMerklTree = (
sum = sum?.add(distribution?.holders[u]?.amount.toString() ?? 0);
}
}
const hash = ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(['address', 'address', 'uint256'], [utils.getAddress(u), t, sum])
);

elements.push(hash);
if (!!sum && sum.gt(0)) {
const hash = ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(['address', 'address', 'uint256'], [utils.getAddress(u), t, sum])
);
leaves.push(hash);
}
}
}
const tree = new MerkleTree(elements, keccak256, { hashLeaves: false, sortPairs: true, sortLeaves: false });
const tree = new MerkleTree(leaves, keccak256, { hashLeaves: false, sortPairs: true, sortLeaves: false });

return {
tokens,
Expand Down
5 changes: 5 additions & 0 deletions src/providers/on-chain/OnChainProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default abstract class OnChainProvider extends ExponentialBackoffProvider
protected abstract onChainParams: () => Promise<OnChainParams>;
protected abstract timestampAt: (blockNumber: number) => Promise<number>;
protected abstract activeDistributions: () => Promise<ExtensiveDistributionParametersStructOutput[]>;
protected abstract activeDistributionsBetween: (start: number, end: number) => Promise<ExtensiveDistributionParametersStructOutput[]>;
protected abstract poolName: (pool: string, amm: AMMType) => Promise<string>;
protected abstract claimed: (holderDetails: HolderDetail[]) => Promise<HolderClaims>;
protected abstract approve: (
Expand Down Expand Up @@ -73,6 +74,10 @@ export default abstract class OnChainProvider extends ExponentialBackoffProvider
return this.retryWithExponentialBackoff(this.activeDistributions, this.fetchParams);
}

async fetchActiveDistributionsBetween(start: number, end: number): Promise<ExtensiveDistributionParametersStructOutput[]> {
return this.retryWithExponentialBackoff(this.activeDistributionsBetween, this.fetchParams, start, end);
}

async fetchOnChainParams(): Promise<OnChainParams> {
return this.retryWithExponentialBackoff(this.onChainParams, this.fetchParams);
}
Expand Down
6 changes: 6 additions & 0 deletions src/providers/on-chain/RpcProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ export default class RpcProvider extends OnChainProvider {
return instance.getActiveDistributions({ blockTag: this.blockNumber });
};

override activeDistributionsBetween = async (start: number, end: number) => {
const instance = DistributionCreator__factory.connect(this.distributorCreator, this.provider);

return instance.getDistributionsBetweenEpochs(start, end, { blockTag: this.blockNumber });
};

override poolName = async (pool: string, amm: AMMType) => {
const multicall = Multicall__factory.connect('0xcA11bde05977b3631167028862bE2a173976CA11', this.provider);
const poolInterface = PoolInterface(AMMAlgorithmMapping[amm]);
Expand Down
1 change: 1 addition & 0 deletions src/types/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export enum BotError {
TreeFetch,
TreeRoot,
NegativeDiff,
OverDistributed,
AlreadyClaimed,
KeeperCreate,
KeeperApprove,
Expand Down
1 change: 1 addition & 0 deletions src/types/holders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ export type HoldersReport = {
unclaimed: UnclaimedRewards;
negativeDiffs: string[];
overclaimed?: string[];
overDistributed?: string[];
};
6 changes: 6 additions & 0 deletions tests/helpers/ManualChainProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import { HolderClaims } from '../../src/types/holders';
export default class ManualChainProvider extends OnChainProvider {
claimedCall: () => HolderClaims;
activeDistributionCall: () => ExtensiveDistributionParametersStructOutput[];
activeDistributionsBetweenCall: (start: number, end: number) => ExtensiveDistributionParametersStructOutput[];
poolNameCall: () => string;

constructor(
activeDistributionCall: () => ExtensiveDistributionParametersStructOutput[],
activeDistributionsBetweenCall: () => ExtensiveDistributionParametersStructOutput[],
claimedCall: () => HolderClaims,
poolNameCall: () => string
) {
Expand All @@ -24,6 +26,10 @@ export default class ManualChainProvider extends OnChainProvider {
return this?.activeDistributionCall();
};

override activeDistributionsBetween = async (start: number, end: number) => {
return this?.activeDistributionsBetweenCall(start, end);
};

override claimed = async () => {
return this?.claimedCall();
};
Expand Down

0 comments on commit 88c636d

Please sign in to comment.