GoodDocs
  • Welcome to GoodDocs!
  • GoodDollar Ecosystem Vision
  • About the Protocol
    • Usage
    • Tokenomics
    • Sybil-Resistance
    • Protocol V3 Documentation
      • Architecture & Value Flow
      • System's Elements
      • Core Contracts & API
        • GoodDollar
        • GoodCompoundStaking V2 (DAI)
        • GoodAaveStaking V2 (USDC)
        • GoodReserveCDai
        • GoodFundManager
        • GoodMarketMaker
        • ContributionCalculation
        • UBIScheme
        • Identity
        • FirstClaimPool
        • AdminWallet
        • OneTimePayments
        • DonationsStaking
        • NameService
        • GReputation
        • CompoundVotingMachine
        • StakersDistribution
        • UniswapV2SwapHelper
        • Invites
        • GovernanceStaking
        • ClaimersDistribution
        • CompoundStakingFactory
        • AaveStakingFactory
        • ExchangeHelper
        • FuseFaucet
        • GoodDollarMintBurnWrapper
      • Previous Protocol Versions
        • Protocol V1
          • Architecture & Value Flow
          • Core Contracts & API
        • Protocol V2
          • Architecture & Value Flow
          • System's Elements
            • 1. The token (G$)
            • 2. The Reserve
            • 3. The Trust
            • 4. Staking rewards (APR)
            • 5. The Fund Manager
            • 6. The Distribution Contract (DisCo)
            • 7. Governance (DAO)
          • Core Contracts & API
            • GoodDollar
            • GoodCompoundStaking V2 (DAI)
            • GoodAaveStaking V2 (USDC)
            • GoodReserveCDai
            • GoodFundManager
            • GoodMarketMaker
            • ContributionCalculation
            • UBIScheme
            • Identity
            • FirstClaimPool
            • AdminWallet
            • OneTimePayments
            • DonationsStaking
            • NameService
            • GReputation
            • CompoundVotingMachine
            • StakersDistribution
            • UniswapV2SwapHelper
            • Invites
            • GovernanceStaking
            • ClaimersDistribution
            • CompoundStakingFactory
            • AaveStakingFactory
            • ExchangeHelper
            • FuseFaucet
  • User Guides
    • Buy & Sell G$
    • Stake to create UBI
    • Claim GOOD and G$X
    • Bridge GoodDollars
    • Connect another wallet address to identity
  • Liquidity
  • Wallet and Products
    • GoodWallet
    • GoodDapp
    • New GoodWallet
    • GoodCollective
    • GoodID & GoodOffers
    • 3rd Party Partners and Integrations
  • Frequently Asked Questions
    • Web3 basic knowledge and security tips - by Consensys
    • About GoodDollar
    • GoodDollar Protocol & G$ Token
    • Using GoodDollar
    • GoodDollar Community
    • Troubleshooting
  • For Developers
    • Contributing to GoodDollar
    • GoodDapp Developer Guides
      • Deploy your own GoodDapp UI
      • How to integrate the G$ token
      • Use G$ streaming
      • Ethers V5/useDapp Context Setup
    • APIs & SDKs
      • UBI
        • Claim UBI (Ethers v5/ React)
        • Claim UBI (Viem/Wagmi)
        • Claim UBI (Web-components)
      • Sybil Resistance
        • Identity (Ethers v5 / React)
        • Identity (Viem/Wagmi)
  • Useful Links
    • GoodDollar.org
    • GoodDapp
    • GoodWallet
    • GoodDollar User Guides
    • Statistics Dashboard
    • GoodDollar Whitepaper
    • GoodDollar Litepaper
    • GoodDollar Litepaper - Español
Powered by GitBook
On this page
  • Contracts & API
  • Core Contracts
  • Core Contracts
  • GoodDollar G$ ERC-20
  • GoodReserve
  • GoodFundManager
  • UBIScheme
  • Identity
  • OneTimePayments
  • DonationsStaking
  • GoodMarketMaker
  • ContributionCalculation
  • FirstClaimPool
  • AdminWallet
  • Token Bridge Contracts
  • Token Bridge Contracts
  • DAO Contracts
  • DAO Contracts

Was this helpful?

  1. About the Protocol
  2. Protocol V3 Documentation
  3. Previous Protocol Versions
  4. Protocol V1

Core Contracts & API

This page provides contract addresses for key components of GoodDollar protocol.

Contracts & API

GoodDollar Protocol is deployed on both the Ethereum mainnet and on the Fuse sidechain. Contracts like the GoodReserve are only on Mainnet, and other contracts like the UBIScheme are only on the Fuse sidechain. Certain contracts, such as the DAO and G$ Token contracts, are deployed on both networks.

Core Contracts

Core Contracts

Contract
Mainnet
Fuse
Source code

GoodDollar G$ ERC-20

GoodDollar G$ ERC-20

The GoodDollar G$ token follows the ERC-20 token standard and also supports ERC-677.

GoodStaking

GoodStaking

Supporters / stakers can stake crypto which is then sent to permissionless protocols which earn interest. The FundManager has permissions to collect interest-earned from this contract.

/**
 * @dev Allows a staker to deposit DAI tokens. Notice that `approve` is
 * needed to be executed before the execution of this method.
 * Can be executed only when the contract is not paused.
 * @param _amount The amount of DAI to stake
 */
function stakeDAI(uint256 _amount) public whenNotPaused

/**
 * @dev Withdraws the sender staked DAI.
 */
function withdrawStake() public

GoodReserve

GoodReserve

The GoodReserve mints G$ based on the interest transferred from the FundManager. Only the FundManager can trigger minting. The GoodReserve also acts as the GoodDollar liquidity pool and AMM (Automatic Market Maker) and enables methods to buy and sell G$s.

/**
 * @dev Converts `buyWith` tokens to GD tokens and updates the bonding curve params.
 * `buy` occurs only if the GD return is above the given minimum. It is possible
 * to buy only with cDAI and when the contract is set to active. 
 * MUST `approve` prior this action to allow this contract to accomplish the
 * conversion.
 * @param _buyWith The tokens that should be converted to GD tokens
 * @param _tokenAmount The amount of `buyWith` tokens that should be converted to GD tokens
 * @param _minReturn The minimum allowed return in GD tokens
 * @return (gdReturn) How much GD tokens were transferred
 */
function buy(ERC20 _buyWith,uint256 _tokenAmount,uint256 _minReturn) public requireActive onlyCDai(_buyWith) returns (uint256)

/**
 * @dev Converts GD tokens to `sellTo` tokens and update the bonding curve params.
 * `sell` occurs only if the token return is above the given minimum. Notice that
 * there is a contribution amount from the given GD that remains in the reserve.
 * It is only possible to sell to cDAI and only when the contract is set to
 * active. MUST make call to G$ `approve` prior to this action to allow this
 * contract to accomplish the conversion.
 * @param _sellTo The tokens that will be received after the conversion
 * @param _gdAmount The amount of GD tokens that should be converted to `_sellTo` tokens
 * @param _minReturn The minimum allowed `sellTo` tokens return
 * @return (tokenReturn) How much `sellTo` tokens were transferred
 */

function sell(
    ERC20 _sellTo,
    uint256 _gdAmount,
    uint256 _minReturn
) public requireActive onlyCDai(_sellTo) returns (uint256)

/**
 * @dev Current price of GD in `token`. currently only cDAI is supported.
 * @param _token The desired reserve token to have
 * @return price of GD
 */
function currentPrice(ERC20 _token) public view returns (uint256)

GoodFundManager

GoodFundManager

Has permissions to collect interest from the GoodStaking contract and permissions to tell GoodReserve to mint. Anyone can trigger the collection and minting process

/**
 * @dev Collects UBI interest in cDai from a given staking contract and transfers
 * that interest to the reserve contract. Then transfers the gd
 * received from the reserve contract back to the staking contract and to the
 * bridge, which locks the funds and then same amount of G$ tokens are minted to the
 * ubiRecipient address on the sidechain
 *
 * @param _staking Contract that implements `collectUBIInterest` and transfer cDai to
 * a given address. The given address should be the same whitelisted `reserve`
 * address in the current contract, in case that the given staking contract transfers
 * the funds to another contract, zero GD tokens will be minted by the reserve contract.
 * Emits `FundsTransferred` event in case which interest has been passed to the `reserve`
 */
function transferInterest(StakingContract _staking)
    public
    requireActive
    reserveHasInitialized
    requireDAOContract(address(_staking))

UBIScheme

UBIScheme

Holds all the G$s that were transferred via bridge from the FundManager. The pool of G$s is divided equally by the amount of current active users, and distributed every day. Each active user can then "claim" his quota. If a user fails to claim his quota it becomes part of the next day's pool of G$ to be distributed as basic income.

/**
 * @dev Checks the amount which the sender address is eligible to claim for,
 * regardless if they have been whitelisted or not.
 * @return The amount of GD tokens the address can claim.
 */
function checkEntitlement() public view requireActive returns (uint256)

/**
 * @dev Function for claiming UBI. Requires contract to be active and claimer to be whitelisted.
 * Calls distributionFormula, calculats the amount the caller can claim, and transfers the amount
 * to the caller. Emits the address of caller and amount claimed.
 * @return A bool indicating if UBI was claimed
 */
function claim() public requireActive onlyWhitelisted returns (bool)

/**
 * @dev In order to update users from active to inactive, we give out incentive to people
 * to update the status of inactive users, this action is called "Fishing". Anyone can
 * send a tx to the contract to mark inactive users. The "fisherman" receives a reward
 * equal to the daily UBI (ie instead of the “fished” user). User that “last claimed” > 14
 * can be "fished" and made inactive (reduces active users count by one). Requires
 * contract to be active.
 * @param _account to fish
 * @return A bool indicating if UBI was fished
 */
function fish(address _account) public requireActive returns (bool)

/**
 * @dev executes `fish` with multiple addresses. emits the number of users from the given
 * array who actually been tried being fished.
 * @param _accounts to fish
 * @return A bool indicating if all the UBIs were fished
 */
function fishMulti(address[] memory _accounts)

Identity

Identity

The identity contract controls addresses that are whitelisted to "Claim" UBI.

  • Face Verification GoodDollar currently whitelists users based on a user proving "uniqueness" by signing up with a live and unique face. All image data and details are anonymized in order to allow the user to create a new account in case he is unable to recover his wallet. Facial details are deleted after authenticationPeriod and users are required to perform face verification again every authenticationPeriod days.

  • Social Profile Each blockchain address is linked to the user's public profile as created in the wallet. The DID is the node id in the public p2p GunDB database. Mappings from wallet address to DID are held in addrTODID

/* 
 * @dev Returns true if given address has been added to whitelist
 * @param account the address to check
 * @return a bool indicating weather the address is present in whitelist
*/
function isWhitelisted(address account) public view returns (bool)

/* 
 * @dev Function that gives the date the given user was added
 * @param account The address to check
 * @return The date the address was added
*/
function lastAuthenticated(address account) public view returns (uint256)

/* the number of days an authentication is valid for*/
uint256 public authenticationPeriod

mapping(address => string) public addrToDID;

OneTimePayments

OneTimePayments

/* 
* @dev ERC677 on token transfer function. When transferAndCall is called on this contract,
 * this function is called, depositing the payment amount under the hash of the given bytes.
 * Reverts if hash is already in use. Can only be called by token contract.
 * @param sender the address of the sender
 * @param value the amount to deposit
 * @param data The given paymentId which should be a fresh public key
 */

to deposit a payment to a one time payment address call:
GoodDollar.transferAndCall(value,data) this will trigger OneTimePayments onTokenTransfer

/* @dev Withdrawal function.
 * allows the sender that proves ownership of paymentId to withdraw
 * @param paymentId the address of the public key that the
 *   rightful receiver of the payment knows the private key to
 * @param signature the signature of a the message containing the msg.sender address signed
 *   with the private key.
 */
function withdraw(address paymentId, bytes memory signature) public onlyRegistered

/* @dev Cancel function
 * allows only creator of payment to cancel
 * @param paymentId The paymentId of the payment to cancelæ
 */
function cancel(address paymentId) public

DonationsStaking

DonationsStaking

Any ETH/DAI sent to this contract address is donated to the GoodDollar DAO and will generate interest to fund UBI. The funds are periodically staked in the GoodStaking contract by calling the stakeDonationsmethod.

    uint256 public totalETHDonated;
    uint256 public totalDAIDonated;

    event DonationStaked(
        address caller,
        uint256 stakedDAI,
        uint256 ethDonated,
        uint256 daiDonated
    );

    /**
     * @dev stake available funds. It
     * take balance in eth and buy DAI from uniswap then stake outstanding DAI balance.
     * anyone can call this.
     * @param _minDAIAmount enforce expected return from uniswap when converting eth balance to DAI
     */
    function stakeDonations(uint256 _minDAIAmount) public payable isActive {
        uint256 daiDonated = DAI.balanceOf(address(this));
        uint256 ethDonated = _buyDAI(_minDAIAmount);

        uint256 daiBalance = DAI.balanceOf(address(this));
        require(daiBalance > 0, "no DAI to stake");

        stakingContract.stakeDAI(daiBalance);
        totalETHDonated += ethDonated;
        totalDAIDonated += daiDonated;
        emit DonationStaked(msg.sender, daiBalance, ethDonated, daiDonated);
    }

    /**
     * @dev total DAI value staked
     * @return DAI value staked
     */
    function totalStaked() public view returns (uint256) {
        Staking.Staker memory staker = stakingContract.stakers(address(this));
        return staker.stakedDAI;
    }

GoodMarketMaker

GoodMarketMaker

Helper contract for the GoodReserve.

ContributionCalculation

ContributionCalculation

Helper contract for calculating the exit contribution (ie when selling G$ back to the reserve)

FirstClaimPool

FirstClaimPool

Helper contract for UBIScheme. Manually funded by the Foundation to give 1G$ for "inactive" users when they claim. Since a new user (inactive) becomes active and eligible to claim UBI only in the next UBI epoch. So for new users not go empty handed on their first claim we give out a 1G$.

AdminWallet

AdminWallet

Helper contract for our backend servers to whitelist users and to fill their Fuse network gas.

Token Bridge Contracts

Token Bridge Contracts

DAO Contracts

Contract
Mainnet
Fuse
Source Code

ForeignBridge (mainnet -> fuse)

HomeBridge (fuse -> mainnet)

DAO Contracts

Contract
Mainnet
Fuse
Source Code

Controller

Avatar

Reputation

SchemeRegistrar

AbsoluteVote

UpgradeScheme

PreviousArchitecture & Value FlowNextProtocol V2

Last updated 3 years ago

Was this helpful?

Payments on the GoodDollar wallet are done via payment links. G$s are held in escrow and the recipient can retrieve the funds if he has the key. While the money is in escrow the sender can choose to cancel the payment and retrieve the funds. Based on payments contract.

Bridge contracts were developed by .

Note: for regular users it is recommended to use FuseSwap Bridge in order to avoid losing your tokens (). FuseSwap Bridge: | .

Note: for regular users it is recommended to use FuseSwap Bridge in order to avoid losing your tokens (). FuseSwap Bridge: | .

DAO contracts were developed by

Celo's
Fuse
help
Mainnet -> Fuse
Fuse -> Mainnet
help
Mainnet -> Fuse
Fuse -> Mainnet
DAOStack
GoodDollar ERC20
0x67C5870b4A41D4Ebef24d2456547A03F1f3e094B
0x495d133B938596C9984d462F007B676bDc57eCEC
GoodDollar.sol
GoodStaking
0xEa12bB3917cf6aE2FDE97cE4756177703426d41F
SimpleDAIStaking.sol
GoodReserve
0x5C16960F2Eeba27b7de4F1F6e84E616C1977e070
GoodReserveCDai.sol
GoodFundManager
0xbDFD60f3aE73329D33ebe17d78383DEfd72643Ad
GoodFundManager.sol
GoodMarketMaker
0xEDbE438Cd865992fDB72dd252E6055A71b02BE72
GoodMarketMaker.sol
ContributionCalculation
0x8eEC64bb6807c0178f96277cCE6a334B4e565E5C
ContributionCalculation.sol
UBIScheme
0xD7aC544F8A570C4d8764c3AAbCF6870CBD960D0D
UBIScheme.sol
Identity
0x76e76e10Ac308A1D54a00f9df27EdCE4801F288b
0xFa8d865A962ca8456dF331D78806152d3aC5B84F
Identity.sol
FirstClaimPool
0x18BcdF79A724648bF34eb06701be81bD072A2384
FirstClaimPool.sol
AdminWallet
0x9F75dAcB77419b87f568d417eBc84346e134144E
AdminWallet.sol
OneTimePayments
0xd9Aa86e0Ddb932bD78ab8c71C1B98F83cF610Bd4
OneTimePayments.sol
DonationsStaking
0x93fb057eec37abc11d955d1c09e6a0d218f35cff
DonationsStakinng.sol
0xD5D11eE582c8931F336fbcd135e98CEE4DB8CCB0
ForeignAMBErc677ToErc677.sol
0xD39021DB018E2CAEadb4B2e6717D31550e7918D0
HomeAMBErc677ToErc677.sol
0x95C0d9dCEA1E243ED696F34CAc5e6559C3c128a3
0xBcE053b99e22158f8B62f4DBFbEdE1f936b2D4e4
Controller.sol
0x1ecFD1afb601C406fF0e13c3485f2d75699b6817
0xf96dADc6D71113F6500e97590760C924dA1eF70e
Avatar.sol
0xCb4a6aF3b15D64E8f50B3cea54c4f481d9E434C1
0x0be7C592374EE0bD0CcBFC76Be758a138BcaEc6E
Reputation.sol
0x098148534aC15A44CFF52387bA81Ed929589eCAf
0x12F706FaafCBf8093282Dba0c40eD0D4Eb5CAF54
SchemeRegistrar.sol
0xf6b5F7a885CBc57d739aDBEe76E52A70Bc04D795
0xf6b5F7a885CBc57d739aDBEe76E52A70Bc04D795
AbsoluteVote.sol
0xF9B357d83BDAD6881feb09d909095872B93203d0
0x653c67Be5b3739708e84B61641253822405d78D8
UpgradeScheme.sol