Skip to content

Commit

Permalink
Merge branch 'feature--role-assignments' into qa
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Lima committed Oct 23, 2023
2 parents 4243a03 + 285bd65 commit ab81c97
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 29 deletions.
3 changes: 2 additions & 1 deletion schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ type RoleAssignment @entity {
expirationDate: BigInt!
revocable: Boolean!
data: Bytes!
timestamp: BigInt!
createdAt: BigInt!
updatedAt: BigInt!
}

type Role @entity {
Expand Down
10 changes: 5 additions & 5 deletions src/erc7432/role/revoke-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ export function handleRoleRevoked(event: RoleRevoked): void {
}

const roleAssignmentId = generateRoleAssignmentId(revoker, grantee, nft, event.params._role)
const roleassignment = RoleAssignment.load(roleAssignmentId)
if (!roleassignment) {
const roleAssignment = RoleAssignment.load(roleAssignmentId)
if (!roleAssignment) {
log.warning('[handleRoleRevoked] RoleAssignment {} does not exist, skipping...', [roleAssignmentId])
return
}
if (event.block.timestamp > roleassignment.expirationDate) {
if (event.block.timestamp > roleAssignment.expirationDate) {
log.warning('[handleRoleRevoked] RoleAssignment {} already expired, skipping...', [roleAssignmentId])
return
}

roleassignment.expirationDate = event.block.timestamp
roleassignment.save()
roleAssignment.expirationDate = event.block.timestamp
roleAssignment.save()
log.warning('[handleRoleRevoked] Revoked RoleAssignment: {} NFT: {} Tx: {}', [
roleAssignmentId,
nftId,
Expand Down
3 changes: 2 additions & 1 deletion src/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ export function findOrCreateRoleAssignment(
roleAssignment.nft = nft.id
roleAssignment.grantor = grantor.id
roleAssignment.grantee = grantee.id
roleAssignment.createdAt = event.block.timestamp
}

roleAssignment.expirationDate = event.params._expirationDate
roleAssignment.revocable = event.params._revocable
roleAssignment.data = event.params._data
roleAssignment.timestamp = event.block.timestamp
roleAssignment.updatedAt = event.block.timestamp
roleAssignment.save()
return roleAssignment
}
Expand Down
15 changes: 12 additions & 3 deletions tests/erc7432/grant-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('ERC-7432 RoleGranted Handler', () => {
clearStore()
})

test('should not grant roleassignment when NFT does not exist', () => {
test('should not grant roleAssignment when NFT does not exist', () => {
assert.entityCount('RoleAssignment', 0)
assert.entityCount('Account', 0)

Expand All @@ -36,13 +36,15 @@ describe('ERC-7432 RoleGranted Handler', () => {
)
handleRoleGranted(event)

assert.entityCount('Role', 0)
assert.entityCount('RoleAssignment', 0)
assert.entityCount('Account', 0)
})

test('should not grant roleassignment when grantor does not exist', () => {
test('should not grant roleAssignment when grantor does not exist', () => {
createMockNft(tokenAddress, tokenId, Addresses[0])
assert.entityCount('RoleAssignment', 0)
assert.entityCount('Role', 0)
assert.entityCount('Account', 1)

const event = createNewRoleGrantedEvent(
Expand All @@ -58,13 +60,15 @@ describe('ERC-7432 RoleGranted Handler', () => {
handleRoleGranted(event)

assert.entityCount('RoleAssignment', 0)
assert.entityCount('Role', 0)
assert.entityCount('Account', 1)
})

test('should not grant roleassignment if grantor is not NFT owner', () => {
test('should not grant roleAssignment if grantor is not NFT owner', () => {
createMockNft(tokenAddress, tokenId, Addresses[0])
createMockAccount(grantor)
assert.entityCount('RoleAssignment', 0)
assert.entityCount('Role', 0)
assert.entityCount('Account', 2)

const event = createNewRoleGrantedEvent(
Expand All @@ -80,12 +84,14 @@ describe('ERC-7432 RoleGranted Handler', () => {
handleRoleGranted(event)

assert.entityCount('RoleAssignment', 0)
assert.entityCount('Role', 0)
assert.entityCount('Account', 2)
})

test('should grant multiple roles for the same NFT', () => {
const nft = createMockNft(tokenAddress, tokenId, grantor)
assert.entityCount('RoleAssignment', 0)
assert.entityCount('Role', 0)
assert.entityCount('Account', 1)

const event1 = createNewRoleGrantedEvent(
Expand Down Expand Up @@ -123,6 +129,7 @@ describe('ERC-7432 RoleGranted Handler', () => {
handleRoleGranted(event3)

assert.entityCount('RoleAssignment', 3)
assert.entityCount('Role', 1)
assert.entityCount('Account', 3)

const grantorAccount = new Account(grantor)
Expand All @@ -140,6 +147,7 @@ describe('ERC-7432 RoleGranted Handler', () => {
const nft2 = createMockNft(tokenAddress, tokenId2, grantor)
const nft3 = createMockNft(tokenAddress, tokenId3, grantor)
assert.entityCount('RoleAssignment', 0)
assert.entityCount('Role', 0)
assert.entityCount('Account', 1)

const event1 = createNewRoleGrantedEvent(
Expand Down Expand Up @@ -177,6 +185,7 @@ describe('ERC-7432 RoleGranted Handler', () => {
handleRoleGranted(event3)

assert.entityCount('RoleAssignment', 3)
assert.entityCount('Role', 3)
assert.entityCount('Account', 3)

const grantorAccount = new Account(grantor)
Expand Down
14 changes: 9 additions & 5 deletions tests/erc7432/revoke-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
clearStore()
})

test('should not revoke roleassignment when NFT does not exist', () => {
test('should not revoke roleAssignment when NFT does not exist', () => {
assert.entityCount('RoleAssignment', 0)

const nftId = generateNftId(tokenAddress, tokenId)
Expand All @@ -35,7 +35,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
assert.entityCount('RoleAssignment', 0)
})

test('should not revoke roleassignment when revoker does not exist', () => {
test('should not revoke roleAssignment when revoker does not exist', () => {
const nft = createMockNft(tokenAddress, tokenId, Addresses[0])
assert.entityCount('RoleAssignment', 0)

Expand All @@ -45,7 +45,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
assert.entityCount('RoleAssignment', 0)
})

test('should not revoke roleassignment when grantee does not exist', () => {
test('should not revoke roleAssignment when grantee does not exist', () => {
const nft = createMockNft(tokenAddress, tokenId, revoker)
assert.entityCount('RoleAssignment', 0)

Expand All @@ -55,7 +55,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
assert.entityCount('RoleAssignment', 0)
})

test('should not revoke roleassignment when roleassignment does not exist', () => {
test('should not revoke roleAssignment when roleAssignment does not exist', () => {
const nft = createMockNft(tokenAddress, tokenId, revoker)
createMockAccount(grantee)
assert.entityCount('RoleAssignment', 0)
Expand All @@ -66,7 +66,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
assert.entityCount('RoleAssignment', 0)
})

test('should not revoke roleassignment when roleassignment already expired', () => {
test('should not revoke roleAssignment when roleAssignment already expired', () => {
const nft = createMockNft(tokenAddress, tokenId, revoker)
const granteeAccount = createMockAccount(grantee)
createMockRoleAssignment(RoleAssignmentId, revoker, grantee, nft, BigInt.fromI32(0))
Expand All @@ -89,6 +89,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
createMockRoleAssignment(RoleAssignmentId, revoker, Addresses[1], nft, expirationDate.plus(ONE))
createMockRoleAssignment(RoleAssignmentId, revoker, Addresses[2], nft, expirationDate.plus(TWO))
assert.entityCount('RoleAssignment', 3)
assert.entityCount('Role', 1)

const event1 = createNewRoleRevokedEvent(RoleAssignmentId, nft, revoker, Addresses[0])
handleRoleRevoked(event1)
Expand All @@ -100,6 +101,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
handleRoleRevoked(event3)

assert.entityCount('RoleAssignment', 3)
assert.entityCount('Role', 1)
const revokerAccount = new Account(revoker)
validateRole(revokerAccount, account1, nft, RoleAssignmentId, ONE, data)
validateRole(revokerAccount, account2, nft, RoleAssignmentId, ONE, data)
Expand All @@ -115,6 +117,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
createMockRoleAssignment(RoleAssignmentId, revoker, grantee, nft2, expirationDate.plus(ONE))
createMockRoleAssignment(RoleAssignmentId, revoker, grantee, nft3, expirationDate.plus(TWO))
assert.entityCount('RoleAssignment', 3)
assert.entityCount('Role', 3)

const event1 = createNewRoleRevokedEvent(RoleAssignmentId, nft1, revoker, grantee)
handleRoleRevoked(event1)
Expand All @@ -126,6 +129,7 @@ describe('ERC-7432 RoleRevoked Handler', () => {
handleRoleRevoked(event3)

assert.entityCount('RoleAssignment', 3)
assert.entityCount('Role', 3)
const revokerAccount = new Account(revoker)
validateRole(revokerAccount, granteeAccount, nft1, RoleAssignmentId, ONE, data)
validateRole(revokerAccount, granteeAccount, nft2, RoleAssignmentId, ONE, data)
Expand Down
31 changes: 21 additions & 10 deletions tests/helpers/entities.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BigInt, Bytes } from '@graphprotocol/graph-ts'
import { Account, Nft, RoleAssignment, RoleApproval } from '../../generated/schema'
import { generateNftId, generateRoleAssignmentId, generateRoleApprovalId } from '../../src/utils/helper'
import { Account, Nft, RoleAssignment, RoleApproval, Role } from '../../generated/schema'
import { generateNftId, generateRoleAssignmentId, generateRoleApprovalId, generateRoleId } from '../../src/utils/helper'
import { assert } from 'matchstick-as'

export function createMockNft(tokenAddress: string, tokenId: string, ownerAddress: string): Nft {
Expand Down Expand Up @@ -28,6 +28,12 @@ export function createMockRoleAssignment(
nft: Nft,
expirationDate: BigInt,
): RoleAssignment {
const roleId = generateRoleId(nft, roleHash)
const role = new Role(roleId)
role.roleHash = roleHash
role.nft = nft.id
role.save()

const roleAssignmentId = generateRoleAssignmentId(new Account(grantor), new Account(grantee), nft, roleHash)
const newRoleAssignment = new RoleAssignment(roleAssignmentId)
newRoleAssignment.role = `${nft.id}-${roleHash.toHex()}`
Expand All @@ -37,7 +43,8 @@ export function createMockRoleAssignment(
newRoleAssignment.expirationDate = expirationDate
newRoleAssignment.revocable = true
newRoleAssignment.data = Bytes.fromUTF8('data')
newRoleAssignment.timestamp = BigInt.fromI32(123)
newRoleAssignment.createdAt = BigInt.fromI32(123)
newRoleAssignment.updatedAt = BigInt.fromI32(123)
newRoleAssignment.save()
return newRoleAssignment
}
Expand All @@ -60,13 +67,17 @@ export function validateRole(
expirationDate: BigInt,
data: Bytes,
): void {
const _id = generateRoleAssignmentId(grantor, grantee, nft, roleAssignment)
assert.fieldEquals('RoleAssignment', _id, 'role', `${nft.id}-${roleAssignment.toHex()}`)
assert.fieldEquals('RoleAssignment', _id, 'nft', nft.id)
assert.fieldEquals('RoleAssignment', _id, 'grantor', grantor.id)
assert.fieldEquals('RoleAssignment', _id, 'grantee', grantee.id)
assert.fieldEquals('RoleAssignment', _id, 'expirationDate', expirationDate.toString())
assert.fieldEquals('RoleAssignment', _id, 'data', data.toHex())
const roleId = generateRoleId(nft, roleAssignment)
assert.fieldEquals('Role', roleId, 'roleHash', roleAssignment.toHex())
assert.fieldEquals('Role', roleId, 'nft', nft.id)

const roleAssignemntId = generateRoleAssignmentId(grantor, grantee, nft, roleAssignment)
assert.fieldEquals('RoleAssignment', roleAssignemntId, 'role', `${nft.id}-${roleAssignment.toHex()}`)
assert.fieldEquals('RoleAssignment', roleAssignemntId, 'nft', nft.id)
assert.fieldEquals('RoleAssignment', roleAssignemntId, 'grantor', grantor.id)
assert.fieldEquals('RoleAssignment', roleAssignemntId, 'grantee', grantee.id)
assert.fieldEquals('RoleAssignment', roleAssignemntId, 'expirationDate', expirationDate.toString())
assert.fieldEquals('RoleAssignment', roleAssignemntId, 'data', data.toHex())
}

export function validateRoleApproval(grantor: string, operator: string, tokenAddress: string): void {
Expand Down
8 changes: 4 additions & 4 deletions tests/helpers/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ export function createTransferEvent(from: string, to: string, tokenId: string, a
}

export function createNewRoleRevokedEvent(
roleassignment: Bytes,
roleAssignment: Bytes,
nft: Nft,
revoker: string,
grantee: string,
): RoleRevoked {
const event = changetype<RoleRevoked>(newMockEvent())
event.parameters = new Array<ethereum.EventParam>()
event.parameters.push(buildEventParamBytes('_role', roleassignment))
event.parameters.push(buildEventParamBytes('_role', roleAssignment))
event.parameters.push(buildEventParamAddress('_tokenAddress', nft.tokenAddress))
event.parameters.push(buildEventParamUint('_tokenId', nft.tokenId))
event.parameters.push(buildEventParamAddress('_revoker', revoker))
Expand All @@ -31,7 +31,7 @@ export function createNewRoleRevokedEvent(
}

export function createNewRoleGrantedEvent(
roleassignment: Bytes,
roleAssignment: Bytes,
tokenId: string,
tokenAddress: string,
grantee: string,
Expand All @@ -42,7 +42,7 @@ export function createNewRoleGrantedEvent(
): RoleGranted {
const event = changetype<RoleGranted>(newMockEvent())
event.parameters = new Array<ethereum.EventParam>()
event.parameters.push(buildEventParamBytes('_role', roleassignment))
event.parameters.push(buildEventParamBytes('_role', roleAssignment))
event.parameters.push(buildEventParamAddress('_tokenAddress', tokenAddress))
event.parameters.push(buildEventParamUint('_tokenId', BigInt.fromString(tokenId)))
event.parameters.push(buildEventParamAddress('_grantor', grantor))
Expand Down

0 comments on commit ab81c97

Please sign in to comment.