Skip to content

Instantly share code, notes, and snippets.

@0xCLARITY
Created March 18, 2024 19:37
Show Gist options
  • Save 0xCLARITY/f594bf564683d8b9e30170ffefd1773a to your computer and use it in GitHub Desktop.
Save 0xCLARITY/f594bf564683d8b9e30170ffefd1773a to your computer and use it in GitHub Desktop.
Simulate LDA Royalty Claiming
import { encodeFunctionData } from "viem";
import { decodeEventLog } from "viem";
import { numberToHex, bytesToHex, hexToBytes } from "viem";
// This is The ABI for the Royalties contract used for Payouts
import abi from "./royalties";
// Wallet address here is an example - but royalties contract is the actual address.
const walletAddress = "0x0bc119a37d1d2817f4f2721b282a548018ecb980";
const royaltiesContract = "0xfe16ee78828672e86cf8e42d8a5119ab79877ec7";
// Every LDA TierID that has ever been issued:
const tierIds = [
3, 4, 5, 6, 7, 8, 24, 25, 26, 27, 28, 29, 33, 34, 35, 36, 37, 38, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64,
65, 66, 157, 190, 223, 224, 256, 257, 289, 290, 291, 322, 323, 324, 325, 326,
327, 328, 355, 356, 388, 421, 454, 487, 520, 553, 554, 555, 586, 587, 619,
620, 652, 685, 686, 687, 718, 751, 752, 753, 784, 785, 786, 787, 788, 817,
818, 819, 820, 821, 822, 823, 883, 884, 885, 916, 917, 918, 949, 982, 983,
1147, 1248, 1312, 1479, 1480, 1590, 1807,
];
const tierIdBigInts = tierIds.map((id) => BigInt(id));
const data = encodeFunctionData({
abi,
functionName: "claim",
// arg types: [address claimer, uint128[] tierIds, address recipient]
args: [walletAddress, tierIdBigInts, walletAddress],
});
const options = {
method: "POST",
headers: { accept: "application/json", "content-type": "application/json" },
body: JSON.stringify({
id: 1,
jsonrpc: "2.0",
method: "alchemy_simulateExecution",
params: [
{
from: walletAddress,
to: royaltiesContract,
value: "0x0",
data,
},
],
}),
};
// Ask Alchemy to simulate a transaction where we attempt to claim royalties for _every_ tierID in existence.
const ALCHEMY_API_KEY = "";
fetch(`https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, options)
.then(async (response) => {
const data = await response.json();
// Filter logs to only include logs from the Royalties contract
const filteredLogs = data?.result?.logs?.filter(
(log: any) => log.address === royaltiesContract
);
if (filteredLogs) {
const decodedLogs = filteredLogs.map((log: any) => {
const topics = log.topics;
topics[1] = numberToHex(topics[1], { size: 32 });
topics[2] = bytesToHex(hexToBytes(topics[2]), { size: 32 });
topics[3] = bytesToHex(hexToBytes(topics[3]), { size: 32 });
return decodeEventLog({ abi, data: log.data, topics: log.topics });
});
// Filter out logs where the amount is 0 (no royalties to claim for that tierID)
const nonZeroAmountLogs = decodedLogs.filter(
(log: any) => log.args.amount > 0n
);
console.log(nonZeroAmountLogs);
// Sum up the total amount of royalties to claim
const totalAmount = nonZeroAmountLogs.reduce(
(acc: bigint, log: any) => acc + log.args.amount,
0n
);
console.log(`totalAmount: ${totalAmount}`);
}
})
.then((response) => console.log(response))
.catch((err) => console.error(err));
// ABI for the Royalties contract used for Payouts
const abi = [
{
inputs: [
{ internalType: "address", name: "lda", type: "address" },
{ internalType: "address", name: "paymentErc20", type: "address" },
{ internalType: "uint256", name: "claimPeriodSeconds", type: "uint256" },
],
stateMutability: "nonpayable",
type: "constructor",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "uint256",
name: "tierId",
type: "uint256",
},
{
indexed: true,
internalType: "address",
name: "claimer",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "recipient",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "lastDepositId",
type: "uint256",
},
{
indexed: false,
internalType: "uint256",
name: "amount",
type: "uint256",
},
],
name: "Claimed",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "uint256",
name: "tierId",
type: "uint256",
},
{
indexed: true,
internalType: "uint256",
name: "depositId",
type: "uint256",
},
{
indexed: true,
internalType: "address",
name: "depositor",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "amount",
type: "uint256",
},
],
name: "Deposited",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "uint256",
name: "tierId",
type: "uint256",
},
{
indexed: false,
internalType: "uint256",
name: "lastExpiredDepositId",
type: "uint256",
},
],
name: "DepositsExpired",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "uint256",
name: "tierId",
type: "uint256",
},
{
indexed: true,
internalType: "address",
name: "claimer",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "lastExpiredDepositId",
type: "uint256",
},
],
name: "DepositsReclaimable",
type: "event",
},
{
anonymous: false,
inputs: [
{ indexed: false, internalType: "uint8", name: "version", type: "uint8" },
],
name: "Initialized",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "previousOwner",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "newOwner",
type: "address",
},
],
name: "OwnershipTransferred",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "account",
type: "address",
},
],
name: "Paused",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "uint256",
name: "tierId",
type: "uint256",
},
{
indexed: true,
internalType: "address",
name: "recipient",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "amount",
type: "uint256",
},
],
name: "Reclaimed",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "uint256",
name: "tierId",
type: "uint256",
},
{
indexed: false,
internalType: "uint256",
name: "supply",
type: "uint256",
},
{
indexed: false,
internalType: "address",
name: "reclaimer",
type: "address",
},
],
name: "TierConfigured",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "account",
type: "address",
},
],
name: "Unpaused",
type: "event",
},
{
inputs: [],
name: "CLAIM_PERIOD_S",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "LDA",
outputs: [
{ internalType: "contract IRoyal1155LDA", name: "", type: "address" },
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "PAYMENT_ERC20",
outputs: [
{ internalType: "contract IERC20Upgradeable", name: "", type: "address" },
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "PRO_RATA_BASE",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "from", type: "address" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint128", name: "tierId", type: "uint128" },
],
name: "beforeLdaTransfer",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "cancelNonce",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "claimer", type: "address" },
{ internalType: "uint128[]", name: "tierIds", type: "uint128[]" },
{ internalType: "address", name: "recipient", type: "address" },
],
name: "claim",
outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "claimer", type: "address" },
{ internalType: "uint128[]", name: "tierIds", type: "uint128[]" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "claimWithSig",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "depositor", type: "address" },
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "uint256", name: "amount", type: "uint256" },
],
name: "deposit",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "depositor", type: "address" },
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "depositWithSig",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "uint256", name: "expiredDepositId", type: "uint256" },
],
name: "expireDeposits",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "address", name: "account", type: "address" },
],
name: "findYUcrId",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "uint256", name: "depositId", type: "uint256" },
],
name: "getDeposit",
outputs: [
{
components: [
{ internalType: "uint128", name: "amount", type: "uint128" },
{ internalType: "uint128", name: "timestamp", type: "uint128" },
],
internalType: "struct IRoyalties.Deposit",
name: "",
type: "tuple",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "getMinimumDepositAmount",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [{ internalType: "uint128", name: "tierId", type: "uint128" }],
name: "getNumDeposits",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [{ internalType: "uint128", name: "tierId", type: "uint128" }],
name: "getNumExpiredDeposits",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [{ internalType: "uint128", name: "tierId", type: "uint128" }],
name: "getTierInfo",
outputs: [
{
components: [
{ internalType: "uint256", name: "supply", type: "uint256" },
{ internalType: "address", name: "reclaimer", type: "address" },
],
internalType: "struct IRoyalties.TierInfo",
name: "",
type: "tuple",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "initialize",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "address", name: "reclaimer", type: "address" },
],
name: "initializeTier",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [{ internalType: "uint128", name: "tierId", type: "uint128" }],
name: "isTierInitialized",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function",
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "nonces",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "owner",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "pause",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "paused",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "uint128[]", name: "tierIds", type: "uint128[]" },
{ internalType: "address", name: "recipient", type: "address" },
],
name: "reclaim",
outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "reclaimer", type: "address" },
{ internalType: "uint128[]", name: "tierIds", type: "uint128[]" },
{ internalType: "address", name: "recipient", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "reclaimWithSig",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "renounceOwnership",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "uint256",
name: "minimumDepositAmount",
type: "uint256",
},
],
name: "setMinimumDepositAmount",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "address[]", name: "accounts", type: "address[]" },
],
name: "settleExpiredRoyalties",
outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [{ internalType: "address", name: "newOwner", type: "address" }],
name: "transferOwnership",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "unpause",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint128", name: "tierId", type: "uint128" },
{ internalType: "address", name: "reclaimer", type: "address" },
],
name: "updateTier",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
] as const;
export default abi;
@FocusBT
Copy link

FocusBT commented Nov 17, 2024

Hey there, I just wanted to ask if you’ve tried using any functions that require an allowance or permissions, and how you handle them with state_override?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment