Skip to content

Commit

Permalink
Merge pull request #3 from iMCrazyDev/v5
Browse files Browse the repository at this point in the history
v5
  • Loading branch information
sepezho authored Jul 1, 2024
2 parents 4ce9764 + 73ce494 commit b964cde
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 23 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ build
dist
temp
*.log
.env
.env
.vscode/
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/)
and this project adheres to [Semantic Versioning](https://semver.org/).

## 0.5.0 - 2024-06-29
This release contains breaking changes.

### Added
- Reserve variables parsing on user & master sc
- Added endpoint argument for getPrices, default api.stardust-mainnet.iotaledger.net
- Added applyDust (default false) option in parseUserLiteData and parseUserData

### Changed
- Master contracts' version
- Testnet master contract address
- Parsers on master sc
- Parsers on user sc
- Liquidation calculations now counts with reserve factor from master config

### Fixed
- UserBalance calculation was fixed

## 0.4.0 - 2024-06-01
This release contains breaking changes.

Expand Down
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
rootDir: './tests',
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/tests/**/*.ts', '**/?(*.)+(spec|test).ts'],
};
8 changes: 3 additions & 5 deletions src/api/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,10 @@ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: Asse
);
}

const reserveFactor = 10n;
const reserveScale = 100n;
supplyInterest = mulDiv(
mulDiv(borrowInterest, utilization, MASTER_CONSTANTS.FACTOR_SCALE),
reserveScale - reserveFactor,
reserveScale,
MASTER_CONSTANTS.ASSET_RESERVE_FACTOR_SCALE - assetConfig.reserveFactor,
MASTER_CONSTANTS.ASSET_RESERVE_FACTOR_SCALE,
);

return {
Expand Down Expand Up @@ -205,7 +203,7 @@ export function calculateLiquidationData(
const values: bigint[] = [];
const gCollateralAssetConfig = assetsConfig.get(gCollateralAsset)!;
const gLoanAssetConfig = assetsConfig.get(gLoanAsset)!;
const liquidationBonus = gLoanAssetConfig.liquidationBonus;
const liquidationBonus = gCollateralAssetConfig.liquidationBonus;
const loanDecimal = 10n ** gLoanAssetConfig.decimals;
values.push(
(bigIntMax(gCollateralValue / 2n, bigIntMin(gCollateralValue, 10_000_000_000n)) *
Expand Down
101 changes: 91 additions & 10 deletions src/api/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,22 @@ import {
presentValue,
} from './math';
import { loadMaybeMyRef, loadMyRef } from './helpers';
import { BalanceType, UserBalance, UserData, UserLiteData } from '../types/User';
import { BalanceType, UserBalance, UserData, UserLiteData, UserRewards } from '../types/User';

// Will be in v6
/* export function createUserRewards(): DictionaryValue<UserRewards> {
return {
serialize: (src: any, buidler: any) => {
buidler.storeUint(src.trackingIndex, 64);
buidler.storeUint(src.trackingAccured, 64);
},
parse: (src: Slice) => {
const trackingIndex = BigInt(src.loadUint(64));
const trackingAccured = BigInt(src.loadUint(64));
return { trackingIndex, trackingAccured };
},
};
}*/

export function createAssetData(): DictionaryValue<AssetData> {
return {
Expand All @@ -22,6 +37,10 @@ export function createAssetData(): DictionaryValue<AssetData> {
buidler.storeUint(src.totalBorrow, 64);
buidler.storeUint(src.lastAccural, 32);
buidler.storeUint(src.balance, 64);
/* Will be in v6
buidler.storeUint(src.trackingSupplyIndex, 64);
buidler.storeUint(src.trackingBorrowIndex, 64);
buidler.storeUint(src.lastTrackingAccural, 32); */
},
parse: (src: Slice) => {
const sRate = BigInt(src.loadInt(64));
Expand All @@ -30,8 +49,13 @@ export function createAssetData(): DictionaryValue<AssetData> {
const totalBorrow = BigInt(src.loadInt(64));
const lastAccural = BigInt(src.loadInt(32));
const balance = BigInt(src.loadInt(64));
return { sRate, bRate, totalSupply, totalBorrow, lastAccural, balance };
},
/* Will be in v6
const trackingSupplyIndex = BigInt(src.loadUint(64));
const trackingBorrowIndex = BigInt(src.loadUint(64));
const lastTrackingAccural = BigInt(src.loadUint(32));
return { sRate, bRate, totalSupply, totalBorrow, lastAccural, balance, trackingSupplyIndex, trackingBorrowIndex, lastTrackingAccural}; }, */
return { sRate, bRate, totalSupply, totalBorrow, lastAccural, balance}; },
};
}

Expand All @@ -51,7 +75,14 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
refBuild.storeUint(src.supplyRateSlopeHigh, 64);
refBuild.storeUint(src.targetUtilization, 64);
refBuild.storeUint(src.originationFee, 64);
refBuild.storeUint(src.dust, 64);
refBuild.storeUint(src.maxTotalSupply, 64);
refBuild.storeUint(src.reserveFactor, 16);
refBuild.storeUint(src.liquidationReserveFactor, 16);
/* Will be in v6
refBuild.storeUint(src.minPrincipalForRewards, 64);
refBuild.storeUint(src.baseTrackingSupplySpeed, 64);
refBuild.storeUint(src.baseTrackingBorrowSpeed, 64); */
builder.storeRef(refBuild.endCell());
},
parse: (src: Slice) => {
Expand All @@ -70,6 +101,12 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
const originationFee = ref.loadUintBig(64);
const dust = ref.loadUintBig(64);
const maxTotalSupply = ref.loadUintBig(64);
const reserveFactor = ref.loadUintBig(16);
const liquidationReserveFactor = ref.loadUintBig(16);
/* Will be in v6
const minPrincipalForRewards = ref.loadUintBig(64);
const baseTrackingSupplySpeed = ref.loadUintBig(64);
const baseTrackingBorrowSpeed = ref.loadUintBig(64); */

return {
oracle,
Expand All @@ -86,6 +123,12 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
originationFee,
dust,
maxTotalSupply,
reserveFactor,
liquidationReserveFactor,
/* Will be in v6
minPrincipalForRewards,
baseTrackingSupplySpeed,
baseTrackingBorrowSpeed */
};
},
};
Expand Down Expand Up @@ -162,6 +205,7 @@ export function parseUserLiteData(
assetsData: Dictionary<bigint, ExtendedAssetData>,
assetsConfig: Dictionary<bigint, AssetConfig>,
testnet: boolean = false,
applyDust: boolean = false
): UserLiteData {
const ASSETS_ID = testnet ? TESTNET_ASSETS_ID : MAINNET_ASSETS_ID;
const userSlice = Cell.fromBase64(userDataBOC).beginParse();
Expand All @@ -175,14 +219,40 @@ export function parseUserLiteData(
const trackingBorrowIndex = userSlice.loadUintBig(64);
const dutchAuctionStart = userSlice.loadUint(32);
const backupCell = loadMyRef(userSlice);
/* Will be in v6
let trackingSupplyIndex = 0n;
let trackingBorrowIndex = 0n;
let dutchAuctionStart = 0;
let backupCell = Cell.EMPTY;
let rewards = Dictionary.empty(Dictionary.Keys.BigUint(256), createUserRewards());
let backupCell1: Cell | null = null;
let backupCell2: Cell | null = null;
const bitsLeft = userSlice.remainingBits;
if (bitsLeft > 32) {
trackingSupplyIndex = userSlice.loadUintBig(64);
trackingBorrowIndex = userSlice.loadUintBig(64);
dutchAuctionStart = userSlice.loadUint(32);
backupCell = loadMyRef(userSlice);
} else {
rewards = userSlice.loadDict(Dictionary.Keys.BigUint(256), createUserRewards());
backupCell1 = userSlice.loadMaybeRef();
backupCell2 = userSlice.loadMaybeRef();
}
*/
userSlice.endParse();

const userBalances = Dictionary.empty<bigint, UserBalance>();

for (const [_, assetID] of Object.entries(ASSETS_ID)) {
const assetData = assetsData.get(assetID) as ExtendedAssetData;
const assetConfig = assetsConfig.get(assetID) as AssetConfig;
const balance = presentValue(assetData.sRate, assetData.bRate, principalsDict.get(assetID) || 0n);
let principals = principalsDict.get(assetID) || 0n;

if (applyDust && (principals > -assetConfig.dust && principals < assetConfig.dust)) { // abs(principals) < dust
principals = 0n;
principalsDict.set(assetID, 0n);
}
const balance = presentValue(assetData.sRate, assetData.bRate, principals);
userBalances.set(assetID, balance);
}

Expand All @@ -198,6 +268,10 @@ export function parseUserLiteData(
trackingBorrowIndex: trackingBorrowIndex,
dutchAuctionStart: dutchAuctionStart,
backupCell: backupCell,
/* Will be in v6
rewards: rewards,
backupCell1: backupCell1,
backupCell2: backupCell2, */
};
}

Expand All @@ -207,6 +281,7 @@ export function parseUserData(
assetsConfig: Dictionary<bigint, AssetConfig>,
prices: Dictionary<bigint, bigint>,
testnet: boolean = false,
applyDust: boolean = false
): UserData {
const ASSETS_ID = testnet ? TESTNET_ASSETS_ID : MAINNET_ASSETS_ID;
const withdrawalLimits = Dictionary.empty<bigint, bigint>();
Expand All @@ -217,7 +292,14 @@ export function parseUserData(
for (const [_, assetID] of Object.entries(ASSETS_ID)) {
const assetData = assetsData.get(assetID) as ExtendedAssetData;
const assetConfig = assetsConfig.get(assetID) as AssetConfig;
const balance = presentValue(assetData.sRate, assetData.bRate, userLiteData.principals.get(assetID) || 0n);
let principals = userLiteData.principals.get(assetID) || 0n;

if (applyDust && (principals > -assetConfig.dust && principals < assetConfig.dust )) { // abs(principals) < dust
principals = 0n;
userLiteData.principals.set(assetID, 0n);
}

const balance = presentValue(assetData.sRate, assetData.bRate, principals);
userLiteData.balances.set(assetID, balance);
}

Expand Down Expand Up @@ -255,12 +337,11 @@ export function parseUserData(
0n,
),
);
} else {
borrowLimits.set(
assetID,
bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(assetID)!, assetData.balance),
);
}
borrowLimits.set(
assetID,
bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(assetID)!, assetData.balance),
);
}

const limitUsed = borrowBalance + availableToBorrow;
Expand Down
6 changes: 3 additions & 3 deletions src/api/prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ type OutputData = {
};
};

export async function getPrices(): Promise<PriceData | undefined> {
export async function getPrices(endpoint: String = "api.stardust-mainnet.iotaledger.net"): Promise<PriceData | undefined> {
try {
let result = await fetch('https://api.stardust-mainnet.iotaledger.net/api/indexer/v1/outputs/nft/' + NFT_ID, {
let result = await fetch(`https://${endpoint}/api/indexer/v1/outputs/nft/${NFT_ID}`, {
headers: { accept: 'application/json' },
});
let outputId = (await result.json()) as NftData;

result = await fetch('https://api.stardust-mainnet.iotaledger.net/api/core/v2/outputs/' + outputId.items[0], {
result = await fetch(`https://${endpoint}/api/core/v2/outputs/${outputId.items[0]}`, {
headers: { accept: 'application/json' },
});

Expand Down
6 changes: 4 additions & 2 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Address, Cell, toNano } from '@ton/core';
import { sha256Hash } from './utils/sha256BigInt';

export const EVAA_MASTER_MAINNET = Address.parse('EQC8rUZqR_pWV1BylWUlPNBzyiTYVoBEmQkMIQDZXICfnuRr');
export const MAINNET_VERSION = 4;
export const MAINNET_VERSION = 5;
export const EVAA_MASTER_TESTNET = Address.parse('kQCj7qf3i2Cbf1GVtZCinla7lIvE7l3MBMsJMTfAja3BdoRP');
export const TESTNET_VERSION = 4;
export const TESTNET_VERSION = 5;

export const NFT_ID = '0xfb9874544d76ca49c5db9cc3e5121e4c018bc8a2fb2bfe8f2a38c5b9963492f5';

Expand Down Expand Up @@ -43,6 +43,8 @@ export const MASTER_CONSTANTS = {
FACTOR_SCALE: BigInt(1e12),
ASSET_COEFFICIENT_SCALE: 10000n,
ASSET_PRICE_SCALE: BigInt(1e8),
ASSET_RESERVE_FACTOR_SCALE: 10000n,
ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: 10000n,
};

export const LENDING_CODE = Cell.fromBoc(
Expand Down
15 changes: 15 additions & 0 deletions src/contracts/MasterContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export type SupplyBaseParameters = {
amount: bigint;
userAddress: Address;
assetID: bigint;
/* Will be in v6
amountToTransfer: bigint;
payload: Cell; */
};
/**
* Parameters for the TON supply message
Expand Down Expand Up @@ -92,6 +95,9 @@ export type WithdrawParameters = {
userAddress: Address;
includeUserCode: boolean;
priceData: Cell;
/* Will be in v6
amountToTransfer: bigint;
payload: Cell; */
};

/**
Expand Down Expand Up @@ -184,6 +190,9 @@ export class Evaa implements Contract {
.storeUint(OPCODES.SUPPLY, 32)
.storeInt(parameters.includeUserCode ? -1 : 0, 2)
.storeAddress(parameters.userAddress)
/* Will be in v6
.storeUint(parameters.amountToTransfer, 64)
.storeRef(parameters.payload) */
.endCell(),
)
.endCell();
Expand All @@ -194,6 +203,9 @@ export class Evaa implements Contract {
.storeInt(parameters.includeUserCode ? -1 : 0, 2)
.storeUint(parameters.amount, 64)
.storeAddress(parameters.userAddress)
/* Will be in v6
.storeUint(parameters.amountToTransfer, 64)
.storeRef(parameters.payload) */
.endCell();
}
}
Expand All @@ -210,6 +222,9 @@ export class Evaa implements Contract {
.storeUint(parameters.amount, 64)
.storeAddress(parameters.userAddress)
.storeInt(parameters.includeUserCode ? -1 : 0, 2)
/* Will be in v6
.storeUint(parameters.amountToTransfer, 64)
.storeRef(parameters.payload) */
.storeRef(parameters.priceData)
.endCell();
}
Expand Down
10 changes: 10 additions & 0 deletions src/types/Master.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ export type AssetConfig = {
originationFee: bigint;
dust: bigint;
maxTotalSupply: bigint;
reserveFactor: bigint;
liquidationReserveFactor: bigint;
/* Will be in v6
minPrincipalForRewards: bigint;
baseTrackingSupplySpeed: bigint;
baseTrackingBorrowSpeed: bigint; */
};

export type MasterConfig = {
Expand All @@ -44,6 +50,10 @@ export type AssetData = {
totalBorrow: bigint;
lastAccural: bigint;
balance: bigint;
/* Will be in v6
trackingSupplyIndex: bigint;
trackingBorrowIndex: bigint;
lastTrackingAccural: bigint; */
};

export type AssetInterest = {
Expand Down
9 changes: 9 additions & 0 deletions src/types/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export type UserLiteData = {
trackingBorrowIndex: bigint;
dutchAuctionStart: number;
backupCell: Cell;
/* Will be in v6
rewards: Dictionary<bigint, UserRewards>;
backupCell1: Cell | null;
backupCell2: Cell | null; */
};

export type UserDataActive = UserLiteData & {
Expand All @@ -64,3 +68,8 @@ export type UserDataInactive = {
};

export type UserData = UserDataActive | UserDataInactive;

export type UserRewards = {
trackingIndex: bigint;
trackingAccured: bigint;
};
Loading

0 comments on commit b964cde

Please sign in to comment.