FOAM Model

This page describes the FOAM Model and its typescript and solidity libraries at a high level. FOAM stands for "First order approximation Model".

Summary

The FOAM model approximates various quantities that relate to the Concrete Core functionalities, such as policy pricing, expected returns and claim probabilities. It does so by approximating the hitting probabilities of price trajectories within a certain time horizon by a parametric model. You can find a more refined description here.

Motivation

Many of the core products of Concrete, such as the protection policies and the reward distribution depend on Monte-Carlo simulations (see Probability Engine) and quantitative predictive models (see Quantitative framework). These tools are sophisticated but are hard to implement on chain. Sampling a hidden distribution by running many test scenarios is effective, but compute and time intensive. The FOAM model aims to provide a simple (not compute intensive) set of formulas that can provide a good functional relation for the above-mentioned quantities at the cost of possibly diminished accuracy (the "first order" part). Ultimately the objective is to run the FOAM Model on chain.

Central Concepts

There are two central quantities that inform most of the formulas in the FOAM model. First and foremost we consider the hitting probability P(dx, T) that the price drops by an amount dx over the time horizon T. The first assumption here is that this probability does not depend on the starting price, but only on the drop. The parametric model that describes this hitting probability very well (and agrees to a great extend with the historical data from crypto price trajectories) is given by:

P(dx,T)=exp(aTx4+bTx3+cTx2+dTx)P(dx, T) = exp(a_T x^4 + b_T x^3 + c_T x^2+ d_T x)

The other central quantity is the credit injection factor. This factor allows us to compute the amount of collateral that sits in the lender after k claims. Here x is the initial borrowed amount and D is the disbursed amount at each claim:

fk=(1+Dλx)kf_k = \left(1 + \frac{D\lambda}{x}\right)^{k}

For instance, when we borrow an amount x and the protection happens at an LTV of Lambda, then we can work back what the amount of collateral is that must sit inside of the lender after k claims, irrespective of the initial amount of collateral. Of course when the initial deposit x is given and the protection LTV is given, too, then the collateral amount at claim time is known, too. The amount of collateral that is inside the lender after k claims is given by:

cfk1ifk1else( k=0)cc\cdot f_{k-1}\quad \text{if} \quad k\geq 1 \quad \text{else( } k=0\text{)}\quad c

Solidity Library

The solidity library consists of two sub-libraries. The MathUtils Library, which does the basic floating-point arithmetics and the hitting-probability calculation. and the PolicyLib which is the application of the math utilities to the Concrete use case. Please visit the repo at https://github.com/Blueprint-Finance/foam-js-and-solidity-library to learn more.

MathUtils Library

The MathUtils library provides utility functions for mathematical operations, particularly focusing on fixed-point arithmetic operations in Solidity. This library includes functions for multiplication and division of both unsigned and signed integers, ensuring accurate calculations within the constraints of Solidity's integer types.

Function Signatures and Purposes

  • uumul(uint256 x, uint256 y): Multiplies two unsigned integers, dividing by a predefined denominator for fixed-point arithmetic.

  • uudiv(uint256 x, uint256 y): Divides an unsigned integer by another, multiplying by a predefined denominator for fixed-point arithmetic.

  • usmul(uint256 x, int256 y): Multiplies an unsigned integer with a signed integer, dividing by a predefined denominator for fixed-point arithmetic.

  • usdiv(uint256 x, int256 y): Divides an unsigned integer by a signed integer, multiplying by a predefined denominator for fixed-point arithmetic.

  • approx_minus_exp(uint256 x): Approximates the exponential function for negative inputs using piecewise linear functions.

  • quartic(uint256 x, int256 a, int256 b, int256 c, int256 d): Computes a quartic polynomial function.

  • function hitting_ratio(uint256 drop, int256 a, int256 b, int256 c, int256 d): Computes the hitting ratio.

PolicyLib Library

PolicyLib library is used for policy-related calculations, working closely with the MathUtils library. It provides functions to calculate various financial metrics based on policy parameters.

Function Signatures and Purposes

  • creditInjectionFactor(...): Calculates the credit injection factor based on various policy parameters.

  • relativePriceDrop(...): Determines the relative price drop based on initial LTV and other policy parameters.

  • debtToEquityPerBorrowedUnit(...): Computes the debt to equity per borrowed unit based on policy parameters.

  • debtToEquity(...): Calculates the total debt to equity ratio for a given borrowed amount and policy parameters.

JavaScript Library

Alongside our Solidity contracts, we provide a JavaScript library for off-chain functions, which can be bundled into a frontend library. These functions replicate the logic of the Solidity contract and can be executed in a JavaScript runtime environment.

Functions

  • DENOM: A constant used for fixed-point arithmetic, set to 10^5.

  • _creditInjectionFactor(ltv_protect, liq_threshold, claim_fee, credit_injection_factor_per_claim, number_of_claims, total_claims): Calculates the credit injection factor based on various policy parameters.

  • quartic(x, a, b, c, d): Computes a quartic polynomial function.

  • hittingRatio(drop, a, b, c, d): Calculates the hitting ratio using a quartic polynomial and an exponential approximation.

  • _relativePriceDrop(initial_ltv, ltv_protect, liq_threshold, claim_fee, credit_injection_factor, number_of_claims, total_claims): Determines the relative price drop based on initial LTV and other policy parameters.

  • hittingRatioForPolicy(initial_ltv, ltv_protect, liq_threshold, claim_fee, credit_injection_factor, number_of_claims, total_claims, a, b, c, d): Calculates the hitting ratio for a given policy.

  • surplusCollateralMinusDebtAfterClaim(borrowed, ltv_protect, liq_threshold, claim_fee, credit_injection_factor, number_of_claims, total_claims): Calculates the surplus collateral minus debt after a claim.

These JavaScript functions are intended for off-chain use and can be executed using the command:

yarn hardhat run scripts/test.ts

They provide a convenient way to simulate and interact with the contract's logic in a non-blockchain environment, making them ideal for development, testing, and frontend integration.

Last updated