Giter Club home page Giter Club logo

defi-by-example's Introduction

Install

# install vyper
virtualenv -p python3 venv
source venv/bin/activate
pip install vyper

cp .env.sample .env

For windows

virtualenv -p python3 venv
venv\Scripts\activate
pip install vyper

To run

venv\Scripts\activate
truffle compile

Test

source .env

# using infura.io
npx ganache-cli \
--fork https://mainnet.infura.io/v3/$WEB3_INFURA_PROJECT_ID \
--unlock $WETH_WHALE \
--unlock $DAI_WHALE \
--unlock $USDC_WHALE \
--unlock $USDT_WHALE \
--unlock $WBTC_WHALE \
--networkId 999

# using archivenode.io (limit 10 req / sec)
## fork at block
BLOCK=11597142
ARCHIVE_NODE_URL=https://api.archivenode.io/$ARCHIVE_NODE_API_KEY@$BLOCK
## latest block
ARCHIVE_NODE_URL=https://api.archivenode.io/$ARCHIVE_NODE_API_KEY

ganache-cli \
--fork $ARCHIVE_NODE_URL \
--unlock $WETH_WHALE \
--unlock $DAI_WHALE \
--unlock $USDC_WHALE \
--unlock $USDT_WHALE \
--unlock $WBTC_WHALE \
--networkId 999

# run test
env $(cat .env) npx truffle test --network mainnet_fork test/test-erc20.js
env $(cat .env) npx truffle test --network mainnet_fork test/test-dydx-solo-margin.js

defi-by-example's People

Contributors

alinobrasil avatar bernardchooo avatar t4sk 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

defi-by-example's Issues

yearn vault

https://etherscan.io/tx/0x6dc268706818d1e6503739950abc5ba2211fc6b451e54244da7b1e226b12e027

https://www.rekt.news/post/yearn-rekt/

https://github.com/iearn-finance/yearn-security/blob/master/disclosures/2020-10-30.md

1/ Flash loaned 116k ETH from dYdX
2/ Flash loaned 99k ETH from Aave v2
3/ Borrow 134M USDC and 129M DAI using ETH as collateral on Compound
4/ Add 134M USDC and 36M DAI to 3crv Curve pool
5/ Withdraw 165M USDT from 3crv Curve pool
6/ Repeat five timesDown pointing backhand index

  • Deposit 93M DAI to yDAI vault (less w/ each time)
  • Add 165M USDT to 3crv pool
  • Withdraw 92M DAI from yDAI vault (less w/ each time)
  • Withdraw 165M USDT from 3crv pool
    7/ In the last time withdraw 39M DAI and 134M USDC instead USDT
    8/ Repay Compound debts
    9/ Repay flash loans

flash mint full code

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;

interface WETH10 {
  function flashLoan(
    address receiver,
    address token,
    uint value,
    bytes calldata data
  ) external returns (bool);
}


interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


contract TestWethFlashMint {
  // WETH 10
  address private WETH = 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F;
  bytes32 public immutable CALLBACK_SUCCESS =
    keccak256("ERC3156FlashBorrower.onFlashLoan");

  address public sender;
  address public token;

  event Log(string name, uint val);

  function flash() external {
    uint total = IERC20(WETH).totalSupply();
    // borrow more than available
    uint amount = total + 1;

    emit Log("total supply", total);

    IERC20(WETH).approve(WETH, amount);

    bytes memory data = "";
    WETH10(WETH).flashLoan(address(this), WETH, amount, data);
  }

  // called by WETH10
  function onFlashLoan(
    address _sender,
    address _token,
    uint amount,
    uint fee,
    bytes calldata data
  ) external returns (bytes32) {
    uint bal = IERC20(WETH).balanceOf(address(this));

    sender = _sender;
    token = _token;

    emit Log("amount", amount);
    emit Log("fee", fee);
    emit Log("balance", bal);

    return CALLBACK_SUCCESS;
  }
}

Error: Cannot create instance of IERC20; no code at address

why?

Everything is up to date, there is nothing to compile.

Contract: TestDyDxSoloMargin
1) "before each" hook for "flash loan"

0 passing (1s)
1 failing

  1. Contract: TestDyDxSoloMargin
    "before each" hook for "flash loan":
    Error: Cannot create instance of IERC20; no code at address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
    at Object.checkCode (node_modules/truffle/build/webpack:/packages/contract/lib/utils/index.js:263:1)
    at Function.at (node_modules/truffle/build/webpack:/packages/contract/lib/contract/constructorMethods.js:73:1)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at Context. (test/test-dydx-solo-margin.js:20:13)

Error when deploy TestAaveFlashLoan.sol

Hello!
When I try to deploy a contract, I get the error "Gas estimation failed".
I take the address for the constructor from the Aave list.
What am I doing wrong?
image

Liquidity.test.js

I am getting this error when I try to test: sender doesn't have enough funds to send tx. The max upfront cost is: 1527451433449412000 and the sender's account only has: 0.

I updated some of the code, is my hardhat setup wrong?
Error starts at when transfering DAI and USDC to owner.

const { expect } = require("chai")
const { ethers } = require("hardhat")

const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F"
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
const DAI_WHALE = "0x6FF8E4DB500cBd77d1D181B8908E022E29e0Ec4A"
const USDC_WHALE = "0xc3dcB715eDeb0374E968177A3620c441344c3ED8"
const IWETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
const wethAmount = ethers.utils.parseEther("1")

describe("LiquidityExamples", () => {
  let liquidityExamples
  let accounts
  let dai
  let usdc
  let owner
  let iweth

  before(async () => {
    accounts = await ethers.getSigners()
    owner = accounts[0]
    console.log(`owner address : ${owner.address}`)
    console.log(`account[0] address : ${accounts[0].address}`)

    const LiquidityExamples = await ethers.getContractFactory(
      "LiquidityExamples"
    )
    liquidityExamples = await LiquidityExamples.deploy()
    await liquidityExamples.deployed()

    dai = await ethers.getContractAt("IERC20", DAI)
    usdc = await ethers.getContractAt("IERC20", USDC)
    iweth = await ethers.getContractAt("IWETH", IWETH)

    // Unlock DAI and USDC whales
    await network.provider.request({
      method: "hardhat_impersonateAccount",
      params: [DAI_WHALE],
    })
    await network.provider.request({
      method: "hardhat_impersonateAccount",
      params: [USDC_WHALE],
    })
    // get Signers
    const daiWhale = await ethers.getSigner(DAI_WHALE)
    const usdcWhale = await ethers.getSigner(USDC_WHALE)

    const daiBal = await dai.balanceOf(DAI_WHALE)
    const usdcBal = await usdc.balanceOf(USDC_WHALE)

    // Send DAI and USDC to accounts[0]
    const daiAmount = 10n * 10n ** 18n
    const usdcAmount = 10n * 10n ** 6n

    await dai.connect(daiWhale).transfer(owner.address, daiAmount)
    await usdc.connect(usdcWhale).transfer(owner.address, usdcAmount)

    const daiBalance = await dai.balanceOf(owner.address)
  })

  it("mintNewPosition", async () => {
    const daiAmount = 1n * 10n ** 18n
    const usdcAmount = 1n * 10n ** 6n

    await dai.connect(owner).transfer(liquidityExamples.address, daiAmount)
    await usdc.connect(owner).transfer(liquidityExamples.address, usdcAmount)

    await liquidityExamples.mintNewPosition()

    console.log(
      "DAI balance after add liquidity",
      await dai.balanceOf(accounts[0].address)
    )
    console.log(
      "USDC balance after add liquidity",
      await usdc.balanceOf(accounts[0].address)
    )
  })

  it.skip("increaseLiquidityCurrentRange", async () => {
    const daiAmount = 20n * 10n ** 18n
    const usdcAmount = 20n * 10n ** 6n

    await dai.connect(accounts[0]).approve(liquidityExamples.address, daiAmount)
    await usdc
      .connect(accounts[0])
      .approve(liquidityExamples.address, usdcAmount)

    await liquidityExamples.increaseLiquidityCurrentRange(daiAmount, usdcAmount)
  })

  it("decreaseLiquidity", async () => {
    const tokenId = await liquidityExamples.tokenId()
    const liquidity = await liquidityExamples.getLiquidity(tokenId)

    await liquidityExamples.decreaseLiquidity(liquidity)

    console.log("--- decrease liquidity ---")
    console.log(`liquidity ${liquidity}`)
    console.log(`dai ${await dai.balanceOf(liquidityExamples.address)}`)
    console.log(`usdc ${await usdc.balanceOf(liquidityExamples.address)}`)
  })

  it("collectAllFees", async () => {
    await liquidityExamples.collectAllFees()

    console.log("--- collect fees ---")
    console.log(`dai ${await dai.balanceOf(liquidityExamples.address)}`)
    console.log(`usdc ${await usdc.balanceOf(liquidityExamples.address)}`)
  })
})


Error minting ETH-USDC 0.3% pool Uniswap v3

I am using the following method to mint a Uniswap v3 position:

function mintPosition(
        address token0,
        address token1,
        uint24 poolFee,
        uint256 amount0,
        uint256 amount1,
        int24 rangeLeft,
        int24 rangeRight) external payable override returns (
            uint256 tokenId,
            uint128 liquidity,
            uint256 actualAmount0,
            uint256 actualAmount1
        )
    {

        // Approve the position manager
        TransferHelper.safeApprove(token0, address(nonfungiblePositionManager), amount0);
        TransferHelper.safeApprove(token1, address(nonfungiblePositionManager), amount1);

        INonfungiblePositionManager.MintParams memory params =
            INonfungiblePositionManager.MintParams({
                token0: token0,
                token1: token1,
                fee: poolFee,
                tickLower: rangeLeft,
                tickUpper: rangeRight,
                amount0Desired: amount0,
                amount1Desired: amount1,
                amount0Min: 0,
                amount1Min: 0,
                recipient: address(this),
                deadline: block.timestamp
            });

        // Note that the pool defined by token0/token1 and fee tier poolFee must already be created and initialized in order to mint
        // THIS TRANSACTION FAILS WITHOUT A REASON STRING
        (tokenId, liquidity, actualAmount0, actualAmount1) = nonfungiblePositionManager.mint(params);

        // Create a deposit
        _createDeposit(msg.sender, tokenId);

        // Remove allowance and refund in both assets.
        if (actualAmount0 < amount0) {
            TransferHelper.safeApprove(token0, address(nonfungiblePositionManager), 0);
            uint256 refund0 = amount0 - actualAmount0;
            TransferHelper.safeTransfer(token0, msg.sender, refund0);
        }

        if (actualAmount1 < amount1) {
            TransferHelper.safeApprove(token1, address(nonfungiblePositionManager), 0);
            uint256 refund1 = amount1 - actualAmount1;
            TransferHelper.safeTransfer(token1, msg.sender, refund1);
        }
    }

I am able to mint a DAI-USDC 0.01% with this method. But when trying to create an ETH-USDC 0.3% pool it fails without a reason string

My test code is this:

it("Should create a new ETH-USDC 0.3% position", async function () {
            
            const FEE = 3000;
            
            const { contract, owner } = await loadFixture(deployUniswapPoolFixture) 
            const ethAmount = 10n**18n;
            const usdcAmount = 3000n * 10n ** 6n;

            const tickLower = -887272 // Math.ceil(baseLog(BASE, Math.sqrt(1/1400)));
            const tickUpper = -tickLower // Math.ceil(baseLog(BASE, Math.sqrt(1/1200)));

            await weth.connect(owner).deposit({ value: 100n * 10n ** 18n });
            await weth.connect(owner).approve(contract.address, 100n * 10n ** 18n);

            await network.provider.request({
                method: "hardhat_impersonateAccount",
                params: [USDC_WHALE]
            })

            const usdcWhale = await ethers.getSigner(USDC_WHALE);
            expect(await usdc.balanceOf(USDC_WHALE)).to.be.greaterThan(usdcAmount);


            await usdc.connect(usdcWhale).transfer(owner.address, usdcAmount);
            await usdc.connect(owner).transfer(contract.address, usdcAmount);
            
            const newPosition = await contract.mintPosition(
                                                MAINNET_TOKENS.ETH,
                                                MAINNET_TOKENS.USDC,
                                                FEE,
                                                ethAmount,
                                                usdcAmount,
                                                tickLower,
                                                tickUpper);

            console.log(await dai.balanceOf(owner.address));

            // expect(daiBalanceAfter).to.be.equal(0);

        });

And I get the following error:

Error: Transaction reverted without a reason string
    at <UnrecognizedContract>.<unknown> (0xc36442b4a4522e871399cd717abdd847ab11fe88)
    at UniswapPool.mintPosition (contracts/uniswap/UniswapPool.sol:95)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1802:23)
    at HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:491:16)
    at EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1522:18)
    at HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:118:18)
    at EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)

Note that I'm using MIN_TICK and MAX_TICK for the range

Can you please help me to understand what is wrong with my code?

Thank you very much in advance

Error: Returned error: sender account not recognized

Hi! When running script:
test-erc20.js
I get an error:
Error: Returned error: sender account not recognized on line:
await token.transfer(accounts[0], bal, { from: WHALE });
Can you please tell me what could be the reason?

Error: The send transactions "from" field must be defined!

Hi,

I have downloaded the repo and set the infura key but I am getting this error where executing npx truffle test --network mainnet_fork test/test-uniswap.js:

Contract: TestUniswap
  1) "before each" hook for "should pass"


0 passing (608ms)
1 failing

1) Contract: TestUniswap
     "before each" hook for "should pass":
   Error: Returned error: base fee exceeds gas limit
    at Context.<anonymous> (test/test-uniswap.js:22:40)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

How do I solve it?

Thank you

Help running test-uniswap-liquidity.js

Concerning a tutorial video that I came across around adding/removing liquidity into Uniswap https://www.youtube.com/watch?v=816kTTNzcHs, I have the following the issue.

When I attempt to run test-uniswap-liquidity.js under truffle environment, it keeps failing on this line of code:

await tokenA.transfer(CALLER, TOKEN_A_AMOUNT, { from: TOKEN_A_WHALE });

_truffle(mainnet_fork)> truffle test test/test-uniswap-liquidity.js --network mainnet_fork
Using network 'mainnet_fork'.

Compiling your contracts...
Compiling https://github.com/OpenZeppelin\contracts\token\ERC20\IERC20.sol
Compiling https://github.com/OpenZeppelin\contracts\utils\math\SafeMath.sol
Compiling .\contracts\Flashloan-arbitrage.sol
Compiling .\contracts\Migrations.sol
Compiling .\contracts\TestUniswapLiquidity.sol
Compiling .\contracts\UniswapV2Library.sol
Compiling .\contracts\interfaces\IERC20.sol
Compiling .\contracts\interfaces\IUniswapV2Callee.sol
Compiling .\contracts\interfaces\IUniswapV2Factory.sol
Compiling .\contracts\interfaces\IUniswapV2Pair.sol
Compiling .\contracts\interfaces\IUniswapV2Router01.sol
Compiling .\contracts\interfaces\IUniswapV2Router02.sol
Compiling .\contracts\interfaces\Uniswap.sol
Artifacts written to C:\Users\SAMUEL~1.SAD\AppData\Local\Temp\test--17744-7ubcxUBqpENh
Compiled successfully using:

solc: 0.8.16+commit.07a7930e.Emscripten.clang
step1...
step2...
step4...TOKEN_A_AMOUNT = BN {
negative: 0,
words: [ 779264, 149, <1 empty item> ],
length: 2,
red: null
}
step4...TOKEN_B_AMOUNT = BN {
negative: 0,
words: [ 779264, 149, <1 empty item> ],
length: 2,
red: null
}
Contract: TestUniswapLiquidity
CALLER... 0x031213df405840b7BCdEb5A7A9126BbD77A6aed3
step6...contract: 0xa0A14ceC4C0cFa67a3d5f39A4704465fC2e446B1
step7 - sent Ether...
step8a - CALLER: 0x031213df405840b7BCdEb5A7A9126BbD77A6aed3
step8b - TOKEN_A_AMOUNT (parsed): 10000000000
step8c - TOKEN_B_AMOUNT (parsed): 10000000000
calling again CALLER... 0x031213df405840b7BCdEb5A7A9126BbD77A6aed3
TOKEN_A_WHALE: 0xee2826453A4Fd5AfeB7ceffeEF3fFA2320081268

  1. "before each" hook for "add liquidity and remove liquidity"

0 passing (2s)
1 failing

Contract: TestUniswapLiquidity
"before each" hook for "add liquidity and remove liquidity":
Error: Returned error: sender account not recognized -- Reason given: Custom error (could not decode).
at Context. (test\test-uniswap-liquidity.js:48:18)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
truffle(mainnet_fork)> truffle --version
Truffle v5.5.28 (core: 5.5.28)
Ganache v7.4.0
Solidity - 0.8.16 (solc-js)
Node v16.17.0
Web3.js v1.7.4_

I would greatly appreciate any insights as to how I could resolve this problem which has been going on for several days now.

One other thing, the liquidity concept is only applicable for non-flash swap contracts/transactions, is that correct?
Reason being, I attempted to run a flash swap loan arbitrage app in truffle that I´ve developed but keeps giving me with the Insufficient liquidity error message which was the original reason why I came across your video.

Thanks once again for your help.

BR,
Samuel

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.