Giter Club home page Giter Club logo

aave-utilities's People

Contributors

0xnook avatar alderian avatar defispartan avatar dependabot[bot] avatar dghelm avatar drewcook avatar foodaka avatar grothem avatar joaquinbattilana avatar joshstevens19 avatar kartojal avatar rex4539 avatar sakulstra avatar satanworker avatar sendra avatar volt62 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

Watchers

 avatar  avatar  avatar  avatar  avatar

aave-utilities's Issues

Create complete class typing's for everything which holds an important that it must be a certain format/value etc

So when we are dealing with something that if something goes wrong with the value or the value wrong someone could execute something very bad proper class types normally come in nice. What I mean by this is let's take userId as an example you probably wouldn't do it for this but just to explain what I mean and assume its a guid, instead of string it be a UserId class aka:

export function formatUserSummaryData(
  poolReservesData: ReserveData[],
  rawUserReserves: UserReserveData[],
  userId: string,
  usdPriceEth: BigNumberValue,
  currentTimestamp: number

turns into

export function formatUserSummaryData(
  poolReservesData: ReserveData[],
  rawUserReserves: UserReserveData[],
  userId: UserId,
  usdPriceEth: BigNumberValue,
  currentTimestamp: number

Now on this class, it validates and throws runtime errors if it doesn't match the time on new User(xxxxx) stopping anything bad from happening. You could write it similar to this:

export default class UserId extends BaseType<Guid, string, string> {
  private _value: string | undefined;

  constructor(value: string) {
    super(new.target.name, value);
  }

  public equals(other: Guid): boolean {
    return other.value === this.value;
  }

  protected validate(): void {
    if (typeof this._value !== 'string' || !Utils.isGuid(this._value)) {
      throw Errors.runtimeErrorWithLogger(
        this._log,
        'String supplied is not a guid string',
        this._value,
      );
    }
  }

  protected setValue(value: string): void {
    if (typeof value === 'string') {
      this._value = value;
    }
  }

  public get value(): string {
    if (!this._value) {
      throw this.valueNotSetError();
    }
    return this._value;
  }
}
export default abstract class BaseType<TClass, TValue, TSetValue> {
  protected _log: Logger;
  constructor(className: string, value: TSetValue) {
    this._log = new Logger(className);

    // set the value
    this.setValue(value);
    // force the validation to always fire straight away on creation of any classes
    // which extend the Base
    this.validate();
  }

  /**
   * Gets the value
   */
  public abstract get value(): TValue;

  /**
   * Validate the class
   */
  protected abstract validate(): void;

  /**
   * Sets the value
   */
  protected abstract setValue(value: TSetValue): void;

  /**
   * Is equal to
   * @param other The other class
   */
  public abstract equals(other: TClass): boolean;

  /**
   * Value not set error
   */
  protected valueNotSetError(): Error {
    return Errors.runtimeErrorWithLogger(this._log, 'Value set is undefined');
  }
}

Now as you use TS you start forgetting to check certain details and this brings in this approach.

Refactor formatUserSummary

1.) Break logic in generate-raw-summary and generate-raw-reserve down further.

  • Separate files for formatting the ReserveData, ComputedUserReserve, and summary fields to reduce complexity and required parameters for each file

2.) Remove any modifications to ReserveData in format-user-reserve, should all be handled in previous steps

3.) Unit test

  • calculate-rewards
  • calculate-supplies
  • generate-raw-user-reserve *once finished
  • generate-raw-user-summary *once finished
  • format-user-reserve *once finished
  • format-user-summary

Remove TheGraph in as many places as possible

Obviously, TheGraph is good to do some queries but on some cases we do not need to use the graph. Even more nothing stopping us create solidity helper contracts to avoid fees altogether this would improve:

  • charges and fees on TheGraph
  • not dependent on them going down and use not working
  • flexibility with responses from the helper sol contract
  • naturally faster and onchain real-time data (not dependent on TheGraph indexing it slower etc)

A lot of cases we don't even need a helper sol we can use multicall and the standard onchain contract to lookup the data.

expose aave (helper) addresses

Issue

Currently there's no easy way to figure out the aave addresses (aka there's no package one can import to get the currently up to date addresses). Also there's no easy way to get notified in case an address was updated.

What currently get's closest to this is:
https://github.com/aave/aave-addresses with jsons per network https://aave.github.io/aave-addresses/kovan.json

This is lacking helper contracts though as they are not registered at the protocol.

Proposed solution

For helper contracts I think it would be reasonable to have a static addresses = {[Network]: string} on the service so that people can simply access the address.

Alternative solution

We could also have a @aave/constants package or similar containing the addresses. This package could contain all the "generatable addresses" and all the helper contract addresses.

tsdocs comments

We should provide tsdocs for non self explanatory properties to enable helpful comments by IDEs.

We should first fix the cases we already have and from here on make it a requirements in reviews. We might wanna add some contribution guidelines to account for such things.

image

Document process for fetching and formatting user and reserves data

Add a guide to the README explaining the process used on the Aave frontend to fetch and format pool data using the UiPoolDataProvider contract and formatReserves / formatUserSummaryData helper functions.

Add UiPoolDataProvider contract code and addresses to the GitBook docs.

Tx-Builder Initializer

Feature Tx-Builder

Port and adapt the tx-builder initializations to be used with different importable modules:

  • lendingPool
  • Governance
  • Staking
  • Data

Integrate ethereum-multicall into the lib

We tend to do separate JSONRPC async calls even if we are calling the same contract for example

image

This will call the same contract twice once to get the decimals and another time to get the allowance. We can bulk these together into 1 JSONRPC call meaning we doing less calls and quicker responses.

metric shows that a JSONRPC request most the times the network coming back eats up most the response time

say you got 3 jsonrpc calls they will probs take 200MS each = 600MS (as it awaits for response)
if you batch this in 1 single JSONRPC call the result tends to be 200MS or close to = x3 improvement in speed.

We can batch together more then just a single contract as well say a method calls 4-5 different contracts we can use this to batch it in 1 JSONRPC again. This can really improve speed and bills from the node provider.

Open source lib which I support which we could use for this -
https://github.com/joshstevens19/ethereum-multicall

Add UiPoolDataProvider to contract-helpers

Feature

Create the data module of tx-builder and add the different data getters for UiPoolDataProvider. (Keep in mind that it should use the new version of the provider, the one that has not incentives data on the reserves)

Move Incentives from UiPoolDataProvider to new UiIncentivesDataProvider contract

Remove the return of the reserve incentives from the UiPoolDataProvider.

Use current deployed version as base: https://github.com/aave/protocol-v2/blob/feat/split-ui-dataprovider-logic/contracts/misc/UiPoolDataProvider.sol

move from 139 - 160 (reserve incentives)
move from 187 - 200 (user reserve incentives)

Also move emissionEndTimestamp (given by incentivesController)
Also move userUnclaimedRewards (incentive rewards unclaimed by the user)

We need to Add also an extra check to instead of passing or hardcoding the incentives controller, we should get it from the a/s/v tokens (as they are initialized with it) this will give us also the possibility to operate with incentive controller by token instead of by network. Take into account that having incentivesController by token we will also need to get emissionEndTimestamp by token (not sure if this will have reaple effect. I think it shouldn't as if multiple tokens have same incentivesController the emissionEndTimestamp will be the same)

userUnclaimedRewards will also be affected by the incentivesController by token. If we have different IncentivesControllers then we provably will need to add all the userUnclaimedRewards but if they are the same then we shouldn't as userUnclaimedRewards accounts for all the unclaimedRewards of the different token incentives. Maybe we could calculate teh unclaimed rewards by getting for every asset the method getUserAssetData, and reproducing smart contract calls in the lib, this way we could query for every token without the need to add extra logic in the contract. (So yeah, take a deeper look at that part)

Update Caching-service with new Helper Contracts

Feature Request

Update the caching-service with the new UiPoolDataProvider (without the reserve incentives)

Add the new IncentivesProvider helper contract to the caching-service so as to query with different frequency (15 - 20 secs) than the reserves quering.

The data provided by this should be usable with the new aave-js lib

Add Fei incentives as native

Background: They used the wrong debt token which has the incentives controller as private. This means they cannot get the incentives controller from the token and therefore cannot display the correct apr.

Hardcode Fei incentives so it is as if it was native incentive, so it can show apr % and can be claimed directly from app.aave.com

This is needed because the FEI debtToken that is incentiviced is not from the latest version of tokens, so we can not get the incentive information automatically from the UiIncentivesProvider contract

fix lerna / migrate away from lerna

Feature Request

As you can see in our ci workflow we're having multiple issues with lerna right now.
lerna/lerna#2788
lerna/lerna#1893
Lerna seems to be no longer properly maintained: lerna/lerna#1893
Might make sense to put some effort into fixing them/maintaining a fork as prs at lerna seem to be no longer to be accepted.

Alternatives to consider

Simplify parameters

Currently the data functions require an excessive number of inputs, this should be re-designed to be easier to integrate.

Suggestion:

An aaveDataProvider object that can be initialized with a network and provider, and supports the following functions

userSummary(userAddress, marketAddress?, assetAddress?)

reserveSummary(marketAddress?, assetAddress?)

where marketAddress = lendingPoolAddressProvider for the market, assetAddress = underlyingAssetAddress, and market/asset default to all if not specified.

Define namespaces

Namespaces = beautiful codebase to work with mainly because its easy to get to certain things. for example on v1 tx builder you have a file called computations-and-formatting.ts and this has many functions in it. If we can expose a clean interface to interact with it this means the learning curve for the user is a lot less.

stuff like

aave.v1.calculate.compoundedInterest
aave.v1.calculate.healthFactorFromBalances
aave.v1.calculate.availableBorrowsETH
aave.v1.format.reserves
aave.v1.format.userSummaryData

etc etc! you want to do this in a partial import way so would be more like:

import { calculate as v1Calculate, format as v1Format } from 'aavejs/v1'

v1Calculate.compoundedInterest
v1Calculate.healthFactorFromBalances
v1Calculate.availableBorrowsETH
v1Format.reserves
v1Format.userSummaryData

The aim here is to make your tech easy for everyone to understand, starting with the interface just like a REST API make it human-readable and its a great start

Helpers refactor

Change lendingPool name to lendingPoolAddressProvider

Change to typechain

Contract types should be its own package

These are all generated files aka they should not be touched manually they are autogenerated we should move them out of touch so they don't randomly get changed. Going forward we should sync with the contracts and make on push generate these typings and upload them to the shared package.

UiPoolDataProvider multi Base Currency Feeds

Feature

We need to update the UiPoolDataProvider so it takes into account the base currency of the market. this is the version we should branch of: https://github.com/aave/protocol-v2/tree/feat/split-ui-dataprovider-logic

To do this we need to get the information of the AaveOracle.
0 - get AaveOracle from PoolAddressProvider
1 - get Base currency information from AaveOracle:

  • We have two versions of AaveOracle so we need to account for that when getting the info from there:
    - Check if we can get BASE_CURRENCY (new version). if we can:
    - check if its 0x0 (usd case)
    - if its erc20 address also get BASE_UNITS (decimals)
    - if we can't get BASE_CURRENCY (means we are on old version). Then get WETH constant. get decimals from WETH return
    2 - get / return the base currency price in usd(provably by passing the base currency address to the oracle). In case of 0x0 (usd) return 1
    3- get / return native network currency in usd price (we could hardcode the chainlink pricefeed). This is so we can display correct usd pricing for gas estimations
    4- return base currency decimals. In case of Usd 8

Simple POC for subgraph design

Background: We are using subgraphs for different things. We use it for different versions. Some issues

  • Data lives in the graph and we dont have direct access to it. On graph you dont have a way to query the last 60 days. There are limits on how you can query. Before we were building services to index the graph data.
  • The graph is slow to fetch data. Ampl is broken because we dont track rebase events.
    If we now fix this there is no testing framework. Thus we need to resync the graph which takes a month. Basically doesnt scale with the data and users we have.

Achieve: How can we replace this service?
Alternatives: Bitquery?

use ethereum-abi-types-generator instead of typechain ones

TypeChain is awesome but at the end of the day, it adds bundle size to the output. Every TypeChain factory IS a class and you have to call it like this.contractFactory.connect < this ADDS bundle size to the output. If you look what is in some of these factories it has LONG abi strings etc which can eat up bundle size for sure! Just look at tx-builder > contract-types that's 428KB of stuff that could be added to the output of the bundle.

I promote we use https://github.com/joshstevens19/ethereum-abi-types-generator < was built for this exact reason you just use native ethers interface and everything in the generated types are interfaces meaning once compiled no bundle size is added to the output (as interfaces are not real). It also does other things typechain does not > https://github.com/joshstevens19/ethereum-abi-types-generator#ethereum-abi-types-generator-vs-typechain

On top of this I see in the project you have got the return types of the contracts tx-builder > types this will all be redundant with this package as it exposes them all for you without you having to recreate it.

not the end of the world but if our aim is bundle size aka smallest package going then this could be a good place to start.

required timestamps

In the current version of @aave/protocol-js we have a lot of non required timestamps where we then default to Date.now() or similar.

This caused a few issues in the past with wrong system clocks and shit like that. While making these field required won't necessarily solve these issues it will make debugging them easier.

Imo low level utility library should be as explicit as possible - if a method needs the currentTimestamp to perform it's math it should be a required field, not optional.

This was previously discussed and decided - if you disagree though, feel free to comment.

Transaction builder for lending pool

Background:
The tx builder in AAVEJS. A private package that we open sourced. Migrated https://github.com/aave/aave-js/tree/master/src/tx-builder into Aave JS.

If you want to interact with the protocol there are specific requirements. A lot of these methods have many parameters. Ie specify which pool, credit delegation, borrow, flashloan, etc.

The tx builder allows you to expose an easy to use and type interface to interact with the Aave protocol.

  • Deposit
  • Borrow
  • ....

Problem: This was built for Aave v1 and for graph data. Most times you get data from RPC and not the graph data. Currently we are transforming the slim RPC data back to nested graph structure so can use older helper functions. They will split the up the configuration file https://github.com/aave/aave-js/blob/master/src/tx-builder/config/defaultConfig.ts#L3 . Plan is to expose single service for lending pool, incentives, governance, staking, swapping.

formatUserSummary doesn't return availableBorrowsUSD

Bug Report

formatUserSummary doesn't return availableBorrowsUSD but all other usd values

Package name / version

0.15

Expected behavior

Method should return either all or no usd values, but not mixed content.

Multipackage releases

Currently aave-js is a single pakage shipping everything included although you might never need it.
Therefore it would be great if our new package structure would allow publishing @aave/tx-builder and perhaps more from a single repo @aave/calculation-utils.

In the past i've been using lerna for these kind of things, but there might be newer/cooler stuff with native typescript support.
Example of a lerna monrorepo: visx

Remove incentive calculation from generalized methods.

Currently formatReserves does a lot besides formatting the reserve. Reward incentive calculation should not be part of it, because:
a) most reserves don't have rewards
b) you might not be interested in rewards
c) in the future we might have multiple rewards per reserve

Therefore my suggestion would be to not do it at all in formatReserves and move the responsibility to userland via calculateAPYs or similar. Once we know exactly how this will work in the future we might add an additional helper method to calculate multiple incentives at once, but that's not needed yet.

  • remove incentive calculation from formatReserve
  • remove incentive calculation from formatUserReserve
  • expose helper methods to do it on demand for a reserve or userReserve

Support multiple IncentiveController's per network

Currently each network only has one associated reward asset and IncentivesController in the aave-ui. That#s a oversimplification that was true, but is no longer true.

In theory every subtoken (a/s/v) can have it's own incentiveController and we should support that.

Move configs to independent files

Currently we have most configs in packag.json - we had to learn that#s confusing is people didn't seem to understand where lint & jest rules came from.
Let's move it to a config file or folder

BaseCurrency

Currently we use both USD and ETH in he library.
As the baseCurrency is variable though we shouldn't be opinionated on the currency imo (especially now as it might change).

  • In reserves the priceInEth will essentially be tokenPriceInReferenceCurrency (perhaps we find a better name, but that's what it is, might be eth/usd/avax, we don't know we don't care)
  • Instead of usdPriceEth we have a usdPriceReferenceCurrency (for usd feeds this will be one)
  • The only addition we'll have is a referencePriceDecimals field which oppose to our current static 18 decimals needs to be used when doing stuff with the former usdPriceEth

Feel free to suggest better parameter naming

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.