In the last post, we looked at how to make smart contracts upgradeable safely. But an upgradeable proxy is just an empty building. Today, we are walking inside the building to look at the engine.
If you are new to Web3, you might wonder why we even need smart contracts for crowdfunding.
Think about traditional crowdfunding platforms like Kickstarter. You trust the creator, you send them your money upfront, and you hope they deliver. Or, think about basic crypto transfers: you send ETH directly to a developer's wallet.
Both scenarios have a simple, critical flaw: you are giving away 100% of your money based on a promise. There is no enforced rule that says, "You only get paid if you actually do the work." If the creator vanishes after taking your money, you are out of luck.
What I wanted to fix with the MilestoneCrowdfundUpgradeable protocol wasn't fundraising. It was execution trust.
The Mental Model: What is a Defensive Escrow?
I framed the architecture around a concept I call a Defensive Escrow.
Instead of sending money directly to a person, you send it to a smart contract. Think of the smart contract as an unbreakable, unbiased robot middleman. The robot locks the money in a vault. It only releases the funds chunk by chunk as the creator proves they've completed specific milestones.
If the creator fails or disappears, the robot protects you automatically by returning whatever is left in the vault.
Here is how I designed the mechanics to make that happen.
The Math Problem: Why 10,000 Basis Points?
When you build financial systems in Solidity, you quickly learn one thing: the Ethereum blockchain hates decimals.
If you try to divide $100 by 3, a normal computer gives you $33.3333... But Solidity doesn't do fractions well. Those leftover .3333 fractions (we call them "dust") can get permanently trapped in the contract. Over time, the math breaks.
To remove this ambiguity, I standardized everything using a financial concept called Basis Points (BPS). In this system, 10,000 BPS is exactly equal to 100%.
Instead of giving a creator a fixed amount of tokens, we give them slices of a pie.
- Phase 1 is
4000 BPS(40% of the pie). - Phase 2 is
4000 BPS(40% of the pie). - Phase 3 is
2000 BPS(20% of the pie).
Why is this pie method so important? Stretch goals.
Imagine a charity sets a goal of $10,000, but the campaign goes viral and raises $50,000. If our code said "Give the creator exactly $4,000 for Phase 1," the contract would get confused by the extra $40,000 sitting in the vault.
But because our milestones are percentages tied to the total amount raised, the math adapts automatically.
- 40% of $10,000 is $4,000.
- 40% of $50,000 is $20,000.
The pie gets bigger, but the sizes of the slices stay exactly the same. The code doesn't break.
Graceful Failure: The "Abandoned" State
Most smart contracts only understand black and white: Success or Failure.
- If the campaign fails to hit its goal, the robot opens the vault and gives everyone a 100% refund. Easy.
But what if the campaign succeeds, the creator takes 40% of the funds to start Phase 1, and then they vanish? You cannot pretend nothing happened. 100% of the money isn't there anymore.
This is where the "Defensive" part of the Defensive Escrow kicks in. I added a state called Abandoned.
If a creator goes rogue, an Admin can press a haltCampaign button. The robot permanently locks the vault.
The concept is simple: you are refunded based on the work that was never unlocked. If you pledged 10 ETH, and the creator ran away after taking 40%, the robot mathematically guarantees you get your remaining 6 ETH back.
This turns a "crypto scam" into a structured, safe process. There is no emotional arguing over who gets what. The math just settles the difference.
The Fiat Bridge: Bringing Web2 to Web3
Most Web3 systems make a fatal assumption: they assume every user already has a crypto wallet and knows how to pay gas fees. That assumption kills adoption.
Now, you might be thinking: "Wait, Obinna, don't we already have smart accounts where users can log in with their Gmail? Aren't there easy fiat on-ramps and off-ramps today?"
Yes, absolutely. The Web3 ecosystem has made massive strides with Account Abstraction and embedded wallets. However, I still chose to architect a direct platform-to-fiat bridge called pledgeFiatOnBehalf.
Why? Because true adoption requires absolute user flexibility. Some people simply do not want to go through a crypto on-ramp or manage a smart account even a hidden one. They want to type their credit card into a familiar website and be done in 30 seconds, remaining entirely Web2-native. By building a custodial bridge, we allow those users to participate natively, while their economic support is still mathematically secured in our smart contract.
If Bob pays $100 with a credit card on our website, our secure backend sees the payment. Then, our own "Platform Wallet" interacts with the smart contract, depositing $100 worth of crypto into the vault on Bob's behalf.
We act as a custodian for Bob. The messy credit card logic stays entirely off-chain, while the blockchain remains the ultimate, pristine source of truth for the project's funding.
The Trust Model: "Wait, isn't this centralized?"
If you have been reading closely, you might have noticed a recurring theme: an Admin or Platform wallet has the power to approve milestones, press the "Halt" button, and bridge fiat payments.
A developer might look at this and ask, "Wait, Obinna, isn't this centralized?"
It is a great question. Yes, there is a human element. But having an administrative role is not the same as having total system control. To understand why, you need to understand the concept of an Invariant.
In smart contract engineering, an Invariant is a mathematical law written into the code that can never, ever be broken. Not even by the creator. Not even by the Admin.
Here is the distinction:
- What the Admin CAN do: They can pause the protocol, tell the robot a milestone is finished, or press the "Halt" button to trigger refunds.
- What the Admin CANNOT do: They cannot withdraw user funds to their own wallet. They cannot bypass the milestone math. They cannot rewrite the refund logic.
The real protection is not governance, it's the strict math constraints written into the robot's code.
The trust model is simple: Humans can trigger states, but they cannot violate the financial laws of the system. That is the boundary.
The BinnaDev Takeaway
If I step back and summarize the architecture, this isn't just "crowdfunding with milestones."
It is a system where capital is locked into predictable, mathematical rules. Failure is not a disastrous rug-pull; it is a structured, mathematically safe process. Fiat and crypto are unified so anyone can participate on their own terms.
Or, to put it in one line:
Immutability handles correctness. Milestones handle trust. Invariants handle safety.
Now that we have written the rules of the protocol, how do we prove they actually work? How do we know a hacker can't break the math? In the next post, we are going to dive into Foundry Testing. I'll show you how I test these invariants to mathematically prove they hold up against any attack.



Top comments (0)