diff --git a/packages/subgraph/human-protocol/src/mapping/EscrowFactory.ts b/packages/subgraph/human-protocol/src/mapping/EscrowFactory.ts index 20014574b0..5508c96647 100644 --- a/packages/subgraph/human-protocol/src/mapping/EscrowFactory.ts +++ b/packages/subgraph/human-protocol/src/mapping/EscrowFactory.ts @@ -4,19 +4,29 @@ import { } from '../../generated/EscrowFactory/EscrowFactory'; import { Escrow, EscrowStatusEvent } from '../../generated/schema'; import { Escrow as EscrowTemplate } from '../../generated/templates'; +import { Escrow as EscrowContract } from '../../generated/templates/Escrow/Escrow'; import { createOrLoadEscrowStatistics } from './Escrow'; import { createOrLoadOperator } from './KVStore'; import { createTransaction } from './utils/transaction'; import { getEventDayData } from './utils/dayUpdates'; import { toEventId } from './utils/event'; import { ONE_BI, ZERO_BI } from './utils/number'; -import { dataSource } from '@graphprotocol/graph-ts'; +import { Address, dataSource } from '@graphprotocol/graph-ts'; + +function getEscrowLauncher(escrowAddress: Address): Address { + const escrowContract = EscrowContract.bind(escrowAddress); + const launcher = escrowContract.try_launcher(); + + return launcher.value; +} export function handleLaunched(event: Launched): void { + const launcher = getEscrowLauncher(event.params.escrow); + createTransaction( event, 'createEscrow', - event.transaction.from, + launcher, dataSource.address(), null, event.params.escrow @@ -28,7 +38,7 @@ export function handleLaunched(event: Launched): void { statusEventEntity.txHash = event.transaction.hash; statusEventEntity.escrowAddress = event.params.escrow; statusEventEntity.sender = event.transaction.from; - statusEventEntity.launcher = event.transaction.from; + statusEventEntity.launcher = launcher; statusEventEntity.status = 'Launched'; statusEventEntity.save(); @@ -39,8 +49,8 @@ export function handleLaunched(event: Launched): void { entity.address = event.params.escrow; entity.token = event.params.token; entity.factoryAddress = event.address; - entity.launcher = event.transaction.from; - entity.canceler = event.transaction.from; + entity.launcher = launcher; + entity.canceler = launcher; entity.balance = ZERO_BI; entity.amountPaid = ZERO_BI; @@ -65,16 +75,18 @@ export function handleLaunched(event: Launched): void { eventDayData.save(); // Increase amount of jobs launched by operator - const operator = createOrLoadOperator(event.transaction.from); + const operator = createOrLoadOperator(launcher); operator.amountJobsProcessed = operator.amountJobsProcessed.plus(ONE_BI); operator.save(); } export function handleLaunchedV2(event: LaunchedV2): void { + const launcher = getEscrowLauncher(event.params.escrow); + createTransaction( event, 'createEscrow', - event.transaction.from, + launcher, dataSource.address(), null, event.params.escrow @@ -87,8 +99,8 @@ export function handleLaunchedV2(event: LaunchedV2): void { entity.token = event.params.token; entity.jobRequesterId = event.params.jobRequesterId; entity.factoryAddress = event.address; - entity.launcher = event.transaction.from; - entity.canceler = event.transaction.from; + entity.launcher = launcher; + entity.canceler = launcher; entity.balance = ZERO_BI; entity.amountPaid = ZERO_BI; @@ -113,7 +125,7 @@ export function handleLaunchedV2(event: LaunchedV2): void { eventDayData.save(); // Increase amount of jobs launched by operator - const operator = createOrLoadOperator(event.transaction.from); + const operator = createOrLoadOperator(launcher); operator.amountJobsProcessed = operator.amountJobsProcessed.plus(ONE_BI); operator.save(); } diff --git a/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts b/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts index 88685f7332..5492229357 100644 --- a/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts +++ b/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts @@ -241,7 +241,7 @@ export function handlePending(event: Pending): void { createTransaction( event, 'setup', - event.transaction.from, + Address.fromBytes(escrowEntity.launcher), Address.fromBytes(escrowEntity.address), null, Address.fromBytes(escrowEntity.address) @@ -275,7 +275,7 @@ export function handlePendingV2(event: PendingV2): void { createTransaction( event, 'setup', - event.transaction.from, + Address.fromBytes(escrowEntity.launcher), Address.fromBytes(escrowEntity.address), null, Address.fromBytes(escrowEntity.address) @@ -312,7 +312,7 @@ export function handlePendingV3(event: PendingV3): void { createTransaction( event, 'setup', - event.transaction.from, + Address.fromBytes(escrowEntity.launcher), Address.fromBytes(escrowEntity.address), null, Address.fromBytes(escrowEntity.address) diff --git a/packages/subgraph/human-protocol/tests/escrow-factory/escrow-factory.test.ts b/packages/subgraph/human-protocol/tests/escrow-factory/escrow-factory.test.ts index 3e905eda7a..eb2aff2b33 100644 --- a/packages/subgraph/human-protocol/tests/escrow-factory/escrow-factory.test.ts +++ b/packages/subgraph/human-protocol/tests/escrow-factory/escrow-factory.test.ts @@ -1,4 +1,9 @@ -import { Address, BigInt, DataSourceContext } from '@graphprotocol/graph-ts'; +import { + Address, + BigInt, + DataSourceContext, + ethereum, +} from '@graphprotocol/graph-ts'; import { describe, test, @@ -7,12 +12,16 @@ import { afterAll, dataSourceMock, beforeAll, + createMockedFunction, } from 'matchstick-as/assembly'; import { STATISTICS_ENTITY_ID } from '../../src/mapping/Escrow'; -import { handleLaunched } from '../../src/mapping/EscrowFactory'; +import { + handleLaunched, + handleLaunchedV2, +} from '../../src/mapping/EscrowFactory'; import { toEventId } from '../../src/mapping/utils/event'; -import { createLaunchedEvent } from './fixtures'; +import { createLaunchedEvent, createLaunchedV2Event } from './fixtures'; const factoryAddressString = '0x92a2eef7ff696bcef98957a0189872680600a958'; const factoryAddress = Address.fromString(factoryAddressString); @@ -24,6 +33,9 @@ const escrow1AddressString = '0xd979105297fb0eee83f7475fc09279cb5b94ffc6'; const escrow1Address = Address.fromString(escrow1AddressString); const escrow2AddressString = '0xd979105297fb0eee83f7433fc09279cb5b94ffc7'; const escrow2Address = Address.fromString(escrow2AddressString); +const escrow3AddressString = '0xd979105297fb0eee83f7433fc09279cb5b94ffc8'; +const escrow3Address = Address.fromString(escrow3AddressString); +const jobRequesterId = 'requester-123'; describe('EscrowFactory', () => { beforeAll(() => { @@ -53,6 +65,17 @@ describe('EscrowFactory', () => { BigInt.fromI32(11) ); + createMockedFunction( + escrow1Address, + 'launcher', + 'launcher():(address)' + ).returns([ethereum.Value.fromAddress(launcherAddress)]); + createMockedFunction( + escrow2Address, + 'launcher', + 'launcher():(address)' + ).returns([ethereum.Value.fromAddress(launcherAddress)]); + handleLaunched(data1); handleLaunched(data2); @@ -208,7 +231,7 @@ describe('EscrowFactory', () => { 'Transaction', data1.transaction.hash.toHex(), 'from', - data1.transaction.from.toHex() + launcherAddressString ); assert.fieldEquals( @@ -233,7 +256,7 @@ describe('EscrowFactory', () => { 'Transaction', data2.transaction.hash.toHex(), 'from', - data2.transaction.from.toHex() + launcherAddressString ); assert.fieldEquals( 'Transaction', @@ -242,4 +265,66 @@ describe('EscrowFactory', () => { factoryAddressString ); }); + + test('Should properly handle LaunchedV2 event using escrow launcher', () => { + const launchedV2 = createLaunchedV2Event( + factoryAddress, + factoryAddress, + tokenAddress, + escrow3Address, + jobRequesterId, + BigInt.fromI32(12) + ); + + createMockedFunction( + escrow3Address, + 'launcher', + 'launcher():(address)' + ).returns([ethereum.Value.fromAddress(launcherAddress)]); + + handleLaunchedV2(launchedV2); + + assert.fieldEquals( + 'Escrow', + escrow3AddressString, + 'launcher', + launcherAddressString + ); + assert.fieldEquals( + 'Escrow', + escrow3AddressString, + 'canceler', + launcherAddressString + ); + assert.fieldEquals( + 'Escrow', + escrow3AddressString, + 'jobRequesterId', + jobRequesterId + ); + assert.fieldEquals( + 'Transaction', + launchedV2.transaction.hash.toHex(), + 'from', + launcherAddressString + ); + assert.fieldEquals( + 'Transaction', + launchedV2.transaction.hash.toHex(), + 'method', + 'createEscrow' + ); + assert.fieldEquals( + 'Operator', + launcherAddressString, + 'amountJobsProcessed', + '3' + ); + assert.fieldEquals( + 'EscrowStatistics', + STATISTICS_ENTITY_ID.toHex(), + 'totalEscrowCount', + '3' + ); + }); }); diff --git a/packages/subgraph/human-protocol/tests/escrow-factory/fixtures.ts b/packages/subgraph/human-protocol/tests/escrow-factory/fixtures.ts index 4673d3412f..610c913b02 100644 --- a/packages/subgraph/human-protocol/tests/escrow-factory/fixtures.ts +++ b/packages/subgraph/human-protocol/tests/escrow-factory/fixtures.ts @@ -1,7 +1,10 @@ import { newMockEvent } from 'matchstick-as/assembly/index'; import { ethereum, BigInt, Address, dataSource } from '@graphprotocol/graph-ts'; -import { Launched } from '../../generated/EscrowFactory/EscrowFactory'; +import { + Launched, + LaunchedV2, +} from '../../generated/EscrowFactory/EscrowFactory'; import { generateUniqueHash } from '../../tests/utils'; export function createLaunchedEvent( @@ -41,3 +44,47 @@ export function createLaunchedEvent( return newLaunchedEvent; } + +export function createLaunchedV2Event( + factory: Address, + launcher: Address, + token: Address, + escrow: Address, + jobRequesterId: string, + timestamp: BigInt +): LaunchedV2 { + const newLaunchedEvent = changetype(newMockEvent()); + newLaunchedEvent.transaction.hash = generateUniqueHash( + escrow.toString(), + timestamp, + newLaunchedEvent.transaction.nonce + ); + + newLaunchedEvent.block.timestamp = timestamp; + newLaunchedEvent.transaction.from = launcher; + newLaunchedEvent.transaction.to = Address.fromString( + dataSource.address().toHexString() + ); + newLaunchedEvent.address = factory; + + newLaunchedEvent.parameters = []; + + const tokenParam = new ethereum.EventParam( + 'token', + ethereum.Value.fromAddress(token) + ); + const escrowParam = new ethereum.EventParam( + 'escrow', + ethereum.Value.fromAddress(escrow) + ); + const jobRequesterIdParam = new ethereum.EventParam( + 'jobRequesterId', + ethereum.Value.fromString(jobRequesterId) + ); + + newLaunchedEvent.parameters.push(tokenParam); + newLaunchedEvent.parameters.push(escrowParam); + newLaunchedEvent.parameters.push(jobRequesterIdParam); + + return newLaunchedEvent; +} diff --git a/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts b/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts index 26a8d442f1..30847fcb56 100644 --- a/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts +++ b/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts @@ -254,7 +254,7 @@ describe('Escrow', () => { 'Transaction', newPending1.transaction.hash.toHex(), 'from', - newPending1.transaction.from.toHex() + launcherAddressString ); assert.fieldEquals( 'Transaction', @@ -380,7 +380,7 @@ describe('Escrow', () => { 'Transaction', newPending1.transaction.hash.toHex(), 'from', - newPending1.transaction.from.toHex() + launcherAddressString ); assert.fieldEquals( 'Transaction', @@ -530,7 +530,7 @@ describe('Escrow', () => { 'Transaction', newPending1.transaction.hash.toHex(), 'from', - newPending1.transaction.from.toHex() + launcherAddressString ); assert.fieldEquals( 'Transaction', @@ -574,6 +574,12 @@ describe('Escrow', () => { 'method', 'fund' ); + assert.fieldEquals( + 'Transaction', + fund.transaction.hash.toHex(), + 'from', + operatorAddressString + ); assert.fieldEquals( 'Transaction', fund.transaction.hash.toHex(), @@ -728,7 +734,7 @@ describe('Escrow', () => { 'Transaction', newPending1.transaction.hash.toHex(), 'from', - newPending1.transaction.from.toHex() + launcherAddressString ); assert.fieldEquals( 'Transaction', @@ -809,6 +815,12 @@ describe('Escrow', () => { 'method', 'setup' ); + assert.fieldEquals( + 'Transaction', + newPending1.transaction.hash.toHex(), + 'from', + launcherAddressString + ); }); test('should properly handle IntermediateStorage event', () => {