UNPKG

@parifi/sdk

Version:

Parifi SDK with common utility functions

348 lines (345 loc) 11.3 kB
"use strict"; 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