paritytech / paritytech/contract-dependency-manager
Solidity version pinning: generate pinned() wrappers in the .cdm/solidity imports
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 4
- Forks
- 3
- Avg merge
- 4d 13h
- Merged PRs (30d)
- 3
Description
Problem
Since #76, Solidity consumers get the stable per-name proxy address baked into their generated imports (.cdm/solidity/<scope>/<pkg>.sol), but calls through the typed ref() interface are plain calldata — the proxy routes them to the latest implementation. The version pinned at cdm install time affects only the generated interface's shape, not execution.
No toolchain blocker — this is pure codegen
Solidity's low-level .call/.staticcall accept arbitrary bytes, and the import files are generated by solidity-imports.ts (fully owned here). The generator can bake the CDM wire prefix as constants and emit one pinned wrapper per ABI method:
// generated — users never write this
bytes4 private constant CDM_MAGIC = 0xa2264d53; // keccak256("cdm.proxy.call.v1")[..4]
uint128 private constant CDM_KEY = <major<<64|minor<<32|patch>; // pinned at install time
function increment() internal {
(bool ok, bytes memory ret) = ADDRESS.call(
abi.encodePacked(CDM_MAGIC, CDM_KEY, abi.encodeCall(IExampleCounter.increment, ()))
);
if (!ok) _bubble(ret); // revert with the proxy/impl's exact revert data
}
User surface becomes a choice of two one-liners:
ExampleCounter.ref().increment(); // follow latest (today's behavior)
ExampleCounter.pinned().increment(); // execute exactly the installed version
Details
- Views/pure →
staticcall; returnsabi.decoded in the generated wrapper. - Reverts bubble the raw returndata so proxy errors (
UnsupportedVersion(uint128,uint128),ContractFrozen(), …) surface with their real selectors. - The
pinned()shape (library of free functions vs a struct-wrapped handle mirroringref()) is the main design choice — whatever reads best next to the existingref()/cdm()surface. - Constants derive from the same pinned
versionthe generator already receives;cdm iregenerates on version change as it does today.
References
- #76 — wire format and on-chain routing (e2e-proven in
proxy.e2e.test.ts);src/lib/contracts/src/solidity-imports.ts— the generator this lands in. TypeScript and Rust pinning are tracked separately.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/lib/contracts/src/solidity-imports.ts and compare the existing ref()/cdm() generated surface with the pinned() design options described in the issue. Use the wire format and routing behavior from #76 and proxy.e2e.test.ts as references. Done means generated imports expose pinned wrappers that route to the installed version, decode view/pure returns, use staticcall where appropriate, and preserve raw revert data.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity, typescript
- Domain
- blockchain
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100