Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 42 additions & 30 deletions scripts/shared-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,50 +214,62 @@ export async function processImages(
const img = bannerImages[0];
const urlExt = img.url.match(/\.(png|jpg|jpeg|gif|svg|webp)/i)?.[0];
const tempPath = path.join(imagesDir, `banner_tmp`);
const detectedType = await downloadImage(img.url, tempPath);
let ext = urlExt || contentTypeToExt(detectedType);
let finalPath = path.join(imagesDir, `banner${ext}`);
fs.renameSync(tempPath, finalPath);
if (ext === ".svg") {
finalPath = await convertSvgToPng(finalPath);
ext = ".png";
try {
const detectedType = await downloadImage(img.url, tempPath);
let ext = urlExt || contentTypeToExt(detectedType);
let finalPath = path.join(imagesDir, `banner${ext}`);
fs.renameSync(tempPath, finalPath);
if (ext === ".svg") {
finalPath = await convertSvgToPng(finalPath);
ext = ".png";
}
banner = `/content-images/${contentType}/${slug}/banner${ext}`;
console.log(` ✓ banner${ext} (banner)`);
} catch (e) {
console.warn(`⚠️ Failed to download banner from ${img.url}:`, (e as Error).message);
}
banner = `/content-images/${contentType}/${slug}/banner${ext}`;
console.log(` ✓ banner${ext} (banner)`);
}

// Process logo image — saved as {slug}/logo.png (converted from SVG if needed)
if (logoImages.length > 0) {
const img = logoImages[0];
const urlExt = img.url.match(/\.(png|jpg|jpeg|gif|svg|webp)/i)?.[0];
const tempPath = path.join(imagesDir, `logo_tmp`);
const detectedType = await downloadImage(img.url, tempPath);
let ext = urlExt || contentTypeToExt(detectedType);
let finalPath = path.join(imagesDir, `logo${ext}`);
fs.renameSync(tempPath, finalPath);
if (ext === ".svg") {
finalPath = await convertSvgToPng(finalPath);
ext = ".png";
try {
const detectedType = await downloadImage(img.url, tempPath);
let ext = urlExt || contentTypeToExt(detectedType);
let finalPath = path.join(imagesDir, `logo${ext}`);
fs.renameSync(tempPath, finalPath);
if (ext === ".svg") {
finalPath = await convertSvgToPng(finalPath);
ext = ".png";
}
logo = `/content-images/${contentType}/${slug}/logo${ext}`;
console.log(` ✓ logo${ext} (logo)`);
} catch (e) {
console.warn(`⚠️ Failed to download logo from ${img.url}:`, (e as Error).message);
}
logo = `/content-images/${contentType}/${slug}/logo${ext}`;
console.log(` ✓ logo${ext} (logo)`);
}

// Process description images
for (let i = 0; i < allImages.length; i++) {
const img = allImages[i];
const { filename, publicPath } = await downloadWithFilename(
img,
imagesDir,
`/content-images/${contentType}/${slug}`,
`image-${i + 1}`,
".png",
);
console.log(` ✓ ${filename}`);
updatedMarkdown = updatedMarkdown.replace(
img.markdown,
`![${img.alt}](${publicPath})`,
);
try {
const { filename, publicPath } = await downloadWithFilename(
img,
imagesDir,
`/content-images/${contentType}/${slug}`,
`image-${i + 1}`,
".png",
);
console.log(` ✓ ${filename}`);
updatedMarkdown = updatedMarkdown.replace(
img.markdown,
`![${img.alt}](${publicPath})`,
);
} catch (e) {
console.warn(`⚠️ Failed to download description image ${img.url}:`, (e as Error).message);
}
}

return { banner, logo, updatedMarkdown };
Expand Down
103 changes: 103 additions & 0 deletions src/content/research/potlock-open-funding-stack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
id: '1779313587790'
slug: potlock-open-funding-stack
name: "POTLOCK and the Open Funding Stack"
shortDescription: "Analysis of POTLOCK's Open Funding Stack and what its modular, multichain design signals for public goods funding."
tags:
- "public-goods"
- "quadratic-funding"
- "open-funding"
- "multichain"
- "near"
- "grants"
lastUpdated: '2026-05-20'
authors:
- "Jason Li"
relatedMechanisms:
- quadratic-funding
- direct-grants
- retroactive-funding
- decentralized-identity
relatedApps:
- giveth
- gitcoin-grants-stack
- allo-protocol
relatedCaseStudies:

relatedResearch:

relatedCampaigns:

researchType: Analysis
ctaUrl: 'https://www.potlock.org/'
banner: /content-images/research/potlock-open-funding-stack/banner.png
---

## POTLOCK and the Shift From Grant Rounds to Funding Primitives

Public goods funding is moving from single-purpose grant programs toward reusable allocation infrastructure. Gitcoin's own evolution illustrates the pattern: funding communities need tools that can support direct grants, quadratic funding, impact evaluation, identity checks, matching pools, and payouts without rebuilding the whole stack for every round. POTLOCK is one of the clearest examples of this shift because it frames itself not only as an app, but as an **Open Funding Stack**.

POTLOCK's public site describes the stack as a set of composable primitives: campaigns, pots, quadratic funding, direct donations, identity, and distribution. Its documentation describes the protocol as open source infrastructure for deploying funding mechanisms that move value and evaluate impact across blockchains. That positioning matters because the product is not just a donation page. It is a toolkit for funders, public goods projects, and ecosystem teams to launch funding flows with different levels of governance and matching complexity.

## What POTLOCK Does

At the user level, POTLOCK gives projects a way to create profiles, receive direct donations, join funding rounds, and launch campaigns. Funders can create "pots" for grant rounds, set matching pools, and choose allocation designs such as quadratic funding or custom criteria. The public site lists past rounds including AI Public Goods, Open Source Software, NEAR Retroactive Builders, Creatives, Africa Public Goods, and NEAR Marketing DAO, with pools ranging from roughly $3,000 to $45,000 equivalent in displayed value.

At the protocol level, the "pot" is the core funding-round primitive. POTLOCK's contract documentation describes a pot as a quadratic funding round deployed from a factory contract. A pot can define application dates, matching requirements, fees, a chef/operator role, donation requirements, sponsorship for matching pools, and payout calculation workflows. This separates the durable funding object from the front-end experience around it.

The stack also includes campaign creation, project discovery, direct donations, identity and sybil-resistance components, and distribution tooling. This gives POTLOCK a broader surface area than a one-off grants portal: the same project profile can sit inside recurring rounds, direct donor flows, and ecosystem campaigns.

## Why the Design Is Interesting

The strongest part of POTLOCK's model is that it treats funding as an interface problem and a protocol problem at the same time. Many public goods grant programs have historically combined both into a single process: apply through one form, evaluate with one committee, and distribute from one treasury. That works for simple programs, but it becomes brittle when ecosystems want recurring rounds, different voting mechanisms, shared identity checks, donation widgets, retroactive assessments, or multichain donations.

POTLOCK's primitive-based design makes those pieces more modular:

- **Projects** can maintain a reusable public profile instead of re-entering basic information for every funding opportunity.
- **Funders** can run pots or campaigns with configurable rules instead of commissioning a custom grants portal.
- **Donors** can give directly or participate in rounds, depending on the funding context.
- **Developers** can integrate donation and funding flows into other apps through open tooling.

This architecture is especially relevant as public goods funding becomes more plural. A single ecosystem may want donation matching for community goods, retroactive funding for infrastructure, direct grants for time-sensitive work, and campaign-based crowdfunding for specific initiatives. POTLOCK's value proposition is that these do not need to be isolated products.

## Multichain Funding as a Practical Constraint

POTLOCK is rooted in NEAR, but its current site emphasizes support for many donation chains, including EVM chains, Bitcoin, Solana, Sui, Stellar, TON, Tron, XRP, Starknet, Cardano, Aleo, and others. The most important point is not the exact chain count; it is the acknowledgement that public goods funders and donors are no longer concentrated on one execution environment.

For public goods funding, multichain support changes the job of the funding platform. The platform has to make it easy for donors to contribute from where they already hold assets, while preserving enough structure for round operators to calculate matching and distribute funds. If the stack succeeds, the funding program becomes less dependent on a single wallet network and more focused on the allocation rules.

This is a meaningful complement to Ethereum-oriented funding systems. Ethereum has led much of the public goods funding experimentation, but many funders and contributors now live across L2s, appchains, non-EVM L1s, and Bitcoin-adjacent rails. A stack that can normalize the donation and round experience across those environments may reduce friction for both donors and grant operators.

## Strengths

POTLOCK's biggest strength is its breadth. It does not force all funding into one mechanism. Direct donations, quadratic rounds, campaigns, project registries, and identity checks are different primitives with different tradeoffs, and POTLOCK makes them part of one stack.

Its open-source posture is also important. Public goods funding infrastructure benefits from forkability because grant mechanisms are social systems as much as software systems. Communities need to adapt rules, interfaces, and eligibility criteria. A closed platform can optimize for convenience, but open infrastructure lets communities inspect and modify the allocation stack itself.

Finally, the project appears to be testing in live funding contexts rather than only describing a mechanism. The presence of multiple past funding rounds on the public site gives the stack useful operational feedback: round setup, project onboarding, donor behavior, matching calculations, and payout workflows all produce different failure modes in practice.

## Limitations and Risks

The main risk is complexity. "Open funding stack" is powerful, but it can also be hard for new funders to understand which primitive they need. Campaigns, pots, direct donations, retroactive funding, and AI-assisted public goods funding each imply different governance assumptions. If the interface does not guide funders well, modularity can become decision fatigue.

There is also a trust and measurement challenge. Public goods projects benefit from visibility, but funders still need high-quality evaluation. POTLOCK can provide rails for funding, but the quality of allocation depends on round design, identity checks, evaluator incentives, and anti-sybil assumptions. The stack should be judged not only by dollars moved, but by whether funded projects produce legible impact.

Multichain support introduces another tradeoff. It can increase donor access, but it also increases operational surface area: bridges, swaps, chain-specific wallet UX, token accounting, and payout expectations all need careful handling. Public goods funding tools win trust by making these details boring and reliable.

## What It Signals for the Funding Ecosystem

POTLOCK's most useful contribution is the framing of funding as reusable infrastructure. The next generation of public goods funding will likely be less about choosing a single best mechanism and more about composing mechanisms around a specific context. A local community campaign, a developer tooling QF round, and a retroactive ecosystem allocation should not need the same process, but they can share identity, project profiles, donation routing, and distribution primitives.

For Gitcoin's funding resource directory, POTLOCK is worth tracking because it represents a parallel path to the same problem Gitcoin has worked on for years: how to make capital allocation more open, participatory, and adaptive. Its NEAR roots, multichain donation ambitions, and modular funding primitives make it a useful comparison point for Gitcoin Grants Stack, Giveth, Allo, and other public goods funding systems.

## Sources

- [POTLOCK official site](https://www.potlock.org/)
- [POTLOCK documentation: Welcome](https://docs.potlock.io/)
- [POTLOCK documentation: Protocol](https://docs.potlock.io/welcome-to-potlock/potlock-protocol)
- [POTLOCK documentation: Contracts overview](https://docs.potlock.io/contracts/contracts-overview)
- [POTLOCK documentation: Apply to a Pot](https://docs.potlock.io/user-guides/apply-to-a-pot)

### Authors

Jason Li | https://github.com/jasonzli-DEV
8 changes: 8 additions & 0 deletions src/data/authors.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,13 @@
},
{
"name": "Gitcoin"
},
{
"name": "wognsdl2.bnb",
"social": "https://bscscan.com/address/0xa7171310Be4f3a3541b5cf71A198949b9Ce7E5d2"
},
{
"name": "Jason Li",
"social": "https://github.com/jasonzli-DEV"
}
]