Giter Club home page Giter Club logo

bifi's Introduction

BIFI

Description

BiFi is a decentralized finance (DeFi) project that offers a financial service, which enables users to deposit various digital assets and borrow other digital assets against the deposits as collateral. BiFi consists of Solidity smart contracts, which operates on top of EVM-compatible blockchains.

Each supported digital asset on BiFi has a dedicated Market Handler Contract ("Market Handler"). All Market Handlers are intermediated by Market Manager Contract ("Market Manager").

Service Incentive Handler ("SI Handler") manages the reward program that rewards participants (service users and operators) that contributed in the growth and operation of BiFi with Service Incentive Tokens ("SI Tokens"). Liquidation Manager Contract ("Liquidation Manager") manages the liquidation process for users whose Loan-To-Value (LTV) Ratio has exceeded a set threshold.

The BiFi components interact with each other. For example, a user may borrow up to 75% of the value of previously deposited assets, and the value of any digital asset can be expressed as the product of its amount and current price. For this user (borrowing) operation, each Market Handler provides the user balance and the Oracle contract provides the current prices of each Token. Market Manager then validates and executes the action. The user also gets a service incentive for this action; The SI Handler will provide SI Tokens when the user claims. When a price of the user token significantly decreases, the user's debt can be liquidated by anyone via the Liquidation Manager contract.

The logic contracts (Market Handler, SI Handler and Market Manager) are designed so that they can be updated without changing the data storage. Each logic contract has its own data storage contracts to store the data.

Overview

alt text

actions

  • Solidity CI

contracts

  • Solidity contracts for BiFi

migrations

  • Truffle script for testing

Description

BiFi 서비스는 가상화폐를 예치하여 이자를 얻거나, 예치금을 담보로 가상화폐를 대출할 수 있는 DeFi 금융서비스이다. BiFi 서비스는 Solidity로 작성된 Smart Contract로 구성되어 있으며 EVM 호환 블록체인에서 동작한다.

BiFi가 지원하는 여러 가상화폐는 고유의 Market Handler Contract(Market Handler)를 가지고 있으며, 모든 Market Handler Contract는 Market Manager Contract(Market Manager)에 연결되어 Handler 간 연계 작업이 가능하다.

Service Incentive Handler(SI Handler)는 BiFi 서비스 유지에 공헌한 참여자에게 BiFi Token을 보상으로 지급하고, Liquidation Manager Contract(Liquidation Manager)는 총 예치 자산 대비 총 대출 자산의 비율(LTV, Loan-To-Value)이 정해진 수준을 넘긴 사용자의 자산을 청산하는 기능을 제공한다.

BiFi 의 컴포넌트는 각각의 기능이 서로 상호작용 한다. 예를 들어 사용자는 이전에 예치한 모든 가상화폐 가치의 75%만큼 대출을 실행할 수 있는데, Market Manager는 Oracle Contract에서 제공하는 각 가상화폐의 가격정보를 이용하여 사용자가 예치한 가상화폐 가치의 합계를 도출한다. 사용자의 요청("대출")이 발생하면, 각각의 Market Handler는 사용자의 잔액을 제공하고 Oracle 컨트랙트는 각 토큰의 가격을 제공한다.

한편, BiFi 서비스의 로직 Contract(Market Handler, SI Handler, Market Manager)들은 Data를 유지한 상태로 업데이트 할 수 있도록 설계 되어 있다. 로직 Contract들은 데이터를 저장하는 각각의 Data Storage Contract를 보유하며, Handler Proxy를 이용하여 효과적으로 로직 Contract는 교체될 수 있다.

Overview

alt text

actions

  • Solidity CI

contracts

  • BiFi를 구성하는 solidity로 짜여진 contracts

migrations

  • Test용 truffle script

bifi's People

Contributors

bifrost-strategy avatar jonghyuplee avatar miller-kk avatar seinmyung25 avatar seonggwonyoon avatar tlatkdgus1 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

Watchers

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

bifi's Issues

DEPOSIT DAI

i used below codes to test deposit function ,

  await DAIERC20Contract.approve(
    tokenProxyContract.address,
    hre.ethers.utils.parseEther("100")
  );
  await tokenProxyContract.deposit(
    hre.ethers.utils.parseEther("100"),
    false
  );

after deposit , i see getDepositTotalAmount is 200000000000000000000 and balanceOf tokenProxyContract is 100000000000000000000 , why ? i deposited 100 Ethers but total deposit is 200 Ethers .

deposit in to platform

i deployed contracts in fork from mainnet and use this code's to make deposit ,

i use this code's in my test file to make deposit in deployed contracts ,

  await DAIERC20Contract.approve(
    tokenProxyContract.address,
    hre.ethers.utils.parseEther("100")
  );
  const depositTX = await tokenProxyContract.deposit(
    hre.ethers.utils.parseEther("100"),
    false
  );
  await depositTX.wait();

but i get error from _applyInterest(userAddr); in tokenHandler deposit function , because when i make it comment , deposit is ok .
and when i pass flag as true , deposit work !

my deployment is :

const hre = require("hardhat");
const { expect } = require("chai");

describe("", async () => {
let DAIOracleContract;
let oracleProxyContract;
let DAItokenSIContract;
let DAIERC20Contract;
let BIFIERC20Contract;

let managerDataStorageContract;
let etherManagerContract;
let etherLiquidationManagerContract;
let marketHandlerDataStorageContract;
let interestModelContract;

let tokenProxyContract;
let DAImarketSIHandlerDataStorageContract;
let DAItokenHandlerContract;

let callProxyContract;

let owner;

describe("BiFiX Deploy And Test", function () {
it("deploy contracts", async function () {
[owner] = await hre.ethers.getSigners();

  // deploy dai oracle
  const observerOracle = await hre.ethers.getContractFactory(
    "observerOracle"
  );
  DAIOracleContract = await observerOracle.deploy(100000000);
  await DAIOracleContract.deployed();
  console.log("DAIOracleContract deployed to:", DAIOracleContract.address);

  // deploy oracle proxy
  const oracleProxy = await hre.ethers.getContractFactory("oracleProxy");
  oracleProxyContract = await oracleProxy.deploy(DAIOracleContract.address);
  await oracleProxyContract.deployed();
  console.log(
    "oracleProxyContract deployed to:",
    oracleProxyContract.address
  );

  // deploy daiSI from contracts/marketHandler/tokenSI.sol
  const tokenSI = await hre.ethers.getContractFactory("tokenSI");
  DAItokenSIContract = await tokenSI.deploy();
  await DAItokenSIContract.deployed();
  console.log(
    "DAItokenSIContract deployed to:",
    DAItokenSIContract.address
  );

  // deploy erc20 dai from /tokenStandard/openzeppelinERC20.sol
  const DAIERC20 = await hre.ethers.getContractFactory(
    "openzeppelinERC20dai"
  );
  DAIERC20Contract = await DAIERC20.deploy("dai", "DAI", 18);
  await DAIERC20Contract.deployed();
  console.log("DAIERC20Contract deployed to:", DAIERC20Contract.address);

  // deploy erc20 BIFI from /tokenStandard/openzeppelinERC20.sol
  const BIFIERC20 = await hre.ethers.getContractFactory(
    "openzeppelinERC20"
  );
  BIFIERC20Contract = await BIFIERC20.deploy("BIFI", "BIFI", 18);
  await BIFIERC20Contract.deployed();
  console.log("BIFIERC20Contract deployed to:", BIFIERC20Contract.address);

  // deploy ManagerDataStorage from contracts/marketManager/managerDataStorage/managerDataStorage.sol
  const managerDataStorage = await hre.ethers.getContractFactory(
    "managerDataStorage"
  );
  managerDataStorageContract = await managerDataStorage.deploy();
  await managerDataStorageContract.deployed();
  console.log(
    "managerDataStorageContract deployed to:",
    managerDataStorageContract.address
  );

  // deploy Token manager or manager from contracts/marketManager/tokenManager.sol
  const etherManager = await hre.ethers.getContractFactory("etherManager");
  etherManagerContract = await etherManager.deploy(
    managerDataStorageContract.address,
    oracleProxyContract.address,
    "0x6d3A0d57Aa65fe133802c48F659521F7693fa477",
    BIFIERC20Contract.address
  );
  await etherManagerContract.deployed();
  console.log(
    "etherManagerContract deployed to:",
    etherManagerContract.address
  );

  // change manager address in managerDataStorage
  await managerDataStorageContract.setManagerAddr(
    etherManagerContract.address
  );

  // transfer 1000000000 BIFI to etherManagerContract
  await BIFIERC20Contract.transfer(
    etherManagerContract.address,
    hre.ethers.utils.parseEther("1000000000")
  );

  // transfer 1000000000 DAI to user
  await DAIERC20Contract.transfer(
    owner.address,
    hre.ethers.utils.parseEther("1000")
  );

  // deploy etherLiquidationManager from /contracts/marketManager/liquidationManager.sol
  const etherLiquidationManager = await hre.ethers.getContractFactory(
    "etherLiquidationManager"
  );
  etherLiquidationManagerContract = await etherLiquidationManager.deploy(
    etherManagerContract.address
  );
  await etherLiquidationManagerContract.deployed();
  console.log(
    "etherLiquidationManagerContract deployed to:",
    etherLiquidationManagerContract.address
  );

  // set etherLiquidationManager address in etherManagerContract
  await etherManagerContract.setLiquidationManager(
    etherLiquidationManagerContract.address
  );

  // MarketHandlerDataStorage
  const borrowLimit = hre.ethers.utils.parseEther("0.75");
  const martinCallLimit = hre.ethers.utils.parseEther("0.93");
  const minimumInterestRate = 0;
  const liquiditySensitive = hre.ethers.utils.parseEther("0.05");

  const marketHandlerDataStorage = await hre.ethers.getContractFactory(
    "marketHandlerDataStorage"
  );
  marketHandlerDataStorageContract = await marketHandlerDataStorage.deploy(
    borrowLimit,
    martinCallLimit,
    minimumInterestRate,
    liquiditySensitive
  );
  await marketHandlerDataStorageContract.deployed();
  console.log(
    "marketHandlerDataStorageContract deployed to:",
    marketHandlerDataStorageContract.address
  );

  // interestModel
  const interestModel = await hre.ethers.getContractFactory(
    "interestModel"
  );
  interestModelContract = await interestModel.deploy(
    hre.ethers.utils.parseEther("0.025"),
    hre.ethers.utils.parseEther("0.8"),
    hre.ethers.utils.parseEther("0.1"),
    hre.ethers.utils.parseEther("0.18"),
    hre.ethers.utils.parseEther("0.825")
  );
  await interestModelContract.deployed();
  console.log(
    "interestModelContract deployed to:",
    interestModelContract.address
  );

  // handlerProxy
  const tokenProxy = await hre.ethers.getContractFactory("tokenProxy");
  tokenProxyContract = await tokenProxy.deploy();
  await tokenProxyContract.deployed();
  console.log(
    "tokenProxyContract deployed to:",
    tokenProxyContract.address
  );

  // DAI si DataStorage
  const marketSIHandlerDataStorage = await hre.ethers.getContractFactory(
    "marketSIHandlerDataStorage"
  );
  DAImarketSIHandlerDataStorageContract =
    await marketSIHandlerDataStorage.deploy(tokenProxyContract.address);
  await DAImarketSIHandlerDataStorageContract.deployed();
  console.log(
    "DAImarketSIHandlerDataStorageContract deployed to:",
    DAImarketSIHandlerDataStorageContract.address
  );

  // DAI Handler
  const tokenHandler = await hre.ethers.getContractFactory("tokenHandler");
  DAItokenHandlerContract = await tokenHandler.deploy();
  await DAItokenHandlerContract.deployed();
  console.log(
    "DAItokenHandlerContract deployed to:",
    DAItokenHandlerContract.address
  );

  // const daiBorrowLimit = hre.ethers.utils.parseEther("0.75");
  await etherManagerContract.handlerRegister(2, tokenProxyContract.address);
  await marketHandlerDataStorageContract.setTokenHandler(
    tokenProxyContract.address,
    interestModelContract.address
  );
  await tokenProxyContract.initialize(
    2,
    DAItokenHandlerContract.address,
    etherManagerContract.address,
    interestModelContract.address,
    marketHandlerDataStorageContract.address,
    DAIERC20Contract.address,
    "DAI",
    DAItokenSIContract.address,
    DAImarketSIHandlerDataStorageContract.address
  );

  await marketHandlerDataStorageContract.setLimitOfAction(
    hre.ethers.utils.parseEther("100000")
  );
  await marketHandlerDataStorageContract.setLiquidityLimit(
    hre.ethers.utils.parseEther("1")
  );

  const ABI = [
    "function setUnderlyingTokenDecimal(uint256 _underlyingTokenDecimal)",
  ];
  const iface = new hre.ethers.utils.Interface(ABI);
  const callBytes = iface.encodeFunctionData("setUnderlyingTokenDecimal", [
    (10 ** 18).toString(),
  ]);

  await tokenProxyContract.handlerViewProxy(callBytes);

  // CallProxy
  const callProxy = await hre.ethers.getContractFactory(
    "callProxyManagerCallProxyHandlerCallProxyMarketCallProxyUserCallProxySISafeMath"
  );
  callProxyContract = await callProxy.deploy(etherManagerContract.address);
  await callProxyContract.deployed();
  console.log("callProxyContract deployed to:", callProxyContract.address);
}).timeout(60000);

it("check balance for owner", async function () {
  expect(
    await BIFIERC20Contract.balanceOf(etherManagerContract.address)
  ).to.equal(hre.ethers.utils.parseEther("1000000000"));

  expect(await DAIERC20Contract.balanceOf(owner.address)).to.equal(
    hre.ethers.utils.parseEther("10000")
  );
}).timeout(60000);

it("we can deposit", async function () {
  await DAIERC20Contract.approve(
    tokenProxyContract.address,
    hre.ethers.utils.parseEther("100")
  );
  const depositTX = await tokenProxyContract.deposit(
    hre.ethers.utils.parseEther("100"),
    false
  );
  await depositTX.wait();
}).timeout(60000);

});
});

params for InterestModel contract

Hi, why you didn't passed any parameters for instances["InterestModel"] = await deployer.deploy(InterestModel) to deploy InterestModel contract ?

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.