Skip to content

Commit

Permalink
Remove gasless infra (#666)
Browse files Browse the repository at this point in the history
### What happened?
Code related to our gasless relayer has been removed. This includes the TestForwarder contract, the frontend relay logic, package.json scripts related to no-gasless, etc.

In places where it can't be removed, e.g. `TrustedForwarder` in `ConfigOptions.sol`, it has been marked as deprecated.

### Why?
Gasless logic adds significant complexity to the codebase and has been a headache to maintain. In the past we valued this tradeoff of complexity to allow our users to not pay for gas. Now that we're more established we're ok with making our users pay for gas in order to eliminate this complexity.

### How has this been tested?
#### Manual Testing
- [x] Test app for `npm run start`
  - [x] App starts
  - [x] setupForTesting works (I do get a minor error but this error is also observed on `main` branch, so likely its own bug)
- [x] Test app in `npm run start:local:liquidity-mining`
  - [x] App starts
  - [x] setupForTesting works
  - [x] can drawdown on a credit line and it makes me pay for gas.

#### Unit testing
- [x] All existing unit tests pass

### Further Actions
Once merged we can delete the [MainnetRelayer](https://defender.openzeppelin.com/#/autotask/9d2053fd-507a-473f-8b5a-b079a694723a) and [RinkebyRelayer](https://defender.openzeppelin.com/#/autotask/348209ac-8cfd-41a4-be60-e97eab073f29) on defender.

**Checklist**
- [x] I have reviewed this code myself
- [ ] Screenshots of the key change are present (if this is a front-end PR)
  • Loading branch information
daltyboy11 authored Jun 6, 2022
1 parent c5344e5 commit b455c50
Show file tree
Hide file tree
Showing 30 changed files with 40 additions and 2,936 deletions.
6 changes: 0 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@

TEST_USER={{ADD_YOUR_METAMASK_ADDRESS_HERE}},

# Gasless relay config
RELAY_SERVER_PORT=4000
# You may want to add your own wallet address to whitelisted senders, and borrower contracts to whitelisted contracts
ALLOWED_SENDERS=0xE7f9ED35DA54b2e4A1857487dBf42A32C4DBD4a0,
FORWARDER_ADDRESS=0xa530F85085C6FE2f866E7FdB716849714a89f4CD

# Set the permit deadline to be a year. This is so that we can advance time locally without
# accidentally making permits invalid
REACT_APP_PERMIT_DEADLINE=31536000
Expand Down
13 changes: 1 addition & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ Both options will start several processes, including your local blockchain and f
```
ALCHEMY_API_KEY={your alchemy api key}
TEST_USER={your metamask address}
ALLOWED_SENDERS={your metamask address}`
```

- If you want the `client` to use variables in your `.env.local`, create a symlink to this file from inside the `packages/client` dir, or else create a separate `packages/client/.env.local` file.
Expand All @@ -63,9 +62,6 @@ Changes to the frontend should be automatically hotloaded using react-refresh.

Changes to smart contracts will require re-compiling and re-deploying. You can do this by re-running your start command.

#### Other ways to run
* `npm run start:no-gasless` is available if gasless transactions are giving you trouble, or if you're having trouble finding the borrower contract address.

***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.
Expand All @@ -77,7 +73,7 @@ then go to `Add Token` in Metamask, and paste it in there. Your fake USDC balanc
* [`protocol/`](./packages/protocol) (`@goldfinch-eng/protocol`): Solidity smart contracts and tests.
* [`client/`](./packages/client) (`@goldfinch-eng/client`): Web3 frontend using React.
* [`functions/`](./packages/functions) (`@goldfinch-eng/functions`): Google cloud functions to support KYC and other server-side functionality.
* [`autotasks/`](./packages/autotasks) (`@goldfinch-eng/functions`): [Defender Autotasks and Relay](https://docs.openzeppelin.com/defender/autotasks) code for supporting gasless transactions and triggering periodic on-chain calls.
* [`autotasks/`](./packages/autotasks) (`@goldfinch-eng/functions`): [Defender Autotasks and Relay](https://docs.openzeppelin.com/defender/autotasks) code for triggering periodic on-chain calls.
* [`utils/`](./packages/utils) (`@goldfinch-eng/utils`): Generally useful utilities that are shared across packages.
* [`docs/`](./packages/docs) (`@goldfinch-eng/docs`): Static site of protocol documentation.
* [`murmuration/`](./murmuration): Provisioning scripts for our cloud staging environment, called Murmuration.
Expand Down Expand Up @@ -108,13 +104,6 @@ Pick up the transaction hash from the output of the test and run export as above
### Security
- See the [`SECURITY.MD`](./SECURITY.MD)

### Gasless transactions

To support gasless transactions, we need to collect the signature from the client, perform some server side checks to validate
the sender and receiving contract (e.g. it's a known borrower interacting with our borrower contracts, we don't want to subsidize any arbitrary transaction).
We use [Defender Relay](https://docs.openzeppelin.com/defender/relay) to do this. For local development, we mimic this by running a local server that executes the gasless logic.
We've configured webpack to proxy to this server when running `npm run start` for local development. If you're having problems with gasless transactions, make sure you've added your address to `.env.local`'s `ALLOWED_SENDERS`.

### Testing
- Run `npm test` to run tests for all packages.
- Note if you want to only run tests for a particular test, then use `it.only` or `describe.only` inside the test file itself, which will focus to only those tests.
Expand Down
5 changes: 0 additions & 5 deletions murmuration/.env.murmuration
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
# So, customize it like would customize your own `.env.local` in local development --
# but in this case, for the values you want to be used in the murmuration environment.

RELAY_SERVER_PORT=4000

ALLOWED_SENDERS=0xBAc2781706D0aA32Fb5928c9a5191A13959Dc4AE,0x0333119c9688Eb0c7805454cf5e101b883FD1BFa,0x3FeB1094eE48DB0B9aC25b82A3A34ABe16208590,0xeF3fAA47e1b0515f640c588a0bc3D268d5aa29B9,0x139C9c156D049dd002b04A6471D3DE0AD1eAb256,0x1F666ca6CeE68F6AfdD3eC0670A40a54F88c8E64,0x69f7A8242ecBDac84b05FD80DA9631E5d659F690,0xd4ad17f7F7f62915A1F225BB1CB88d2492F89769
FORWARDER_ADDRESS=0x05aa229aec102f78ce0e852a812a388f076aa555

MERKLE_GRANT_RECIPIENTS=0xBAc2781706D0aA32Fb5928c9a5191A13959Dc4AE,0x0333119c9688Eb0c7805454cf5e101b883FD1BFa,0x3FeB1094eE48DB0B9aC25b82A3A34ABe16208590,0xeF3fAA47e1b0515f640c588a0bc3D268d5aa29B9,0x139C9c156D049dd002b04A6471D3DE0AD1eAb256,0x1F666ca6CeE68F6AfdD3eC0670A40a54F88c8E64,0x69f7A8242ecBDac84b05FD80DA9631E5d659F690,0xd4ad17f7F7f62915A1F225BB1CB88d2492F89769,0x483e2BaF7F4e0Ac7D90c2C3Efc13c3AF5050F3c2,0x0eD17aD2936479ca3DbC3Cd59cE8a220FBD478FA,0x8fEab515323815c34972cfb4ec2DbC2030336772,0xA2990D127858B41008714741194226f67760097e,0xC172af9764e4F6e0cFfe9d07F4499ba796B4446b,0xAb03fF72Ba45dc5731fC3A6B7D2dE6A229a91fa6,0xA6a638Ef300C9be0563c92Fe28758A60B4Dfe85C,0x82aC1524c77Fc8271Fc267A86286DDcc88162Ac0,0x3a7AC1c18492d363Bb5C0f7Fe51202dD1AA393ef,0x0Aa34EB615ab330b64060ff9Fa994E72A7A95B59,0x4ac7a945C62Ba41A0543CE5D30d26Acd14fbcFeC,0x6cCcaf4f99b9493AB2D8061E4CB380bCb8844F9A,0x6d8b09Ebcd47489c77F50599C30c6726E38AFF6A,0x501B06e19675Eb0107ad13e7d3379c3389222f20,0x1e59636DCBBE879f9DfDEf2ef40eB3178f723885,0x11AA0Ba70c3e29bD2Ba18e99B35382f644e690F4

# AUTOTASK_API_KEY=
Expand Down
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
"bootstrap": "npx lerna bootstrap && npm run stub-dev-deployments && npm run build",
"stub-dev-deployments": "sh -c \"[ ! -e \"packages/protocol/deployments/all_dev.json\" ] && echo {} > packages/protocol/deployments/all_dev.json || true\"",
"start": "npm run kill-ports && REACT_APP_HARDHAT_FORK=mainnet HARDHAT_FORK=mainnet npx lerna run --ignore @goldfinch-eng/client2 start --parallel",
"start:no-gasless": "npm run kill-ports && REACT_APP_DISABLE_GASLESS=true REACT_APP_HARDHAT_FORK=mainnet HARDHAT_FORK=mainnet npx lerna run --ignore @goldfinch-eng/client2 start --parallel",
"start:local": "npm run kill-ports && REACT_APP_HARDHAT_FORK= HARDHAT_FORK= npx lerna run --ignore @goldfinch-eng/client2 start --parallel",
"start:local:no-gassless": "npm run kill-ports && REACT_APP_DISABLE_GASLESS=true REACT_APP_HARDHAT_FORK= HARDHAT_FORK= npx lerna run --ignore @goldfinch-eng/client2 start --parallel",
"start:local:liquidity-mining": "npx lerna run --ignore @goldfinch-eng/client2 generate-merkle-root:local && REACT_APP_GCLOUD_FUNCTIONS_URL=http://localhost:5001/goldfinch-frontends-dev/us-central1 BACKER_MERKLE_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/backerMerkleDistributor/merkleDistributorInfo.dev.json BACKER_MERKLE_DIRECT_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/backerMerkleDirectDistributor/merkleDirectDistributorInfo.dev.json MERKLE_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/merkleDistributor/merkleDistributorInfo.dev.json MERKLE_DIRECT_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/merkleDirectDistributor/merkleDirectDistributorInfo.dev.json npm run start:local",
"start:local:liquidity-mining:no-gasless": "npx lerna run --ignore @goldfinch-eng/client2 generate-merkle-root:local && REACT_APP_GCLOUD_FUNCTIONS_URL=http://localhost:5001/goldfinch-frontends-dev/us-central1 BACKER_MERKLE_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/backerMerkleDistributor/merkleDistributorInfo.dev.json BACKER_MERKLE_DIRECT_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/backerMerkleDirectDistributor/merkleDirectDistributorInfo.dev.json MERKLE_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/merkleDistributor/merkleDistributorInfo.dev.json MERKLE_DIRECT_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/merkleDirectDistributor/merkleDirectDistributorInfo.dev.json npm run start:local:no-gassless",
"start:murmuration": "npm run kill-ports && npx lerna run --ignore @goldfinch-eng/client2 start:murmuration --parallel",
"start:murmuration:liquidity-mining": "npm run kill-ports && npx lerna run --ignore @goldfinch-eng/client2 generate-merkle-root:murmuration && BACKER_MERKLE_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/backerMerkleDistributor/merkleDistributorInfo.dev.json BACKER_MERKLE_DIRECT_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/backerMerkleDirectDistributor/merkleDirectDistributorInfo.dev.json && MERKLE_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/merkleDistributor/merkleDistributorInfo.dev.json MERKLE_DIRECT_DISTRIBUTOR_INFO_PATH=./blockchain_scripts/merkle/merkleDirectDistributor/merkleDirectDistributorInfo.dev.json npx lerna run --ignore @goldfinch-eng/client2 start:murmuration:liquidity-mining --parallel",
"kill-ports": "for i in 4000 4001 3000 3002 5001 8545 8080; do lsof -t -i:$i | xargs -r kill; done",
Expand Down
85 changes: 0 additions & 85 deletions packages/autotasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,95 +2,10 @@ import {findEnvLocal, assertNonNullable} from "@goldfinch-eng/utils"
import dotenv from "dotenv"
dotenv.config({path: findEnvLocal()})

import {relay} from "./relayer/relay"
import * as uniqueIdentitySigner from "./unique-identity-signer"
import {hardhat as hre} from "@goldfinch-eng/protocol"
import {TypedDataUtils} from "eth-sig-util"
import {bufferToHex} from "ethereumjs-util"
import {UniqueIdentity} from "@goldfinch-eng/protocol/typechain/ethers"

assertNonNullable(
process.env.FORWARDER_ADDRESS,
"FORWARDER_ADDRESS must be passed as an envvar when running the development server"
)

const FORWARDER_ADDRESS = process.env.FORWARDER_ADDRESS
const ALLOWED_SENDERS = (process.env.ALLOWED_SENDERS || "").split(",").filter((val) => !!val)

async function hardhatRelay(txData) {
const {protocol_owner} = await hre.getNamedAccounts()
const signer = (await hre.ethers.getSigners()).find((signer) => signer.address === protocol_owner)
console.log(`Sending: ${JSON.stringify(txData)}`)
assertNonNullable(signer)
const result = await signer.sendTransaction({to: txData.to, data: txData.data})
console.log(`Result: ${JSON.stringify(result)}`)
return result
}

function calculateDomainSeparator(chainId, forwarderAddress) {
const EIP712DomainType = [
{name: "name", type: "string"},
{name: "version", type: "string"},
{name: "chainId", type: "uint256"},
{name: "verifyingContract", type: "address"},
]

const ForwardRequestType = [
{name: "from", type: "address"},
{name: "to", type: "address"},
{name: "value", type: "uint256"},
{name: "gas", type: "uint256"},
{name: "nonce", type: "uint256"},
{name: "data", type: "bytes"},
]

const TypedData = {
domain: {
name: "Defender",
version: "1",
chainId: chainId,
verifyingContract: forwarderAddress,
},
primaryType: "ForwardRequest",
types: {
EIP712Domain: EIP712DomainType,
ForwardRequest: ForwardRequestType,
},
message: {},
}
return bufferToHex(TypedDataUtils.hashStruct("EIP712Domain", TypedData.domain, TypedData.types))
}

async function createContext() {
const {ethers, deployments} = hre
const {getOrNull} = deployments

const deployed = await getOrNull("TestForwarder")
assertNonNullable(deployed)
assertNonNullable(FORWARDER_ADDRESS)
const forwarder = await ethers.getContractAt(deployed.abi, FORWARDER_ADDRESS)
const chainId = await hre.getChainId()
return {
chainId: chainId,
forwarder: forwarder,
allowed_senders: ALLOWED_SENDERS,
relayTx: hardhatRelay,
domain_separator: calculateDomainSeparator(chainId, forwarder.address),
}
}

export async function relayHandler(req, res) {
try {
console.log(`Forwarding: ${JSON.stringify(req.body)}`)
const context = await createContext()
const tx = await relay(req.body, context)
res.status(200).send({status: "success", result: JSON.stringify(tx)})
} catch (error: any) {
console.log(`Failed: ${error}`)
res.status(500).send({status: "error", message: error.toString()})
}
}

export async function uniqueIdentitySignerHandler(req, res) {
try {
console.log(`Forwarding: ${JSON.stringify(req.body)}`)
Expand Down
1 change: 0 additions & 1 deletion packages/autotasks/relayer/Forwarder.json

This file was deleted.

74 changes: 0 additions & 74 deletions packages/autotasks/relayer/index.ts

This file was deleted.

Loading

0 comments on commit b455c50

Please sign in to comment.