Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions contracts/mocks/tokens/ERC20Mock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,21 @@ contract ERC20Mock is ERC20 {
}

function setMetadata(
string memory name,
string memory symbol,
uint8 __decimals
string memory tokenName,
string memory tokenSymbol,
uint8 tokenDecimals
) public {
_name = name;
_symbol = symbol;
_decimals = __decimals;
_name = tokenName;
_symbol = tokenSymbol;
_decimals = tokenDecimals;
}

function setName(string memory name) public {
_name = name;
function name() public view override returns (string memory) {
return _name;
}

function setSymbol(string memory symbol) public {
_symbol = symbol;
}

function setDecimals(uint8 __decimals) public {
_decimals = __decimals;
function symbol() public view override returns (string memory) {
return _symbol;
}

function decimals() public view override returns (uint8) {
Expand Down
1 change: 1 addition & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ const PoolAsset = {
SafeTracker: 5,
USDC: 6,
cbBTC: 7,
NXM: 255,
};

const ContractTypes = {
Expand Down
24 changes: 17 additions & 7 deletions lib/protocol.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { ethers } = require('ethers');
const { parseEther, ZeroAddress } = ethers;
const { BigIntMath } = require('./helpers');

const COVER_PRICE_DENOMINATOR = 10000n;

Expand Down Expand Up @@ -33,15 +34,15 @@ function calculateInternalPrice(currentState, observations, capital, supply, cur

const averagePriceB = (currentObservation.priceCumulativeBelow - firstObservation.priceCumulativeBelow) / elapsed;

const priceA = averagePriceA > spotPriceA ? spotPriceA : averagePriceA;
const priceB = averagePriceB > spotPriceB ? averagePriceB : spotPriceB;
const priceA = BigIntMath.min(averagePriceA, spotPriceA);
const priceB = BigIntMath.max(averagePriceB, spotPriceB);
const bookValue = (parseEther('1') * capital) / supply;

const internalPrice = ((priceA + priceB - parseEther('1')) * capital) / supply;
const internalPrice = priceA + priceB - bookValue;
const maxPrice = (parseEther('1') * 3n * capital) / supply; // 300% BV
const minPrice = (parseEther('1') * 35n * capital) / (supply * 100n); // 35% BV

const maxInternalPrice = internalPrice > maxPrice ? internalPrice : maxPrice;
return maxInternalPrice > minPrice ? minPrice : maxInternalPrice;
return BigIntMath.max(BigIntMath.min(internalPrice, maxPrice), minPrice);
}

// TODO: eject from lib - we'll clearly not use it outside of tests
Expand Down Expand Up @@ -71,6 +72,7 @@ async function getInternalPrice(ramm, pool, tokenController, timestamp) {
timestamp: observation.timestamp,
};
}

const state = {
nxmA: previousState.nxmA,
nxmB: previousState.nxmB,
Expand All @@ -81,8 +83,8 @@ async function getInternalPrice(ramm, pool, tokenController, timestamp) {
};

const [currentState] = await ramm._getReserves(state, context, timestamp);

const observations = await ramm._updateTwap(state, previousObservations, context, timestamp);

return calculateInternalPrice(currentState, observations, capital, supply, timestamp, { GRANULARITY, PERIOD_SIZE });
}

Expand All @@ -94,13 +96,20 @@ function calculatePremium(amount, rate, period, price, allocationUnit) {
const coverNXMAmount =
nxmAmount % allocationUnit === 0n ? nxmAmount : (nxmAmount / allocationUnit + 1n) * allocationUnit;

const premiumInNxm = (((coverNXMAmount * price) / COVER_PRICE_DENOMINATOR) * period) / (365n * 24n * 60n * 60n);
const annualizedPremiumNxm = (coverNXMAmount * price) / COVER_PRICE_DENOMINATOR;
const premiumInNxm = (annualizedPremiumNxm * BigInt(period)) / (365n * 24n * 60n * 60n);

const premiumInAsset = (premiumInNxm * rate) / parseEther('1');

return { premiumInNxm, premiumInAsset, coverNXMAmount };
}

function calculateFixedPricePremium(coverAmount, period, fixedPrice, nxmPerAllocationUnit, targetPriceDenominator) {
const premiumPerYear = (coverAmount * nxmPerAllocationUnit * fixedPrice) / targetPriceDenominator;
const yearInSeconds = BigInt(365 * 24 * 3600); // 365 days in seconds
return (BigInt(premiumPerYear) * BigInt(period)) / yearInSeconds;
}

// ====================== STAKING =============================================

function calculateFirstTrancheId(lastBlock, period, gracePeriod) {
Expand Down Expand Up @@ -159,6 +168,7 @@ module.exports = {
calculateInternalPrice,
getInternalPrice,
calculatePremium,
calculateFixedPricePremium,
calculateFirstTrancheId,
stakeOnly,
stake,
Expand Down
Loading