diff --git a/config.yaml b/config.yaml index b820723..95596a5 100644 --- a/config.yaml +++ b/config.yaml @@ -6,98 +6,108 @@ field_selection: - hash - transactionIndex contracts: - # - name: Hub **COMMENTED OUT FOR NOW TO SYNC FASTER*** - # handler: src/event_handlers/hubV1.ts - # events: - # - event: HubTransfer(address indexed from, address indexed to, uint256 amount) - # - event: OrganizationSignup(address indexed organization) - # - event: Signup(address indexed user, address token) - # - event: Trust(address indexed canSendTo, address indexed user, uint256 limit) - # - name: PersonalCRC - # abi_file_path: abis/PersonalCRC.json - # handler: src/event_handlers/hubV1.ts - # events: - # - event: Transfer(address indexed from, address indexed to, uint256 amount) +- name: Hub + handler: src/event_handlers/hubV1.ts + events: + - event: HubTransfer(address indexed from, address indexed to, uint256 amount) + - event: OrganizationSignup(address indexed organization) + - event: Signup(address indexed user, address token) + - event: Trust(address indexed canSendTo, address indexed user, uint256 limit) +- name: PersonalCRC + abi_file_path: abis/PersonalCRC.json + handler: src/event_handlers/hubV1.ts + events: + - event: Transfer(address indexed from, address indexed to, uint256 amount) +- name: HubV2 + handler: src/event_handlers/hubV2.ts + events: + - event: RegisterHuman(address indexed avatar, address indexed inviter) + - event: RegisterOrganization(address indexed organization, string name) + - event: RegisterGroup(address indexed group, address indexed mint, address indexed treasury, string name, string symbol) + - event: Trust(address indexed truster, address indexed trustee, uint256 expiryTime) + - event: Stopped(address indexed avatar) + - event: StreamCompleted(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts) + - event: PersonalMint(address indexed human, uint256 amount, uint256 period, uint256 endPeriod) + - event: TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value) + - event: TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values) + - event: DiscountCost(address indexed account, uint256 indexed id, uint256 discountCost) +- name: ERC20Lift + handler: src/event_handlers/hubV2.ts + events: + - event: ProxyCreation(address proxy, address masterCopy) + - event: ERC20WrapperDeployed(address indexed avatar, address indexed erc20Wrapper, uint8 circlesType) +- name: StandardTreasury + handler: src/event_handlers/treasury.ts + events: + - event: CreateVault(address indexed group, address indexed vault) + - event: GroupMintSingle(address indexed group, uint256 indexed id, uint256 value, bytes userData) + - event: GroupMintBatch(address indexed group, uint256[] ids, uint256[] values, bytes userData) + - event: GroupRedeem(address indexed group, uint256 indexed id, uint256 value, bytes data) + - event: GroupRedeemCollateralReturn(address indexed group, address indexed to, uint256[] ids, uint256[] values) + - event: GroupRedeemCollateralBurn(address indexed group, uint256[] ids, uint256[] values) +- name: CustomTreasury + handler: src/event_handlers/treasury.ts + events: + - event: CreateVault(address indexed group, address indexed vault) + - event: GroupMintSingle(address indexed group, uint256 indexed id, uint256 value, bytes userData) + - event: GroupMintBatch(address indexed group, uint256[] ids, uint256[] values, bytes userData) + - event: GroupRedeem(address indexed group, uint256 indexed id, uint256 value, bytes data) + - event: GroupRedeemCollateralReturn(address indexed group, address indexed to, uint256[] ids, uint256[] values) + - event: GroupRedeemCollateralBurn(address indexed group, uint256[] ids, uint256[] values) +- name: NameRegistry + handler: src/event_handlers/hubV2.ts + events: + - event: UpdateMetadataDigest(address indexed avatar, bytes32 metadataDigest) +- name: WrappedERC20 + handler: src/event_handlers/wrappedERC20.ts + events: + - event: Transfer(address indexed from, address indexed to, uint256 value) + - event: DepositDemurraged(address indexed account, uint256 amount, uint256 inflationaryAmount) + - event: WithdrawDemurraged(address indexed account, uint256 amount, uint256 inflationaryAmount) + - event: DepositInflationary(address indexed account, uint256 amount, uint256 demurragedAmount) + - event: WithdrawInflationary(address indexed account, uint256 amount, uint256 demurragedAmount) +- name: SafeAccount + handler: src/event_handlers/hubV2.ts + events: + - event: ExecutionSuccess(bytes32 txHash, uint256 payment) + +networks: +# - id: 10200 +# start_block: 2211707 +# contracts: +# - name: Hub +# address: +# - 0xdbF22D4e8962Db3b2F1d9Ff55be728A887e47710 +# - name: PersonalCRC +# - name: HubV2 +# address: +# - 0xb80feeDfEce647dDc709777D5094fACD157BA001 +# - name: ERC20Lift +# address: +# - 0xBD2D6Fbb6A702B04B750Bc9942fBaAE81187355E +# - name: StandardTreasury +# address: +# - 0xC06ADED7950429FdF2023e139B076f6BaFf9Fe1C +# - name: NameRegistry +# address: +# - 0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E +# - name: WrappedERC20 +- id: 100 + # start_block: 12529458 + start_block: 36486014 + contracts: - name: HubV2 - handler: src/event_handlers/hubV2.ts - events: - - event: RegisterHuman(address indexed avatar, address indexed inviter) - - event: RegisterOrganization(address indexed organization, string name) - - event: RegisterGroup(address indexed group, address indexed mint, address indexed treasury, string name, string symbol) - - event: Trust(address indexed truster, address indexed trustee, uint256 expiryTime) - - event: Stopped(address indexed avatar) - - event: StreamCompleted(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts) - - event: PersonalMint(address indexed human, uint256 amount, uint256 period, uint256 endPeriod) - - event: TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value) - - event: TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values) - - event: DiscountCost(address indexed account, uint256 indexed id, uint256 discountCost) + address: + - 0xc12C1E50ABB450d6205Ea2C3Fa861b3B834d13e8 - name: ERC20Lift - handler: src/event_handlers/hubV2.ts - events: - - event: ProxyCreation(address proxy, address masterCopy) - - event: ERC20WrapperDeployed(address indexed avatar, address indexed erc20Wrapper, uint8 circlesType) + address: + - 0x5F99a795dD2743C36D63511f0D4bc667e6d3cDB5 - name: StandardTreasury - handler: src/event_handlers/standardTreasury.ts - events: - - event: CreateVault(address indexed group, address indexed vault) - - event: GroupMintSingle(address indexed group, uint256 indexed id, uint256 value, bytes userData) - - event: GroupMintBatch(address indexed group, uint256[] ids, uint256[] values, bytes userData) - - event: GroupRedeem(address indexed group, uint256 indexed id, uint256 value, bytes data) - - event: GroupRedeemCollateralReturn(address indexed group, address indexed to, uint256[] ids, uint256[] values) - - event: GroupRedeemCollateralBurn(address indexed group, uint256[] ids, uint256[] values) + address: + - 0x08F90aB73A515308f03A718257ff9887ED330C6e - name: NameRegistry - handler: src/event_handlers/hubV2.ts - events: - - event: UpdateMetadataDigest(address indexed avatar, bytes32 metadataDigest) - - name: WrapperERC20Personal - handler: src/event_handlers/hubV2.ts - events: - - event: Transfer(address indexed from, address indexed to, uint256 value) - - event: DepositDemurraged(address indexed account, uint256 amount, uint256 inflationaryAmount) - - event: WithdrawDemurraged(address indexed account, uint256 amount, uint256 inflationaryAmount) - - event: DepositInflationary(address indexed account, uint256 amount, uint256 demurragedAmount) - - event: WithdrawInflationary(address indexed account, uint256 amount, uint256 demurragedAmount) + address: + - 0xA27566fD89162cC3D40Cb59c87AAaA49B85F3474 + - name: WrappedERC20 - name: SafeAccount - handler: src/event_handlers/hubV2.ts - events: - - event: ExecutionSuccess(bytes32 txHash, uint256 payment) - -networks: - # - id: 10200 - # start_block: 2211707 - # contracts: - # - name: Hub - # address: - # - 0xdbF22D4e8962Db3b2F1d9Ff55be728A887e47710 - # - name: PersonalCRC - # - name: HubV2 - # address: - # - 0xb80feeDfEce647dDc709777D5094fACD157BA001 - # - name: ERC20Lift - # address: - # - 0xBD2D6Fbb6A702B04B750Bc9942fBaAE81187355E - # - name: StandardTreasury - # address: - # - 0xC06ADED7950429FdF2023e139B076f6BaFf9Fe1C - # - name: NameRegistry - # address: - # - 0x24b3fDCdD9fef844fB3094ef43c0A6Ac23a6dF9E - # - name: WrapperERC20Personal - - id: 100 - start_block: 12529458 - # start_block: 36486014 - contracts: - - name: HubV2 - address: - - 0xc12C1E50ABB450d6205Ea2C3Fa861b3B834d13e8 - - name: ERC20Lift - address: - - 0x5F99a795dD2743C36D63511f0D4bc667e6d3cDB5 - - name: StandardTreasury - address: - - 0x08F90aB73A515308f03A718257ff9887ED330C6e - - name: NameRegistry - address: - - 0xA27566fD89162cC3D40Cb59c87AAaA49B85F3474 - - name: WrapperERC20Personal - - name: SafeAccount + - name: CustomTreasury diff --git a/schema.graphql b/schema.graphql index a6fa4ea..5062159 100644 --- a/schema.graphql +++ b/schema.graphql @@ -14,6 +14,11 @@ enum TransferType { StreamCompleted HubTransfer Transfer + GroupMintSingle + GroupMintBatch + GroupRedeem + GroupRedeemCollateralReturn + GroupRedeemCollateralBurn } type Transfer { @@ -74,8 +79,6 @@ type AvatarBalance { token: Token! avatar: Avatar! balance: BigInt! - version: Int! - isWrapped: Boolean! inflationaryValue: BigInt lastCalculated: Int } diff --git a/src/common/handleTransfer.ts b/src/common/handleTransfer.ts index 4ae07b6..652cf91 100644 --- a/src/common/handleTransfer.ts +++ b/src/common/handleTransfer.ts @@ -6,7 +6,7 @@ import { Transfer, HubV2_TransferSingle_eventArgs, HubV2_TransferBatch_eventArgs, - WrapperERC20Personal_Transfer_eventArgs, + WrappedERC20_Transfer_eventArgs, } from "generated"; import { incrementStats } from "../incrementStats"; import { TransferType_t } from "generated/src/db/Enums.gen"; @@ -26,7 +26,7 @@ export const handleTransfer = async ({ | PersonalCRC_Transfer_eventArgs */ | HubV2_TransferSingle_eventArgs | HubV2_TransferBatch_eventArgs - | WrapperERC20Personal_Transfer_eventArgs + | WrappedERC20_Transfer_eventArgs >; context: handlerContext; operator: string | undefined; @@ -76,23 +76,21 @@ export const handleTransfer = async ({ await updateAvatarBalance( context, - event.params.to, - tokens[i], values[i], - version, - isWrapped, - undefined, - undefined + event.block.timestamp, + { + id: event.params.to, + token_id: tokens[i], + } ); await updateAvatarBalance( context, - event.params.from, - tokens[i], -values[i], - version, - isWrapped, - undefined, - undefined + event.block.timestamp, + { + id: event.params.from, + token_id: tokens[i], + }, ); await incrementStats(context, "transfers"); } diff --git a/src/common/updateAvatarBalance.ts b/src/common/updateAvatarBalance.ts index 552e402..a229690 100644 --- a/src/common/updateAvatarBalance.ts +++ b/src/common/updateAvatarBalance.ts @@ -1,4 +1,4 @@ -import { handlerContext } from "generated"; +import { AvatarBalance, handlerContext } from "generated"; import { zeroAddress } from "viem"; function makeAvatarBalanceEntityId(avatarId: string, tokenId: string) { @@ -7,30 +7,29 @@ function makeAvatarBalanceEntityId(avatarId: string, tokenId: string) { export const updateAvatarBalance = async ( context: handlerContext, - avatarId: string, - tokenId: string, amount: bigint, - version: number, - isWrapped: boolean, - inflationaryValue: bigint | undefined, - lastCalculated: number | undefined + blockTimestamp: number, + options: Partial ) => { - if (avatarId === zeroAddress) { + const { id: avatarId, token_id: tokenId } = options; + if (avatarId === zeroAddress || !avatarId || !tokenId) { return; } const balanceId = makeAvatarBalanceEntityId(avatarId, tokenId); - const [avatarBalance, avatar] = await Promise.all([ + const [avatarBalance, avatar, token] = await Promise.all([ context.AvatarBalance.get(balanceId), context.Avatar.get(avatarId), + context.Token.get(tokenId), ]); if (avatarBalance) { let updated = { ...avatarBalance, - balance: avatarBalance.balance + amount, + lastCalculated: blockTimestamp, }; - if (inflationaryValue !== undefined) { - updated.inflationaryValue = - (avatarBalance.inflationaryValue || 0n) + inflationaryValue; + if (token?.tokenType === "WrappedStaticToken") { + updated.inflationaryValue = avatarBalance.inflationaryValue! + amount; + } else { + updated.balance = avatarBalance.balance + amount; } context.AvatarBalance.set(updated); } else { @@ -39,10 +38,8 @@ export const updateAvatarBalance = async ( avatar_id: avatarId, token_id: tokenId, balance: amount, - version, - isWrapped, - inflationaryValue, - lastCalculated, + inflationaryValue: 0n, + lastCalculated: blockTimestamp, }); } if (avatar) { diff --git a/src/event_handlers/hubV2.ts b/src/event_handlers/hubV2.ts index 1873e87..242aa01 100644 --- a/src/event_handlers/hubV2.ts +++ b/src/event_handlers/hubV2.ts @@ -1,42 +1,23 @@ import { - eventLog, - handlerContext, - /* Hub_HubTransfer_eventArgs, - PersonalCRC_Transfer_eventArgs, */ ERC20Lift, HubV2, - WrapperERC20Personal, Avatar, TrustRelation, - Transfer, - HubV2_TransferSingle_eventArgs, - HubV2_TransferBatch_eventArgs, - WrapperERC20Personal_Transfer_eventArgs, NameRegistry, SafeAccount, } from "generated"; -import { - toBytes, - bytesToBigInt, - zeroAddress, - parseEther, - getAddress, -} from "viem"; +import { toBytes, bytesToBigInt, parseEther } from "viem"; import { incrementStats } from "../incrementStats"; -import { TransferType_t } from "generated/src/db/Enums.gen"; import { getProfileMetadataFromIpfs } from "../utils"; import { Profile } from "../types"; - -function makeAvatarBalanceEntityId(avatarId: string, tokenId: string) { - return `${avatarId}-${tokenId}`; -} +import { handleTransfer } from "../common/handleTransfer"; // ############### // #### TOKEN #### // ############### ERC20Lift.ERC20WrapperDeployed.contractRegister(async ({ event, context }) => { - context.addWrapperERC20Personal(event.params.erc20Wrapper); + context.addWrappedERC20(event.params.erc20Wrapper); }); ERC20Lift.ERC20WrapperDeployed.handler(async ({ event, context }) => { @@ -284,140 +265,6 @@ NameRegistry.UpdateMetadataDigest.handler(async ({ event, context }) => { // ## TRANSFERS ## // ############### -const updateAvatarBalance = async ( - context: handlerContext, - avatarId: string, - tokenId: string, - amount: bigint, - version: number, - isWrapped: boolean, - inflationaryValue: bigint | undefined, - lastCalculated: number | undefined -) => { - if (avatarId === zeroAddress) { - return; - } - const balanceId = makeAvatarBalanceEntityId(avatarId, tokenId); - const [avatarBalance, avatar] = await Promise.all([ - context.AvatarBalance.get(balanceId), - context.Avatar.get(avatarId), - ]); - if (avatarBalance) { - let updated = { - ...avatarBalance, - balance: avatarBalance.balance + amount, - }; - if (inflationaryValue !== undefined) { - updated.inflationaryValue = - (avatarBalance.inflationaryValue || 0n) + inflationaryValue; - } - context.AvatarBalance.set(updated); - } else { - context.AvatarBalance.set({ - id: balanceId, - avatar_id: avatarId, - token_id: tokenId, - balance: amount, - version, - isWrapped, - inflationaryValue, - lastCalculated, - }); - } - if (avatar) { - context.Avatar.set({ - ...avatar, - balance: avatar.balance + amount, - }); - } -}; - -const handleTransfer = async ({ - event, - context, - operator, - values, - tokens, - transferType, - version, -}: { - event: eventLog< - /* | Hub_HubTransfer_eventArgs - | PersonalCRC_Transfer_eventArgs */ - | HubV2_TransferSingle_eventArgs - | HubV2_TransferBatch_eventArgs - | WrapperERC20Personal_Transfer_eventArgs - >; - context: handlerContext; - operator: string | undefined; - values: bigint[]; - tokens: string[]; - transferType: TransferType_t; - version: number; -}) => { - let isWrapped = transferType === "Erc20WrapperTransfer"; - - for (let i = 0; i < tokens.length; i++) { - const token = await context.Token.get(tokens[i]); - if (!token) { - context.Token.set({ - id: tokens[i], - blockNumber: event.block.number, - timestamp: event.block.timestamp, - transactionIndex: event.transaction.transactionIndex, - logIndex: event.logIndex, - transactionHash: event.transaction.hash, - version, - // TODO: fix - tokenType: "RegisterHuman", - // TODO: fix - tokenOwner: event.params.to, - }); - } - - const transferEntity: Transfer = { - id: `${event.transaction.hash}-${event.logIndex}`, - safeTxHash: undefined, - blockNumber: event.block.number, - timestamp: event.block.timestamp, - transactionIndex: event.transaction.transactionIndex, - transactionHash: event.transaction.hash, - logIndex: event.logIndex, - from: event.params.from, - to: event.params.to, - operator, - value: values[i], - token: tokens[i], - transferType, - version, - isPartOfStream: false, - }; - context.Transfer.set(transferEntity); - - await updateAvatarBalance( - context, - event.params.to, - tokens[i], - values[i], - version, - isWrapped, - undefined, - undefined - ); - await updateAvatarBalance( - context, - event.params.from, - tokens[i], - -values[i], - version, - isWrapped, - undefined, - undefined - ); - await incrementStats(context, "transfers"); - } -}; - HubV2.StreamCompleted.handlerWithLoader({ loader: async ({ event, context }) => { let transfers = await context.Transfer.getWhere.transactionHash.eq( @@ -432,14 +279,10 @@ HubV2.StreamCompleted.handlerWithLoader({ // delete the transfers only // it's important to not reverse balances because of how the pathfinder works. for (let i = 0; i < transfers.length; i++) { - const tx = await context.Transfer.get(transfers[i].id); - if (tx) { - context.Transfer.set({ - ...tx, - isPartOfStream: true, - }); - // decrese transfer count - } + context.Transfer.set({ + ...transfers[i], + isPartOfStream: true, + }); } // register as transfer @@ -501,73 +344,6 @@ HubV2.DiscountCost.handler(async ({ event, context }) => { } }); -WrapperERC20Personal.Transfer.handler( - async ({ event, context }) => - await handleTransfer({ - event, - context, - operator: undefined, - values: [event.params.value], - tokens: [event.srcAddress], - transferType: "Erc20WrapperTransfer", - version: 2, - }) -); - -WrapperERC20Personal.DepositDemurraged.handler(async ({ event, context }) => { - await updateAvatarBalance( - context, - event.params.account, - event.srcAddress, - 0n, - 2, - true, - event.params.inflationaryAmount, - event.block.timestamp - ); -}); - -WrapperERC20Personal.WithdrawDemurraged.handler(async ({ event, context }) => { - await updateAvatarBalance( - context, - event.params.account, - event.srcAddress, - 0n, - 2, - true, - -event.params.inflationaryAmount, - event.block.timestamp - ); -}); - -WrapperERC20Personal.DepositInflationary.handler(async ({ event, context }) => { - await updateAvatarBalance( - context, - event.params.account, - event.srcAddress, - 0n, - 2, - true, - event.params.demurragedAmount, - event.block.timestamp - ); -}); - -WrapperERC20Personal.WithdrawInflationary.handler( - async ({ event, context }) => { - await updateAvatarBalance( - context, - event.params.account, - event.srcAddress, - 0n, - 2, - true, - -event.params.demurragedAmount, - event.block.timestamp - ); - } -); - // ############### // #### TRUST #### // ############### diff --git a/src/event_handlers/standardTreasury.ts b/src/event_handlers/standardTreasury.ts deleted file mode 100644 index e88f3ef..0000000 --- a/src/event_handlers/standardTreasury.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { StandardTreasury } from "generated"; - -function makeAvatarBalanceEntityId(avatarId: string, tokenId: string) { - return `${avatarId}-${tokenId}`; -} - -StandardTreasury.CreateVault.handler(async ({ event, context }) => { - // TODO: Implement handler here -}); - -StandardTreasury.GroupMintSingle.handler(async ({ event, context }) => { - const avatar = await context.Avatar.get(event.params.group); - if (avatar) { - const balanceId = makeAvatarBalanceEntityId( - event.params.group, - event.params.id.toString() - ); - const avatarBalance = await context.AvatarBalance.get(balanceId); - if (avatarBalance) { - context.AvatarBalance.set({ - ...avatarBalance, - balance: avatarBalance.balance + event.params.value, - }); - } else { - context.AvatarBalance.set({ - id: makeAvatarBalanceEntityId( - event.params.group, - event.params.id.toString() - ), - token_id: event.params.id.toString(), - avatar_id: event.params.group, - balance: event.params.value, - inflationaryValue: 0n, - isWrapped: false, - lastCalculated: 0, - version: 2, - }); - } - } -}); - -StandardTreasury.GroupMintBatch.handler(async ({ event, context }) => { - // TODO: Implement handler here -}); - -StandardTreasury.GroupRedeem.handler(async ({ event, context }) => { - // TODO: Implement handler here -}); - -StandardTreasury.GroupRedeemCollateralBurn.handler( - async ({ event, context }) => { - // TODO: Implement handler here - } -); - -StandardTreasury.GroupRedeemCollateralReturn.handler( - async ({ event, context }) => { - // TODO: Implement handler here - } -); - -// TODO: missing envent to redeeem from group diff --git a/src/event_handlers/treasury.ts b/src/event_handlers/treasury.ts new file mode 100644 index 0000000..f6f85d0 --- /dev/null +++ b/src/event_handlers/treasury.ts @@ -0,0 +1,116 @@ +import { + CustomTreasury, + HandlerTypes_handler, + HandlerTypes_loader, + StandardTreasury, + StandardTreasury_GroupMintBatch_eventArgs, + StandardTreasury_GroupMintSingle_eventArgs, + StandardTreasury_GroupRedeem_eventArgs, + StandardTreasury_GroupRedeemCollateralBurn_eventArgs, + StandardTreasury_GroupRedeemCollateralReturn_eventArgs, +} from "generated"; +import { Transfer_t } from "generated/src/db/Entities.gen"; +import { TransferType_t } from "generated/src/db/Enums.gen"; + +StandardTreasury.CreateVault.handler(async ({ event, context }) => { + // TODO: Implement handler here +}); + +const loader: HandlerTypes_loader< + | StandardTreasury_GroupMintSingle_eventArgs + | StandardTreasury_GroupMintBatch_eventArgs + | StandardTreasury_GroupRedeem_eventArgs + | StandardTreasury_GroupRedeemCollateralReturn_eventArgs + | StandardTreasury_GroupRedeemCollateralBurn_eventArgs, + { + transfers: Transfer_t[]; + } +> = async ({ event, context }) => { + let transfers = await context.Transfer.getWhere.transactionHash.eq( + event.transaction.hash + ); + + return { transfers }; +}; + +const createHandler = + ( + transferType: TransferType_t + ): HandlerTypes_handler< + | StandardTreasury_GroupMintSingle_eventArgs + | StandardTreasury_GroupMintBatch_eventArgs + | StandardTreasury_GroupRedeem_eventArgs + | StandardTreasury_GroupRedeemCollateralReturn_eventArgs + | StandardTreasury_GroupRedeemCollateralBurn_eventArgs, + { + transfers: Transfer_t[]; + } + > => + async ({ context, loaderReturn }) => { + const { transfers } = loaderReturn; + + for (let i = 0; i < transfers.length; i++) { + context.Transfer.set({ + ...transfers[i], + transferType, + }); + } + }; + +// ######################### +// ### STANDARD TREASURY ### +// ######################### + +StandardTreasury.GroupMintSingle.handlerWithLoader({ + loader, + handler: createHandler("GroupMintSingle"), +}); + +StandardTreasury.GroupMintBatch.handlerWithLoader({ + loader, + handler: createHandler("GroupMintBatch"), +}); + +StandardTreasury.GroupRedeem.handlerWithLoader({ + loader, + handler: createHandler("GroupRedeem"), +}); + +StandardTreasury.GroupRedeemCollateralBurn.handlerWithLoader({ + loader, + handler: createHandler("GroupRedeemCollateralBurn"), +}); + +StandardTreasury.GroupRedeemCollateralReturn.handlerWithLoader({ + loader, + handler: createHandler("GroupRedeemCollateralReturn"), +}); + +// ######################### +// #### CUSTOM TREASURY #### +// ######################### + +CustomTreasury.GroupMintSingle.handlerWithLoader({ + loader, + handler: createHandler("GroupMintSingle"), +}); + +CustomTreasury.GroupMintBatch.handlerWithLoader({ + loader, + handler: createHandler("GroupMintBatch"), +}); + +CustomTreasury.GroupRedeem.handlerWithLoader({ + loader, + handler: createHandler("GroupRedeem"), +}); + +CustomTreasury.GroupRedeemCollateralBurn.handlerWithLoader({ + loader, + handler: createHandler("GroupRedeemCollateralBurn"), +}); + +CustomTreasury.GroupRedeemCollateralReturn.handlerWithLoader({ + loader, + handler: createHandler("GroupRedeemCollateralReturn"), +}); diff --git a/src/event_handlers/wrappedERC20.ts b/src/event_handlers/wrappedERC20.ts new file mode 100644 index 0000000..4d5b518 --- /dev/null +++ b/src/event_handlers/wrappedERC20.ts @@ -0,0 +1,104 @@ +import { + eventLog, + handlerContext, + WrappedERC20, + WrappedERC20_DepositInflationary_eventArgs, + WrappedERC20_WithdrawInflationary_eventArgs, + WrappedERC20_DepositDemurraged_eventArgs, + WrappedERC20_WithdrawDemurraged_eventArgs, + } from "generated"; + import { handleTransfer } from "../common/handleTransfer"; + + function makeAvatarBalanceEntityId(avatarId: string, tokenId: string) { + return `${avatarId}-${tokenId}`; + } + +WrappedERC20.Transfer.handler( + async ({ event, context }) => + await handleTransfer({ + event, + context, + operator: undefined, + values: [event.params.value], + tokens: [event.srcAddress], + transferType: "Erc20WrapperTransfer", + version: 2, + }) + ); + + async function updateDemurragedAvatarBalance( + event: eventLog< + | WrappedERC20_DepositDemurraged_eventArgs + | WrappedERC20_WithdrawDemurraged_eventArgs + >, + context: handlerContext, + operation: "deposit" | "withdraw" + ) { + const avatarId = event.params.account; + const tokenId = event.srcAddress; + const balanceId = makeAvatarBalanceEntityId(avatarId, tokenId); + const avatarBalance = await context.AvatarBalance.get(balanceId); + + if (avatarBalance) { + const balanceChange = + operation === "deposit" + ? event.params.inflationaryAmount + : -event.params.inflationaryAmount; + context.AvatarBalance.set({ + ...avatarBalance, + inflationaryValue: avatarBalance.inflationaryValue! + balanceChange, + }); + } + } + + WrappedERC20.DepositDemurraged.handler(async ({ event, context }) => { + await updateDemurragedAvatarBalance(event, context, "deposit"); + }); + + WrappedERC20.WithdrawDemurraged.handler(async ({ event, context }) => { + await updateDemurragedAvatarBalance(event, context, "withdraw"); + }); + + /** + * On inflationary tokens, the `amount` on transfers is the inflationary value so we adjust to + * always keep the `balance` property as demurraged amount even if the token is inflationary. + * Amount is added in `updateAvatarBalance` then subtracted here because it might be a simple transfer. + */ + async function updateInflationaryAvatarBalance( + event: eventLog< + | WrappedERC20_DepositInflationary_eventArgs + | WrappedERC20_WithdrawInflationary_eventArgs + >, + context: handlerContext, + operation: "deposit" | "withdraw" + ) { + const avatarId = event.params.account; + const tokenId = event.srcAddress; + const balanceId = makeAvatarBalanceEntityId(avatarId, tokenId); + const avatarBalance = await context.AvatarBalance.get(balanceId); + + if (avatarBalance) { + const balanceChange = + operation === "deposit" + ? event.params.demurragedAmount + : -event.params.demurragedAmount; + const inflationaryValueChange = + operation === "deposit" ? event.params.amount : -event.params.amount; + context.AvatarBalance.set({ + ...avatarBalance, + balance: avatarBalance.balance! - event.params.amount + balanceChange, + inflationaryValue: + avatarBalance.inflationaryValue! + inflationaryValueChange, + }); + } + } + + WrappedERC20.DepositInflationary.handler(async ({ event, context }) => { + await updateInflationaryAvatarBalance(event, context, "deposit"); + }); + + WrappedERC20.WithdrawInflationary.handler( + async ({ event, context }) => { + await updateInflationaryAvatarBalance(event, context, "withdraw"); + } + ); \ No newline at end of file