@parifi/sdk
Version:
Parifi SDK with common utility functions
348 lines (345 loc) • 11.3 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/distribution/index.ts
var distribution_exports = {};
__export(distribution_exports, {
RewardDistribution: () => RewardDistribution
});
module.exports = __toCommonJS(distribution_exports);
var import_merkle_tree = require("@openzeppelin/merkle-tree");
var import_viem = require("viem");
// src/common/constants.ts
var import_decimal = require("decimal.js");
var PRECISION_MULTIPLIER = new import_decimal.Decimal("10000");
var DEVIATION_PRECISION_MULTIPLIER = new import_decimal.Decimal(10).pow(12);
var SECONDS_IN_A_YEAR = new import_decimal.Decimal(365 * 24 * 60 * 60);
var MAX_FEE = new import_decimal.Decimal(1e7);
var WAD = new import_decimal.Decimal(10).pow(18);
var DECIMAL_10 = new import_decimal.Decimal(10);
var DECIMAL_ZERO = new import_decimal.Decimal(0);
var BIGINT_ZERO = BigInt(0);
var ONE_GWEI = 1e9;
var DEFAULT_GAS_PRICE = 2 * ONE_GWEI;
var REWARD_DISTRIBUTOR_ADDRESSES = {
[8453 /* BASE */]: {
esprf: "0x6511718804180CC57833fEA036389A24604Dfc69",
prf: "0x0000000000000000000000000000000000000000",
rt: "0x648d6D711860699A11aBa192E9daBAfb6408af18"
}
};
var REWARD_DISTRIBUTOR_ABI = [
{
inputs: [{ internalType: "contract IERC20", name: "_rewardToken", type: "address" }],
stateMutability: "nonpayable",
type: "constructor"
},
{ inputs: [], name: "AccessControlBadConfirmation", type: "error" },
{
inputs: [
{ internalType: "address", name: "account", type: "address" },
{ internalType: "bytes32", name: "neededRole", type: "bytes32" }
],
name: "AccessControlUnauthorizedAccount",
type: "error"
},
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "address", name: "user", type: "address" },
{ indexed: false, internalType: "uint256", name: "amount", type: "uint256" }
],
name: "RewardClaimed",
type: "event"
},
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "bytes32", name: "role", type: "bytes32" },
{ indexed: true, internalType: "bytes32", name: "previousAdminRole", type: "bytes32" },
{ indexed: true, internalType: "bytes32", name: "newAdminRole", type: "bytes32" }
],
name: "RoleAdminChanged",
type: "event"
},
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "bytes32", name: "role", type: "bytes32" },
{ indexed: true, internalType: "address", name: "account", type: "address" },
{ indexed: true, internalType: "address", name: "sender", type: "address" }
],
name: "RoleGranted",
type: "event"
},
{
anonymous: false,
inputs: [
{ indexed: true, internalType: "bytes32", name: "role", type: "bytes32" },
{ indexed: true, internalType: "address", name: "account", type: "address" },
{ indexed: true, internalType: "address", name: "sender", type: "address" }
],
name: "RoleRevoked",
type: "event"
},
{
inputs: [],
name: "DEFAULT_ADMIN_ROLE",
outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "actualRound",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "uint256", name: "_round", type: "uint256" },
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "bytes32[]", name: "proof", type: "bytes32[]" }
],
name: "claimReward",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "uint256[]", name: "_rounds", type: "uint256[]" },
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
{ internalType: "bytes32[][]", name: "proofs", type: "bytes32[][]" }
],
name: "claimRewards",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "uint256", name: "", type: "uint256" },
{ internalType: "address", name: "", type: "address" }
],
name: "claimed",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "bytes32", name: "role", type: "bytes32" }],
name: "getRoleAdmin",
outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "bytes32", name: "role", type: "bytes32" },
{ internalType: "address", name: "account", type: "address" }
],
name: "grantRole",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "bytes32", name: "role", type: "bytes32" },
{ internalType: "address", name: "account", type: "address" }
],
name: "hasRole",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "bytes32", name: "role", type: "bytes32" },
{ internalType: "address", name: "callerConfirmation", type: "address" }
],
name: "renounceRole",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "bytes32", name: "role", type: "bytes32" },
{ internalType: "address", name: "account", type: "address" }
],
name: "revokeRole",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [],
name: "rewardToken",
outputs: [{ internalType: "contract IERC20", name: "", type: "address" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "uint256", name: "_round", type: "uint256" }],
name: "setActualRound",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "uint256", name: "_round", type: "uint256" },
{ internalType: "bytes32", name: "_root", type: "bytes32" }
],
name: "setRootPerRound",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [{ internalType: "bytes4", name: "interfaceId", type: "bytes4" }],
name: "supportsInterface",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "uint256", name: "", type: "uint256" }],
name: "verifiersPerRound",
outputs: [{ internalType: "contract Verifier", name: "", type: "address" }],
stateMutability: "view",
type: "function"
}
];
// src/distribution/index.ts
var RewardDistribution = class {
constructor(_rewards) {
this.rewards = _rewards || {};
}
/**
* Sets the reward list.
* @param rewards The reward list to set.
*/
setRewardList(rewards) {
this.rewards = rewards;
}
/**
* Gets the reward contract address and ABI for a specific token.
* @param tokenSymbol The symbol of the token.
* @returns The reward contract address and ABI.
*/
async getRewardContract(tokenSymbol) {
tokenSymbol = tokenSymbol.toLowerCase();
const rewardContract = REWARD_DISTRIBUTOR_ADDRESSES[8453 /* BASE */][tokenSymbol];
if (!rewardContract) {
throw new Error(`No reward contract found for token ${tokenSymbol}`);
}
return {
address: rewardContract,
abi: REWARD_DISTRIBUTOR_ABI
};
}
/**
* Gets the Merkle tree for a specific token and round.
* @param tokenSymbol The symbol of the token.
* @param round The round number.
* @returns The Merkle tree for the specified token and round.
*/
async getTree(tokenSymbol, round) {
tokenSymbol = tokenSymbol.toLowerCase();
const treeData = this.rewards?.[tokenSymbol]?.[round];
if (!treeData) {
throw new Error(`No rewards found for token ${tokenSymbol}`);
}
const tree = import_merkle_tree.StandardMerkleTree.of(
treeData.map((u) => [u.address, u.amount]),
["address", "uint256"]
);
return tree;
}
async getUserData(user, tokenSymbol, round) {
const tree = await this.getTree(tokenSymbol, round);
const indexOf = tree.dump().values.findIndex((data) => data.value.at(0)?.toLowerCase() === user.toLowerCase());
const userData = tree.dump().values.find((data) => data.value.at(0)?.toLowerCase() === user.toLowerCase())?.value?.reduce(
(acc, curr, index) => {
const keys = ["address", "amount"];
const key = keys[index];
if (!key) return acc;
acc[key] = curr;
return acc;
},
{}
);
return { userData, indexOf, tree };
}
/**
* Claims rewards for a user in multiple rounds.
* @param user The address of the user.
* @param rounds The array of round numbers.
* @param tokenSymbol The symbol of the token.
* @returns An array of transactions to be sent.
*/
async claimRewards({ user, rounds, tokenSymbol }) {
const txs = [];
for (const round of rounds) {
try {
const tx = await this.claimReward({ user, round, tokenSymbol });
txs.push(tx);
} catch (error) {
console.error(`Error claiming rewards for ${user} in round ${round}:`, error);
}
}
return txs.flat();
}
/**
* Claims the reward for a user in a specific round.
* @param user The address of the user.
* @param round The round number.
* @param tokenSymbol The symbol of the token.
* @returns An array of transactions to be sent.
*/
async claimReward({ user, round, tokenSymbol }) {
tokenSymbol = tokenSymbol.toLowerCase();
const { userData, indexOf, tree } = await this.getUserData(user, tokenSymbol, round);
if (!userData || !userData?.address) throw new Error(`User ${user} not found in the tree`);
const proof = tree.getProof(indexOf);
const distributor = await this.getRewardContract(tokenSymbol);
return [
{
tx: {
to: distributor.address,
data: (0, import_viem.encodeFunctionData)({
abi: distributor.abi,
functionName: "claimReward",
args: [round, userData.amount, proof]
}),
value: "0"
},
amount: userData.amount
}
];
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
RewardDistribution
});
//# sourceMappingURL=index.js.map