Skip to content

This crowdfunding escrow platform uses dominant assurance smart contracts to fund public goods and real world asset tokenization endeavors.

Notifications You must be signed in to change notification settings

Starmand6/op-crowdfund-dom-assurance

Repository files navigation

Crowdfunding Escrow Platform Using Dominant Assurance

Table of Contents
  1. About The Project
  2. Project Technicals
  3. Usage
  4. For The Devs
  5. Future Considerations
  6. Lessons Learned
  7. Contributing
  8. License
  9. Contact
  10. Acknowledgments

About The Project

This project translates Alex Tabarrok’s “dominant assurance” contracts idea to the blockchain in the form of a working escrow contract for the crowdfunding of a property. Click here for more info on dominant assurance. This alternative mechanism can be extended to fund any public good.

Using "DAOntown" as the main campaign example, any pledger that pledges to the campaign will be able to mint and claim DAOntown tokens, which could represent their share of governance rights, land use rights, etc. The token contract is presently written with the ERC20 standard, but could easily be replaced with the ERC721 or other token standard if desired.

DomCrowdfund.sol Crowdfunding Contract Functionality

  • createCampaign() is called by a campaign creator to populate the campaign struct for all users. Each campaign is given a unique campaign ID. The campaign struct is organized as follows:
    struct Campaign {
        string title;
        address creator;
        uint256 targetAmount;
        uint256 refundBonus;
        uint256 campaignExpiryDate;
        uint32 maxEarlyPledgers;
        address[] pledgers;
        address[] earlyPedgers;
        uint256 totalPledgedAmount;
        bool isGoalMet;
        bool hasCompletedRefunds;
        bool creatorHasWithdrawnFunds;
    }
  • pledge() will make a pledge to the campaign associated with the campaign ID that the user enters. Pledge sends funds to the crowdfunding platform contract.
  • withdrawRefund() is only callable after a campaign expires that has not met its goal. This function can only be called by pledgers of the specific unsuccessful campaign.
  • creatorWithdrawal() can only be called by the creator of the specific campaign ID entered as an argument. This function can only be called upon successful campaign. Creator can choose any address to withdraw all the campaign funds to.
  • A bunch of getters: getCampaignInfo(), getCampaignFundingStatus(), getCampaignCount(), getBalance(), getCampaignEarlyPledgers(), getCampaignPledgers(), getAmountPledged(), getAddress(), getCampaignRefundsCompleted(), getCampaignAmountRefunded(), getEarlyRefundCalc()

DAOntownToken.sol XRC20 Token Contract Functionality

  • claimDAOntownTokens() is really the only function that can be called on this contract by campaign pledgers. In this project example, DAOntown tokens are minted and sent 1-for-1 to pledgers based on how much ETH they pledged to the campaign. These tokens can be used as governance tokens, land use right tokens, etc.
  • mint() can only be called by the token contract owner. Ownership could be transferred to a multisig after a successful campaign so that the property token holders can vote on if they want to mint more tokens or keep with the existing supply.

(back to top)

Project Technicals

Crowdfund w/ Dominant Assurance (DomCrowdfund.sol) Contract Address: 0x81fa7a47bE7BBa84a6391773e8481725310563C8

Crowdfund Contract Page - Optimism-Goerli Testnet

DAOntown Token (DAOntownToken.sol) Contract Address: 0xAB9098d0C2F056f7b3BfacDFc8A67ceb4CF185f8

DAOntown Token Contract Page - Optimism-Goerli Testnet

Live Crowdfunding dApp Link

Test Coverage Report:

Alt text

(back to top)

Usage

  • Testnet ETH is needed to interact with the app. It can be obtained from this faucet, then bridged to Optimism Goerli.

  • Please use MetaMask to interact with the app.

  • Most everything is tied to the campaign ID#. Users need it when calling functions for pledging, withdrawing, and claiming tokens.

  • Though the smart contracts are working properly on chain, the front end has some visual bugs. To interact with a full life cycle of a campaign, after you have created the campaign, do not refresh the page until you are done interacting with that campaign. Refreshes will wipe the slate clean, though you can still find the campaign you just created or an older one using the Find Campaign element. If the front end gets extra bug-y for some reason, as a reminder, the crowdfunding smart contract is working as intended, so you can always run through complete life cycles using the Block Explorer Read and Write Contract pages, since the contract is verified.

Here's a couple of screenshots of the app in action:

Alt text

Alt text

(back to top)

For The Devs

For quickstart, clone the repo using the link from Github, cd into directory, and run npm install.

Then cd into the /app directory and run npm install.

To launch the front-end application, run npm start from the /app directory. Open http://localhost:3000 to view it in your browser.

Development Stack, Plugins, Libraries, and Dependencies

  • Smart contracts: Solidity, Hardhat (deploy, toolbox, chai matchers, mocha, network helpers), Ethers, prettier, solhint
  • OpenZeppelin inherited contracts: Ownable, ReentrancyGuard
  • Front End: React, Webpack, Craco, Babel, Ethers, detectEthereumProvider

(back to top)

Future Considerations

  • Add edge case or bizarre case testing in unit tests and staging tests.
  • Add user action feedback, e.g. creating visual displays when a campaign has met a goal from a pledge, error messaging, etc.
  • Add more functionality on the front end to get more precise info for existing or past campaigns.
  • Add more flexibility in the user inputs for payment amounts and campaign lengths.

(back to top)

Lessons Learned

  • I have to remind myself that bug locations are often not in obvious places. If a particular element is not working properly, there's a good chance it is because of another element elsewhere. Slowing down and backing up can help bring more causes and effects into focus.

(back to top)

Contributing

Scott Auriat was the main consultant and sounding board for this project.

(back to top)

License

Distributed under the MIT License.

(back to top)

Contact

Armand Daigle - @_Starmand - armanddaoist@gmail.com

(back to top)

Acknowledgments and Resources

Thanks to Scott Auriat for his consultation on different aspects, as well as introducing me to the dominant assurance strategy.

A big thanks to the fellow Alchemy University students and community for helping me learn a lot about React.

(back to top)

About

This crowdfunding escrow platform uses dominant assurance smart contracts to fund public goods and real world asset tokenization endeavors.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published