Giter Site home page Giter Site logo

goldfinch-eng / mono Goto Github PK

View Code? Open in Web Editor NEW
53.0 8.0 40.0 64.01 MB

The main Goldfinch monorepo, including contracts, front-ends, etc.

License: MIT License

Dockerfile 0.04% Shell 0.08% JavaScript 0.53% TypeScript 50.13% HTML 0.01% Solidity 49.15% CSS 0.07% Handlebars 0.01%

mono's Introduction

Goldfinch Protocol icon

Goldfinch Protocol

Goldfinch is a decentralized lending protocol built on the blockchain. This is a monorepo containing Goldfinch's smart contracts, web3 frontend, and other supporting code. For the latest documentation, check out our docs.

Stay up to date by joining our Goldfinch Discord server or following us on Twitter @goldfinch_fi.

Software Development Set Up

  • Install VSCode
  • Clone this repo to your local computer

When you open the project in a new VSCode window, a pop up will display which will allow you to install all the recommended extensions for the repo.

Installation

Goldfinch requires NodeJS to get up and running. We recommend using nvm to manage the Node installation. Once nvm is installed, set up the environment from the project root by running

# setup Node using the version defined in .nvmrc
nvm install

# install yarn for package & workspace management
npm install --global yarn 

Now that the environment is set up, prepare the projects with

# install all dependencies
yarn install

This will also install Husky for utilizing Git Hooks.

At this point, you may wish to yarn build:core in order to build some of the commonly-used artifacts between packages. This will enable yarn start:local or yarn start if you are planning to use those.

Other Requirements

For certain packages, you may also need to:

  • Install python and add it to your path. Some of the dependencies require node-gyp, which compiles native addons using python. If you don't have python, we recommend using pyenv, which has instructions here.
  • Install Java. The frontend requires Java for the Firebase emulator.

Monorepo

  • packages/: Contains all typescript packages and contracts.
    • protocol/ (@goldfinch-eng/protocol): Solidity smart contracts and tests.
    • client2/ (@goldfinch-eng/client2): Web3 frontend using React.
    • subgraph/ (@goldfinch-eng/subgraph): Subgraph powering the frontend.
    • functions/ (@goldfinch-eng/functions): Google cloud functions to support KYC and other server-side functionality.
    • autotasks/ (@goldfinch-eng/autotasks): Defender Autotasks and Relay code for triggering periodic on-chain calls.
    • utils/ (@goldfinch-eng/utils): Generally useful utilities that are shared across packages.
    • docs/ (@goldfinch-eng/docs): Static site of protocol documentation.

Smart Contract Development

All contracts are located under packages/protocol/contracts

Setup

Copy the .env.example at the workspace root to a new file .env.local. Fill in the TEST_USER field with some development address that you control.

Testing

All tests should be under packages/protocol/tests. There are two kinds of tests. "Regular" (all local state) and "mainnet forking" (uses state from mainnet). They are located in different folders. Sometimes you write both for the same feature. Use your judgement depending on the change.

Mainnet Forking

Run yarn test:mainnet-forking in packages/protocol

Regular Tests

Run forge test in packages/protocol

If you don't already have Foundry installed:

  • Install Foundry using the instructions here: https://github.com/foundry-rs/foundry
  • Once installed, run the foundry-tool.sh script in packages/protocol
    • This will set up Foundry and prepare the git submodules
  • In the future, you should run forge install in packages/protocol to update your forge dependencies.

Coverage

Run yarn test:coverage in the protocol package to generate a coverage report for smart contract typescript tests. You can specify a set of files with a glob pattern, e.g. yarn test:coverage -- --testfiles test/TranchedPool.test.ts. See soliditiy-coverage for more info.

Tenderly debugging

We have the ability to debug/profile local transactions via Tenderly. To do this, get hold of a transaction hash and then run:

# Ensure tenderly-cli is installed via `brew tap tenderly/tenderly && brew install tenderly`
# And run this from the protocol directory
tenderly export --force <txhash>

To get a local transaction, run the app as normal, and make the transaction via the frontend, and get the hash from metamask after it's confirmed.

To get a test transaction, write a MainnetForking test, log the transaction hash in the test. Then run the mainnet forking test via:

# Run from the protocol directory
yarn test:tenderly

Pick up the transaction hash from the output of the test and run export as above

Compilation

Generally speaking, you shouldn't need to do this, since the test command automatically compiles. But if you need to independently compile, you can run:

yarn build

This will run build in all packages in the monorepo, including compiling the contracts. Beware this takes a long time to run, and if you don't have environment variables set up in every package that requires it, it may fail.

Alternatively, there's a lightweight version of build:

yarn build:core

This will build a handful of packages and get you ready to yarn start:local or yarn start.

Frontend Development

The frontend is located in packages/client2

Setup

Within packages/client2:

  1. Copy .env.example to .env.local
  2. Find the following variables in .env.local and update them with your API key and EOA address. Our local dev scripts will use these to automatically send you test ETH, and give you a credit line and USDC to play with
    TEST_USER={your metamask address}
    
    // only necessary if running a mainnet-forked frontend
    ALCHEMY_API_KEY={your alchemy api key}

Running

(Make sure you have run yarn build:core once before this)

  • yarn start:local
    • The simplest way to get going. All fresh, local state.
  • yarn start

Both options will start several processes, including your local blockchain and front-end server. It takes a min to spin up.

Once the services are running, go into packages/client2 and run yarn dev to start the client.

Changes to the frontend should be automatically hotloaded using react-refresh, but changes to smart contracts will require re-compiling and re-deploying. You can do this by re-running your start command.

Note When running with start:local, the Fake USDC address that we create will also not be visible to Metamask by default. So you'll need to add this as well by looking at the terminal output of the @goldfinch-eng/protocol start command. Search "USDC Address", and you should see something. Take that address, and then go to Add Token in Metamask, and paste it in there. Your fake USDC balance should show up.

Contributing

See the CONTRIBUTING.MD

Security

See the SECURITY.MD

Deployment

Local deployment

Contract deployment is handled automatically through the yarn start command, using hardhat-deploy and custom build scripts in packages/protocol/blockchain_scripts.

Mainnet deployments

Contracts are already deployed to mainnet. We write custom scripts to do upgrades or deploy new contracts.

Troubleshooting

Unrecognized network name

Similar errors: Accounts array must not be empty, ADD_YOUR_METAMASK_ADDRESS_HERE

It's possible your local environment is not set up properly (or at all). You may need to create an .env.local file. Wherever these are needed, there is always an .env.example file that you can copy and rename.

See "One time setup" in "Frontend Development" for an example of this.

Frontend

Front-end blockchain development is still early, and has rough edges. Here are some issues you might run into. If you see others, please add them here!

  • Authorization required Make sure you have your Alchemy API key set in .env.local
  • Cannot set headers of undefined. If you see this on the front-end, and the whole app blew up, then try switching your metamask off of the current network, and then back again (eg. to Mainnet and then back to Localhost)
  • Error: [ethjs-rpc] rpc error with payload. This may look like a failed transaction, and Metamask is just throwing some random error with no help. If you're pretty sure everything should be fine, then try to shut down your local server, restart it, and then before you try any transactions, reset your Metamask account, and switch away and back to the local network (eg. local -> mainnet -> local). To reset your Metamask account, click Metamask --> Settings --> Advanced --> Reset Account. This is fast and painless
  • If Metamask is unable to / times-out while trying to connect to Localhost 8545: rm deployments/localhost, and then re-running yarn start:local, was observed to fix this problem and enable Metamask to connect.
  • Error: a provider or signer is needed to resolve ENS names. You probably have an undefined address somewhere. But generally it means Ethers doesn't understand the address and is trying to interpret it as an ENS address.

Appendix

Testing

For testing the whole repo, run yarn test from the root

Testing UID Locally

  • Start the app
  • Connect with an account that is not golisted and no UID
  • Navigate to /verify
  • Use the DevTools and press the kyc and set US
  • Use the DevTools to fund yourself with eth
  • Refresh page, you should now be able to Create UID

mono's People

Contributors

andrew-goldfinch avatar blakewest avatar bstchow avatar carterappleton avatar daltyboy11 avatar emilyhsia avatar gregegan avatar ihinsdale avatar jaenia avatar kel1582 avatar landakram avatar marycaroline avatar michael-zadra avatar mikesall avatar philippeoz avatar pugbyte avatar rsarai avatar sanjayprabhu avatar smakosh avatar spyapali avatar taylorgoldfinch avatar thpaim-vinta avatar unordered-set avatar vedransisic avatar wbj-goldfinch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mono's Issues

Allow protocol owner to be passed in as an environment variable.

Currently the function getProtocolOwner returns Goldfinch Governance's address non-conditionally. This prevents developers looking to deploy on a test net from being able to specify their own wallet as the protocol owner. Instead, this function should source the protocol owner from an environment variable or some other source that can be configured easily by a developer.

Active?

Is development in this repo still happening? Seems there haven't been any new merges for a couple month.

`deployFixedLeverageRatioStrategy` attempts to re-initialize an existing contract

deployFixedLeverageRatioStrategy is not idempotent and will fail if called multiple times after deploy a contract.

The bug is caused by initialize being called after the contract has already initialized. This is caused by this line being idempotent. During deploy, if hardhat doesn't detect bytecode changes from the contract attempting to be deployed and the currently deployed contract it won't deploy a new contract and instead will return the existing contract. If that contract has already been initialized then the second call to initialize will fail.

To fix this initialize should only be called if the contract hasn't already been intialized

Partial sweep to Compound

One feature that would be awesome is the ability to sweep some funds to Compound, so that idle capital in the Senior Pool can be earning additional yield. And in fact, we already built this! However, for simplicity reasons, we built it such that it always sweeps all idle capital to Compound. And then if an LP withdraws, it would sweep it all back, and give the LP whatever the need. It required a manual action to sweep the funds back into Compound. We could have also swept the capital right back to Compound within the same withdraw transaction, but the gas costs would have been insane.
This was all fine in the very early days because we didn't have many LP's. But now that we have over 4800 LPs, withdraws happen multiple times/day, which basically breaks the feature.

So what would be awesome is the ability to sweep some funds to Compound (eg. 90% of available funds), so that 10% remains as liquidity for LPs. And only if someone wants to withdraw more than what remains at once would it trigger the withdraw back. This makes the accounting more difficult, but this feature would be very valuable! The core code to make it happen is already present here and here.

typechain/ethers is missing when launching the mono

in

https://github.com/goldfinch-eng/mono

I go:

npm install
npm run bootstrap

and this error comes out:

GOLDFINCH/mono/packages/server/node_modules/ts-node/src/index.ts:692
return new TSError(diagnosticText, diagnosticCodes);
^
TSError: ⨯ Unable to compile TypeScript:
../autotasks/index.ts(10,30): error TS2307: Cannot find module '@goldfinch-eng/protocol/typechain/ethers' or its corresponding type declarations.

is ethers the npm ethers package? if so, I tried installing it and it says I dont have permissions.

any ideas how to work around here?

Error: call revert exception

When calling setupForTesting, the following error pops up:

Error: call revert exception (method="creditLine()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.4.1)

Line of code that triggers it: https://github.com/goldfinch-eng/mono/blob/main/packages/protocol/blockchain_scripts/setUpForTesting.ts#L234

From what I've read on the internet, it may be caused by the creditLine not being present in the contract. Any hints to solve this?

Multiple deployment functions in `baseDeploy` do not use `DeployEffects` for upgrading config values

Uncovered by #18

Many functions called by baseDeploy attempt to update config variables directly instead of using DeployEffects to create a multisend to be executed by the protocol owner

Examples

Incorrect example
Here, the deploy script will immediately attempt to update the config variable with using the deployer account which doesn't have permission.

Correct example
Instead, updating the config variable should be added to DeployEffects for the protocol owner to execute

network does not support ENS

I run npm run start:local and encounter this error

lerna ERR! npm run start stderr:
Error HH604: Error running JSON-RPC server: ERROR processing /mono/packages/protocol/deploy/setUpForTesting.ts:
Error: network does not support ENS

Here is my setUpForTesting:

import {HardhatRuntimeEnvironment} from "hardhat/types"
import {MAINNET_CHAIN_ID} from "../blockchain_scripts/deployHelpers"
import {setUpForTesting} from "../blockchain_scripts/setUpForTesting"

async function main(hre) {
  await setUpForTesting(hre)
}

module.exports = main
module.exports.dependencies = ["base_deploy"]
module.exports.tags = ["setup_for_testing"]
module.exports.skip = async ({getChainId}: HardhatRuntimeEnvironment) => {
  const chainId = await getChainId()
  return String(chainId) === MAINNET_CHAIN_ID
}

Infinite loading when installing the project

I have an Apple M1 Pro chipset and tried to compile the entire the project multiple times. The project does not seem to finish compiling, it seems that the installation just hangs after some point.

This didn't happen prior to the latest merge.

Command that's causing the issue: npm run bootstrap.

PR that seems to have caused the issue: #27

chainId error when start running mainnet fork

I run npm run start and got this error
Error running JSON-RPC server: with hardhat-deploy >= 0.6 you need to rename network folder without appended chainId
You also need to create a '.chainId' file in the folder with the chainId

Senior pool should return the amount it invested when `invest` is called

When a user calls SeniorPool.invest the SeniorPool should return the amount of USDC that was invested in the given tranched pool.

Example

Given a TranchedPool T with 1 usdc in the tranched pool, when I call .invest it should return 4 because the senior pool invests at a 4x leverage ratio.

ProviderError: Unsupported method: hardhat_impersonateAccount

After deploying the goldfinch contracts on Rinkeby, I'm trying to call setUpForTesting to test the smart contract interaction.

However, I'm getting ProviderError: Unsupported method: hardhat_impersonateAccount when trying to impersonate the account. Is there any workaround for this?

Is setUpForTesting supposed to work only for mainnet forking network?

ProviderError: max code size exceeded

Getting this error on both AVAX and Aurora networks, when trying to run the tests.

 |  TranchedPool                               ·     24.504  ·               │
 ··············································|·············|················
 |  StakingRewards                             ·     24.549  ·               │

TranchedPool and StakingRewards exceed the smart contract size limit, so they cannot be deployed on neither of these networks. Can we have the contracts reduced in size so they can be deployed on the network?

Instructions missing - the project cannot be run

Hello,

First of all, congrats for the amazing effort put into this repo.

I've tried to run the project, but it doesn't seem to be working. I'm getting the same errors over and over again.

When running npm run start:local, I get:

Unhandled Rejection (Error): You must provide the json interface of the contract when instantiating a contract object.
▶ 3 stack frames were collapsed.
GoldfinchProtocol.getContract
src/ethereum/GoldfinchProtocol.ts:71
  68 | } else {
  69 |   abi = contractOrAbi
  70 | }
> 71 | const readOnly = new web3.readOnly.eth.Contract(abi, address) as unknown as T
     | ^  72 | ;(readOnly as any).loaded = true
  73 | const userWallet = new web3.userWallet.eth.Contract(abi, address) as unknown as T
  74 | ;(userWallet as any).loaded = true

When running start:local:liquidity-mining, I get:

Unhandled Rejection (Error): MerkleDirectDistributor address of GFI contract doesn't match with deployed GFI address
MerkleDirectDistributor._callee$
src/ethereum/merkleDirectDistributor.ts:35
  32 |   }
  33 | }
  34 | 
> 35 | async initialize(currentBlock: BlockInfo): Promise<void> {
     | ^  36 |   const [gfiAddress, isPaused] = await Promise.all([
  37 |     this.contract.readOnly.methods.gfi().call(undefined, currentBlock.number),
  38 |     this.contract.readOnly.methods.paused().call(undefined, currentBlock.number),

Note that the second command was running fine before the last changes in May got pushed.

Can I please get some help here? Are there any additional steps that need to be taken in order to be able to run the project?

Create NFT's for Flight Academy awards ceremony

Problem Statement

It would be awesome to give Flight Academy participants NFT's. We were gonna use POAPs, but the POAP team seems to be backed up, and doesn't have time to talk to Goldfinch.

Potential solutions

Could the community can spin up an NFT contract on Polygon or some other L2? Then we just need a way for people to claim. You could use a Merkle Distributor to let people claim, and could maybe create a simple front-end page (potentially using this repo).

There may be other ways to do it then what I'm describing! What are people's thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.