Context
Audit #320 confirmed (all 5 reviewers: T2-1, T2-2, T2-3, T2a, T2b) that the SDK has wrong ABI definitions and client logic for getRoyaltyInfo and claimRoyalties, verified against the actual Mint Club V2 contract source (MCV2_Royalty.sol) and PlotLink's own IMCV2_Bond.sol interface.
Additionally, the re-review against plotlink-contracts source confirmed the web app MCV2 ABI (lib/price.ts) has incorrect output types for 4 functions. These should be corrected for ABI accuracy.
Note: T2b's re-review claimed chainPlot and PlotChained are missing a title param — this is incorrect. The source at StoryFactory.sol:38-45 and :154 clearly includes title. Disregard that finding.
Part 1: Fix SDK royalty ABI and client (CRITICAL)
Bug Details
| Function |
SDK (wrong) |
Contract (correct, matches web app) |
getRoyaltyInfo |
inputs: (token, beneficiary), outputs: (unclaimed) — 1 output |
inputs: (wallet, reserveToken), outputs: (balance, claimed) — 2 outputs |
claimRoyalties |
SDK client passes storyline token address |
Contract expects reserve token address (WETH on testnet, $PLOT on mainnet) |
Impact: SDK getRoyaltyInfo() returns garbage data. SDK/CLI claimRoyalties() fails or claims the wrong asset. All royalty features in the CLI (claim, status) are broken.
Files to Change
-
packages/sdk/src/abi.ts (lines 131-148)
- Fix
getRoyaltyInfo: inputs to (wallet: address, reserveToken: address), outputs to (balance: uint256, claimed: uint256)
- Fix
claimRoyalties: rename input to reserveToken for clarity
-
packages/sdk/src/client.ts
getRoyaltyInfo() (lines 502-511): pass args as (beneficiary, reserveTokenAddress) in correct order; return both balance and claimed; resolve reserve token from tokenBond() internally or accept it as parameter
claimRoyalties() (lines 520-533): change parameter from storyline token to reserve token address
- Update
RoyaltyInfo type (line 102-104): add claimed field alongside unclaimed (rename to balance)
-
packages/cli/src/commands/claim.ts
- Already reads
reserveToken from tokenBond() result (line 29) — pass it to claimRoyalties() instead of the storyline token address
-
packages/cli/src/commands/status.ts (if it calls getRoyaltyInfo)
- Update to match new SDK method signature
Part 2: Fix web app MCV2 ABI output types (minor, ABI accuracy)
The re-review confirmed via IMCV2_Bond.sol that 4 functions in lib/price.ts have incorrect output declarations:
| Function |
Contract (IMCV2_Bond.sol) |
Web ABI (lib/price.ts) current |
getReserveForToken |
returns (uint256 reserveAmount, uint256 royalty) |
1 output only |
getRefundForTokens |
returns (uint256 refundAmount, uint256 royalty) |
1 output only |
mint |
returns uint256 |
outputs: [] |
burn |
returns uint256 |
outputs: [] |
Impact: mint/burn missing returns are harmless (return values unused). getReserveForToken/getRefundForTokens — viem returns the first tuple element which is the correct cost/refund value, so trading estimates work correctly. The second value (royalty) is informational only. Not a functional bug, but ABI should match the contract for accuracy.
Files to Change
lib/price.ts (lines 16-58)
- Update
getReserveForToken outputs to [{ name: "reserveAmount" }, { name: "royalty" }]
- Update
getRefundForTokens outputs to [{ name: "refundAmount" }, { name: "royalty" }]
- Update
mint outputs to [{ name: "", type: "uint256" }]
- Update
burn outputs to [{ name: "", type: "uint256" }]
- Ensure
TradingWidget.tsx still reads the correct value (first element of tuple, or destructure explicitly)
Acceptance Criteria
Context
Audit #320 confirmed (all 5 reviewers: T2-1, T2-2, T2-3, T2a, T2b) that the SDK has wrong ABI definitions and client logic for
getRoyaltyInfoandclaimRoyalties, verified against the actual Mint Club V2 contract source (MCV2_Royalty.sol) and PlotLink's ownIMCV2_Bond.solinterface.Additionally, the re-review against
plotlink-contractssource confirmed the web app MCV2 ABI (lib/price.ts) has incorrect output types for 4 functions. These should be corrected for ABI accuracy.Note: T2b's re-review claimed
chainPlotandPlotChainedare missing atitleparam — this is incorrect. The source atStoryFactory.sol:38-45and:154clearly includestitle. Disregard that finding.Part 1: Fix SDK royalty ABI and client (CRITICAL)
Bug Details
getRoyaltyInfoinputs: (token, beneficiary),outputs: (unclaimed)— 1 outputinputs: (wallet, reserveToken),outputs: (balance, claimed)— 2 outputsclaimRoyaltiesImpact: SDK
getRoyaltyInfo()returns garbage data. SDK/CLIclaimRoyalties()fails or claims the wrong asset. All royalty features in the CLI (claim,status) are broken.Files to Change
packages/sdk/src/abi.ts(lines 131-148)getRoyaltyInfo: inputs to(wallet: address, reserveToken: address), outputs to(balance: uint256, claimed: uint256)claimRoyalties: rename input toreserveTokenfor claritypackages/sdk/src/client.tsgetRoyaltyInfo()(lines 502-511): pass args as(beneficiary, reserveTokenAddress)in correct order; return bothbalanceandclaimed; resolve reserve token fromtokenBond()internally or accept it as parameterclaimRoyalties()(lines 520-533): change parameter from storyline token to reserve token addressRoyaltyInfotype (line 102-104): addclaimedfield alongsideunclaimed(rename tobalance)packages/cli/src/commands/claim.tsreserveTokenfromtokenBond()result (line 29) — pass it toclaimRoyalties()instead of the storyline token addresspackages/cli/src/commands/status.ts(if it calls getRoyaltyInfo)Part 2: Fix web app MCV2 ABI output types (minor, ABI accuracy)
The re-review confirmed via
IMCV2_Bond.solthat 4 functions inlib/price.tshave incorrect output declarations:IMCV2_Bond.sol)lib/price.ts) currentgetReserveForToken(uint256 reserveAmount, uint256 royalty)getRefundForTokens(uint256 refundAmount, uint256 royalty)mintuint256outputs: []burnuint256outputs: []Impact:
mint/burnmissing returns are harmless (return values unused).getReserveForToken/getRefundForTokens— viem returns the first tuple element which is the correct cost/refund value, so trading estimates work correctly. The second value (royalty) is informational only. Not a functional bug, but ABI should match the contract for accuracy.Files to Change
lib/price.ts(lines 16-58)getReserveForTokenoutputs to[{ name: "reserveAmount" }, { name: "royalty" }]getRefundForTokensoutputs to[{ name: "refundAmount" }, { name: "royalty" }]mintoutputs to[{ name: "", type: "uint256" }]burnoutputs to[{ name: "", type: "uint256" }]TradingWidget.tsxstill reads the correct value (first element of tuple, or destructure explicitly)Acceptance Criteria
getRoyaltyInfoABI matches MCV2_Royalty contract (2 inputs, 2 outputs)(beneficiary, reserveToken)in correct orderclaimRoyaltiesaccepts and passes reserve token addressclaimcommand passes reserve token (already available fromtokenBond())lib/price.tsMCV2 ABI output types matchIMCV2_Bond.solnpm run buildandnpm run typecheckpass