This sample Solidity Smart Contract is for a funding pool. It allows for any address to contribute to the funding pool by sending ether directly to the contract. Addresses that have sent ether to the contract would then be eligible to vote. 1 wei = 1 vote. The address that receives the threshold amount of votes (10 ether) would be eligible to get the total balance of the pot.
- the funding pool is a smart contract
- allows anyone to contribute to the funding pool
- funding pool allows for distribution of funds
- funds are distributed wholly (total balance)
- funds are distributed to a single recipient
- the recipient is chosen via voting
- only contributors can vote
- only owner can distribute
- voting weights are proportionate to contributions made to the pool
- the contract owner can be trusted to only call distribute() after doing due dilligence on the to-be recipient
- this contract's design makes it a one use contract
- ownership is not transferrable in the current implementation
transferandsendwill not work since the receive() function requires more than 2300 gas as it calls_contribute
- there is a reliance on the contract owner to validate the
toaddress fordistribute()(that it has the highest number of votes and is a legitimate candidate) - this contract allows the contract owner to call
distribute()for any address that has more than the threshold amount of votes
- Foundry (includes Forge, Cast, and Anvil)
- Git
- Clone the repository
git clone https://github.com/your-username/solidity-funding-pool.git
cd solidity-funding-pool- Install dependencies
forge installCompile the contracts:
forge buildView contract sizes:
forge build --sizesRun all tests:
forge testRun tests with verbose output:
forge test -vvvRun a specific test:
forge test --match-test testFunctionName -vvv- Set up your environment variables (Create a
.envfile):
PRIVATE_KEY=your_private_key
RPC_URL=your_rpc_url
- Deploy to a network:
source .env
forge script script/FundingPool.sol:FundingPoolScript --rpc-url https://optimism-sepolia.gateway.tenderly.co --account default --sender <SENDER_ADDRESS> --broadcastAfter deployment, you can interact with the contract using Cast:
- Contribute funds:
cast send <CONTRACT_ADDRESS> --value <AMOUNT_IN_ETH>ether --private-key $PRIVATE_KEY- Vote for a recipient:
cast send <CONTRACT_ADDRESS> "vote(address,uint256)" <RECIPIENT_ADDRESS> <VOTES_TO_CAST> --private-key $PRIVATE_KEY- Distribute funds (owner only):
cast send <CONTRACT_ADDRESS> "distribute(address)" <RECIPIENT_ADDRESS> --private-key $PRIVATE_KEY- Check contributions:
cast call <CONTRACT_ADDRESS> "contributions(address)" <CONTRIBUTOR_ADDRESS>- Check votes received:
cast call <CONTRACT_ADDRESS> "votesReceived(address)" <RECIPIENT_ADDRESS>- Start a local Ethereum node:
anvil- Deploy to local node:
forge script script/FundingPool.sol:FundingPoolScript --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcastThe private key above is Anvil's default first account private key.
Generate test coverage report:
forge coverageGenerate gas usage report:
forge test --gas-report