Skip to content

[Bug]: InviteSDK blocks late inviter attachment supported by InvitesV2 #55

Description

@L03TJ3

Summary

@goodsdks/invite-sdk@1.0.1 prevents a user who first registered a personal invite code without an inviter from later attaching an inviter. InvitesV2 and GoodWallet support this one-time transition. Align InviteSDK prechecks with the contract, then release a corrected version for SDK-only consumers such as GoodWidget.

Scope

  • Repo: GoodDollar/GoodSDKs
  • Package: @goodsdks/invite-sdk
  • Main file: packages/invite-sdk/src/sdks/viem-invite-sdk.tsInviteSDK.join
  • Reference contract: use gooddollar skills to look up the invite contract
  • Tests: InviteSDK join/precheck tests

Current Problems

  • InviteSDK.join rejects any non-zero codeToUser(myCode), including when that code belongs to the connected caller.
  • It also rejects any caller with joinedAt > 0.
  • InvitesV2 permits this valid sequence once: join(myCode, zeroHash), then join(myCode, inviterCode) while invitedBy is zero and the bounty is unpaid.
  • GoodWallet relies on that behavior by reusing the caller's existing personal code when an inviter code is supplied later.

Required Changes

  • Permit myCode when codeToUser(myCode) is the connected caller; continue rejecting codes owned by another address.
  • Replace the blanket joinedAt > 0 rejection with the InvitesV2 rule: allow one deferred inviter attachment only when the caller has no invitedBy, has not received their bounty, and supplies a valid non-zero inviter code.
  • Continue rejecting a second join after an inviter is attached, after bounty payment, self-invites, inactive campaigns, and codes owned by another account.
  • Release a new InviteSDK version and document this corrected join behavior.

Implementation Notes

  • Mirror InvitesV2.join exactly: the existing caller-owned code is valid, and invitedBy == address(0) is the relevant deferred-assignment condition—not joinedAt == 0.
  • Resolve the supplied inviter code before allowing the deferred path, so an unknown code remains rejected before transaction submission.
  • Preserve typed, actionable errors for invalid inviter, self-invite, already-attached inviter, bounty-paid user, inactive contract, and conflicting code owner.

Acceptance Criteria

  • A user can register with join(myCode, zeroHash) and later successfully call join(myCode, inviterCode).
  • The later call uses the same caller-owned myCode and reaches SDK simulation/submission.
  • A user cannot change or add another inviter once invitedBy is non-zero.
  • A code owned by another address, an unknown inviter code, self-invitation, inactive campaign, and a bounty-paid user remain rejected with typed errors.
  • Existing initial join and collection behavior remains unchanged.

Testing / Verification

  • Add an SDK test for initial self-registration followed by deferred inviter attachment.
  • Add negative SDK tests for a second inviter attachment, a conflicting code owner, unknown inviter code, self-invite, and bounty-paid caller.
  • Run the InviteSDK test suite and build.
  • Verify a GoodWidget consumer can use the released SDK version without direct InvitesV2 writes.

Evidence

  • InvitesV2 explicitly permits the deferred assignment in contracts/invite/InvitesV2.sol:122-157 and tests it in test/invite/InvitesV2.test.ts:244-250.
  • GoodWallet keeps invite-code entry available until invitedBy is set and reuses the existing personal code.
  • InviteSDK 1.0.1 currently rejects both caller-owned existing codes and callers with joinedAt > 0 before simulation.

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions