Skip to content

Commit

Permalink
Merge pull request #8 from PatrickAlphaC/master
Browse files Browse the repository at this point in the history
Updated for developer experience and config for chain customization
  • Loading branch information
iamdefinitelyahuman authored Apr 27, 2021
2 parents b0212e3 + c1a0d44 commit 601a64d
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 16 deletions.
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export WEB3_INFURA_PROJECT_ID=YourProjectID
export ETHERSCAN_TOKEN=YourApiToken
export PRIVATE_KEY="0xasdfasdfasdfasd..."
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ __pycache__
.hypothesis/
build/
reports/
.env
43 changes: 33 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This mix is configured for use with [Ganache](https://github.com/trufflesuite/ga

1. [Install Brownie](https://eth-brownie.readthedocs.io/en/stable/install.html) & [Ganache-CLI](https://github.com/trufflesuite/ganache-cli), if you haven't already.

2. Sign up for [Infura](https://infura.io/) and generate an API key. Store it in the `WEB3_INFURA_PROJECT_ID` environment variable.
2. Sign up for [Infura](https://infura.io/) and generate an API key. Store it in the `WEB3_INFURA_PROJECT_ID` environment variable. You can [learn more about environment variables here](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html). If you're unfamiliar with environment variables you can just add all these commands to your `.env` file and run `source .env` when you're done.

```bash
export WEB3_INFURA_PROJECT_ID=YourProjectID
Expand All @@ -32,7 +32,33 @@ export ETHERSCAN_TOKEN=YourApiToken
brownie bake aave-flashloan
```

## Basic Use
5. Add your `PRIVATE_KEY` environment variable, with [a private key from you wallet.](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key). *Note: If using metamask, you'll have to add a `0x` to the start of your private key)

## Quickstart (Kovan)

We can see our flash loans on Etherscan via the Kovan testnet. If you're rather *run everything locally, check out the [Basic Console Use](#basic-console-use).

1. Get some WETH. We need this to pay the preimum that flash loans cost.

```bash
$ brownie run scripts/get_weth.py --network kovan
```

2. Deploy the flash loan contract. This will also fund the contract with WETH to pay the flash loan fee if it's not funded.

```bash
$ brownie run scripts/deployment_v2.py --network kovan
```

3. Execute the flash loan

```bash
$ brownie run scripts/run_flash_loan_v2.py --network kovan
```

This will print out an etherscan URL to see the flash loan transaction. [Like this one.](https://kovan.etherscan.io/tx/0x161d423dd1a56e7c440dabed95bea314b63668fc462567348ba4dd188e894de3)

## Basic Console Use

To perform a simple flash loan in a development environment:

Expand Down Expand Up @@ -85,8 +111,8 @@ Transaction sent: 0x335530e6d2b7588ee4727b35ae1ed8634a264aca04b325640101ec1c2b89

[`contracts/v2/FlashloanV2.sol`](contracts/v2/FlashloanV2.sol) is where you implement your own logic for flash loans. In particular:

* The size of the loan is set in line 39 in `flashloan`.
* Custom flash loan logic is added after line 23 in `executeOperation`.
* The size of the loan is set in line 89 in `flashloan`.
* Custom flash loan logic is added after line 31 in `executeOperation`.

See the Aave documentation on [Performing a Flash Loan](https://docs.aave.com/developers/guides/flash-loans) for more detailed information.

Expand Down Expand Up @@ -253,16 +279,13 @@ See the [Brownie documentation](https://eth-brownie.readthedocs.io/en/stable/cor

When you are finished testing and ready to deploy to the mainnet:

1. [Import a keystore](https://eth-brownie.readthedocs.io/en/stable/account-management.html#importing-from-a-private-key) into Brownie for the account you wish to deploy from.
2. Edit [`scripts/deployment.py`](scripts/deployment.py) and add your keystore ID according to the comments.
3. Run the deployment script on the mainnet using the following command:
1. [Import a keystore](https://eth-brownie.readthedocs.io/en/stable/account-management.html#importing-from-a-private-key) into Brownie for the account you wish to deploy from. Add this as a `PRIVATE_KEY` environment variable.
2. Run the deployment script on the mainnet using the following command:

```bash
$ brownie run deployment --network mainnet
$ brownie run scripts/deployment_v2.py --network mainnet
```

You will be prompted to enter your keystore password, and then the contract will be deployed.

## Known issues

### No access to archive state errors
Expand Down
14 changes: 14 additions & 0 deletions brownie-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,17 @@ compiler:
solc:
remappings:
- "@openzeppelin=OpenZeppelin/[email protected]"
networks:
default: mainnet-fork
mainnet-fork:
aave_lending_pool_v2: "0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5"
weth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
kovan:
aave_lending_pool_v2: "0x88757f2f99175387ab4c6a4b3067c77a695b0349"
weth: "0xd0a1e359811322d97991e03f863a0c30c2cf029c"
mainnet:
aave_lending_pool_v2: "0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5"
weth: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
wallets:
from_key: ${PRIVATE_KEY}
from_mnemonic: ${MNEMONIC}
4 changes: 2 additions & 2 deletions contracts/v2/FlashloanV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract FlashloanV2 is FlashLoanReceiverBaseV2, Withdrawable {
override
returns (bool)
{

//
// This contract now has the funds requested.
// Your logic goes here.
Expand Down Expand Up @@ -96,4 +96,4 @@ contract FlashloanV2 is FlashLoanReceiverBaseV2, Withdrawable {

_flashloan(assets, amounts);
}
}
}
15 changes: 15 additions & 0 deletions interfaces/WethInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

pragma solidity ^0.4.19;

interface WethInterface {
function allowance(address owner, address spender) external view returns (uint256 remaining);
function approve(address spender, uint256 value) external returns (bool success);
function balanceOf(address owner) external view returns (uint256 balance);
function decimals() external view returns (uint8 decimalPlaces);
function name() external view returns (string memory tokenName);
function symbol() external view returns (string memory tokenSymbol);
function totalSupply() external view returns (uint256 totalTokensIssued);
function transfer(address to, uint256 value) external returns (bool success);
function transferFrom(address from, address to, uint256 value) external returns (bool success);
function deposit() external;
}
13 changes: 9 additions & 4 deletions scripts/deployment_v2.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
from brownie import FlashloanV2, accounts
from brownie import FlashloanV2, accounts, config, network

AAVE_LENDING_POOL_ADDRESS_PROVIDER = "0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5"
# AAVE_LENDING_POOL_ADDRESS_PROVIDER = "0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5"


def main():
"""
Deploy a `FlashloanV2` contract from `accounts[0]`.
"""

acct = accounts.load() # add your keystore ID as an argument to this call
acct = accounts.add(
config["wallets"]["from_key"]
) # add your keystore ID as an argument to this call

flashloan = FlashloanV2.deploy(AAVE_LENDING_POOL_ADDRESS_PROVIDER, {"from": acct})
flashloan = FlashloanV2.deploy(
config["networks"][network.show_active()]["aave_lending_pool_v2"],
{"from": acct},
)
return flashloan
21 changes: 21 additions & 0 deletions scripts/get_weth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from brownie import accounts, config, network, interface


def main():
"""
Runs the get_weth function to get WETH
"""
get_weth()


def get_weth():
"""
Mints WETH by depositing ETH.
"""
acct = accounts.add(
config["wallets"]["from_key"]
) # add your keystore ID as an argument to this call
weth = interface.WethInterface(config["networks"][network.show_active()]["weth"])
tx = weth.deposit({"from": acct, "value": 1000000000000000000})
print("Received 1 WETH")
return tx
22 changes: 22 additions & 0 deletions scripts/run_flash_loan_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from brownie import FlashloanV2, accounts, config, network, interface

MINIMUM_FLASHLOAN_WETH_BALANCE = 500000000000000000
ETHERSCAN_TX_URL = "https://kovan.etherscan.io/tx/{}"


def main():
"""
Executes the funcitonality of the flash loan.
"""
acct = accounts.add(config["wallets"]["from_key"])
print("Getting Flashloan contract...")
flashloan = FlashloanV2[len(FlashloanV2) - 1]
weth = interface.WethInterface(config["networks"][network.show_active()]["weth"])
# We need to fund it if it doesn't have any token to fund!
if weth.balanceOf(flashloan) < MINIMUM_FLASHLOAN_WETH_BALANCE:
print("Funding Flashloan contract with WETH...")
weth.transfer(flashloan, "1 ether", {"from": acct})
print("Executing Flashloan...")
tx = flashloan.flashloan(weth, {"from": acct})
print("You did it! View your tx here: " + ETHERSCAN_TX_URL.format(tx.txid))
return flashloan

0 comments on commit 601a64d

Please sign in to comment.