Give Protocol Documentation

Smart Contract Interactions

Understanding how to interact with Give Protocol’s smart contracts for building integrations and custom applications.

Core Smart Contracts

DurationDonation Contract

The main contract handling all donation operations:

// Basic donation function
function donate(
    address charity,
    address token,
    uint256 amount,
    string memory message
) external payable;

// Scheduled donation setup
function createScheduledDonation(
    address charity,
    address token,
    uint256 totalAmount,
    uint256 frequency,
    uint256 duration
) external;

VolunteerVerification Contract

Manages volunteer hour verification and NFT rewards:

// Submit volunteer hours for verification
function submitVolunteerHours(
    address charity,
    uint256 hours,
    string memory description,
    bytes32 proofHash
) external;

// Verify and mint NFT reward
function verifyAndReward(
    uint256 submissionId,
    address volunteer,
    uint256 hours
) external onlyVerifier;

Integration Examples

Web3.js Integration

const Web3 = require("web3");
const DurationDonationABI = require("./DurationDonation.json");

const web3 = new Web3("https://rpc.api.moonbeam.network");
const contract = new web3.eth.Contract(
  DurationDonationABI.abi,
  "0x...", // Contract address
);

// Make a donation
async function makeDonation(from, charity, amount) {
  const tx = await contract.methods
    .donate(charity, "0x0", amount, "One-time donation")
    .send({ from, value: amount });

  return tx.transactionHash;
}

Ethers.js Integration

const { ethers } = require("ethers");
const DurationDonationABI = require("./DurationDonation.json");

const provider = new ethers.JsonRpcProvider("https://rpc.api.moonbeam.network");
const contract = new ethers.Contract(
  "0x...", // Contract address
  DurationDonationABI.abi,
  provider,
);

// Listen for donation events
contract.on("DonationMade", (donor, charity, amount, event) => {
  console.log(`Donation: ${donor}${charity}: ${amount} GLMR`);
});

Event Monitoring

Key Events

// Donation events
event DonationMade(
    address indexed donor,
    address indexed charity,
    uint256 amount,
    address token,
    string message
);

// Verification events
event VolunteerHoursSubmitted(
    address indexed volunteer,
    address indexed charity,
    uint256 hours,
    uint256 submissionId
);

event VolunteerHoursVerified(
    uint256 indexed submissionId,
    address indexed volunteer,
    uint256 hours,
    uint256 nftTokenId
);

Event Filtering

// Filter donations to specific charity
const filter = contract.filters.DonationMade(null, charityAddress);
const events = await contract.queryFilter(filter, fromBlock, toBlock);

// Real-time event listening
contract.on(filter, (donor, charity, amount, token, message, event) => {
  // Handle new donation
});

Error Handling

Common Errors

// Custom error types
error InsufficientBalance(uint256 required, uint256 available);
error UnauthorizedVerifier(address caller);
error InvalidCharityAddress(address charity);
error ExceedsMaxDonation(uint256 amount, uint256 max);

Error Handling in JavaScript

try {
  const tx = await contract.donate(charity, token, amount, message);
  await tx.wait();
} catch (error) {
  if (error.reason === "InsufficientBalance") {
    // Handle insufficient balance
  } else if (error.reason === "InvalidCharityAddress") {
    // Handle invalid charity
  } else {
    // Handle generic error
  }
}

Gas Optimization

Batch Operations

// Batch multiple donations
function batchDonate(
    DonationData[] calldata donations
) external payable {
    for (uint i = 0; i < donations.length; i++) {
        _processDonation(donations[i]);
    }
}

Gas Estimation

// Estimate gas before transaction
const gasEstimate = await contract.estimateGas.donate(
  charity,
  token,
  amount,
  message,
);

// Add 20% buffer for safety
const gasLimit = gasEstimate.mul(120).div(100);

const tx = await contract.donate(charity, token, amount, message, {
  gasLimit,
});

Security Best Practices

Input Validation

  • Always validate addresses before contract calls
  • Check token approvals before transfers
  • Verify amounts are within acceptable ranges
  • Sanitize string inputs to prevent injection

Transaction Safety

  • Use proper error handling for all transactions
  • Implement transaction retry logic with exponential backoff
  • Monitor for failed transactions and handle appropriately
  • Use multicall patterns for complex operations

Access Control

  • Implement proper role-based access control
  • Use time locks for sensitive operations
  • Require multiple signatures for large transactions
  • Regular security audits and updates

Testing

Unit Tests

describe("DurationDonation", function () {
  it("should process donation correctly", async function () {
    const tx = await contract.donate(
      charity.address,
      ethers.constants.AddressZero,
      ethers.utils.parseEther("1.0"),
      "Test donation",
    );

    expect(tx).to.emit(contract, "DonationMade");
  });
});

Integration Tests

// Test full donation flow
it("should complete end-to-end donation", async function () {
  // 1. Approve tokens if needed
  // 2. Make donation
  // 3. Verify events emitted
  // 4. Check balances updated
  // 5. Confirm charity received funds
});

Need Help?

Visit our API Documentation for REST API details or check out the blockchain integration guide for more context.

Last updated: August 25, 2025

Search Results

Navigate
Enter Select
Esc Close