Skip to content

Commit

Permalink
[TOWNS-12637] Encode no op rule datas as empty bytes (#1217)
Browse files Browse the repository at this point in the history
https://linear.app/hnt-labs/issue/TOWNS-12637/%5Balpha%5D%5Buser-feedback%5D-unable-to-update-membership-of-a-town-gated-by
was caused by towns with empty rule datas being initialized with an
encode no-op rule data instead of empty bytes. This is an issue because
the RuleEntitlementV2 contract will ignore NoOpRuleDatas when set on the
contract, but the architect considers the rule data to be a valid
entitlement if it is a non-empty byte array.

The most surgical change here is to encode `NoopRuleData`s as empty byte
arrays. This allows us to continue using NoopRuleData as a placeholder
for the empty RuleDataV2 which is consistent with what CreateRole
expects on the spaceDapp, as well as the API/logic we exposed to create
legacy spaces.

Follow up PR to revert when setEntitlement sets an empty entitlement for
RuleEntitlementV2 to also catch this on the contracts side.
  • Loading branch information
clemire authored Oct 3, 2024
1 parent 1c451c0 commit 653851b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
32 changes: 32 additions & 0 deletions packages/sdk/src/updateRole.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @group with-v2-entitlements
*/

import { createTownWithRequirements, updateRole } from './util.test'
import { NoopRuleData, UpdateRoleParams, Permission, EVERYONE_ADDRESS } from '@river-build/web3'

describe('updateRole', () => {
test('user-gated space created with no-op ruleData allows updates on minter role', async () => {
const { bobSpaceDapp, bobProvider, spaceId } = await createTownWithRequirements({
everyone: false,
users: ['alice'],
ruleData: NoopRuleData,
})

// Update role to be ungated
const { error } = await updateRole(
bobSpaceDapp,
bobProvider,
{
spaceNetworkId: spaceId,
roleId: 1, // Minter role id
roleName: 'Updated minter role',
permissions: [Permission.JoinSpace],
users: [EVERYONE_ADDRESS],
ruleData: NoopRuleData,
} as UpdateRoleParams,
bobProvider.signer,
)
expect(error).toBeUndefined()
})
})
31 changes: 31 additions & 0 deletions packages/sdk/src/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import {
encodeERC1155Params,
convertRuleDataV2ToV1,
XchainConfig,
UpdateRoleParams,
} from '@river-build/web3'

const log = dlog('csb:test:util')
Expand Down Expand Up @@ -945,6 +946,36 @@ export async function createRole(
return { roleId, error: roleError }
}

export interface UpdateRoleContext {
error: Error | undefined
}

export async function updateRole(
spaceDapp: ISpaceDapp,
provider: ethers.providers.Provider,
params: UpdateRoleParams,
signer: ethers.Signer,
): Promise<UpdateRoleContext> {
let txn: ethers.ContractTransaction | undefined = undefined
let error: Error | undefined = undefined
if (useLegacySpaces()) {
throw new Error('updateRole is v2 only')
}
try {
txn = await spaceDapp.updateRole(params, signer)
} catch (err) {
error = spaceDapp.parseSpaceError(params.spaceNetworkId, err)
return { error }
}

const receipt = await provider.waitForTransaction(txn.hash)
if (receipt.status === 0) {
return { error: new Error('Transaction failed') }
}

return { error: undefined }
}

export interface CreateChannelContext {
channelId: string | undefined
error: Error | undefined
Expand Down
5 changes: 5 additions & 0 deletions packages/web3/src/entitlement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ export function decodeRuleData(entitlementData: Hex): IRuleEntitlementBase.RuleD
}

export function encodeRuleDataV2(ruleData: IRuleEntitlementV2Base.RuleDataV2Struct): Hex {
// If we encounter a no-op rule data, just encode as empty bytes.
if (ruleData.operations.length === 0) {
return '0x'
}

const getRuleDataV2Abi: ExtractAbiFunction<typeof IRuleEntitlementV2Abi, 'getRuleDataV2'> =
getAbiItem({
abi: IRuleEntitlementV2Abi,
Expand Down

0 comments on commit 653851b

Please sign in to comment.