Skip to content

Commit

Permalink
Merge branch 'next' of github.com:morpho-org/sdks into next
Browse files Browse the repository at this point in the history
  • Loading branch information
Rubilmax committed Oct 22, 2024
2 parents f021fd4 + fa12005 commit 39a2c08
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 77 deletions.
16 changes: 7 additions & 9 deletions packages/blue-api-sdk/src/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
MarketParams,
MathLib,
Position,
TokenWithPrice,
Token,
VaultConfig,
VaultMarketAllocation,
VaultMarketConfig,
Expand Down Expand Up @@ -160,17 +160,15 @@ export class BlueSdkConverter {
return price;
}

public getTokenWithPrice(
public getToken(
dto: PartialBlueApiToken,
ethPriceUsd?: BlueApiToken["priceUsd"],
) {
return new TokenWithPrice(
{
...dto,
address: this.options.parseAddress(dto.address),
},
this.getPriceUsd(dto, ethPriceUsd),
);
return new Token({
...dto,
address: this.options.parseAddress(dto.address),
price: this.getPriceUsd(dto, ethPriceUsd),
});
}

public getMarketParams(dto: PartialBlueApiMarketParams) {
Expand Down
10 changes: 5 additions & 5 deletions packages/blue-sdk-ethers/src/fetch/Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,16 @@ export async function fetchToken(
const erc20 = ERC20Metadata__factory.connect(address, chainId, runner);

const [decimals, symbol, name] = await Promise.all([
erc20.decimals(overrides),
erc20.symbol(overrides),
erc20.name(overrides),
erc20.decimals(overrides).catch(() => undefined),
erc20.symbol(overrides).catch(() => undefined),
erc20.name(overrides).catch(() => undefined),
]);

const token = {
address,
decimals: Number.parseInt(decimals.toString()),
symbol,
name,
symbol,
decimals,
};

const { wstEth, stEth } = getChainAddresses(chainId);
Expand Down
11 changes: 10 additions & 1 deletion packages/blue-sdk-ethers/test/e2e/Token.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ExchangeRateWrappedToken,
addresses,
} from "@morpho-org/blue-sdk";
import { randomAddress } from "@morpho-org/test";
import { Token } from "../../src/augment/Token.js";

const { mkr, usdc, stEth, wstEth } = addresses[ChainId.EthMainnet];
Expand Down Expand Up @@ -41,7 +42,7 @@ describe("augment/Token", () => {
expect(value).toStrictEqual(expectedData);
});

test("Should fetch MKR token data", async ({ wallet }) => {
test("should fetch MKR token data", async ({ wallet }) => {
const expectedData = new Token({
address: mkr,
decimals: 18,
Expand All @@ -53,4 +54,12 @@ describe("augment/Token", () => {

expect(value).toStrictEqual(expectedData);
});

test("should fetch invalid ERC20", async ({ wallet }) => {
const expectedData = new Token({ address: randomAddress() });

const value = await Token.fetch(expectedData.address, wallet);

expect(value).toStrictEqual(expectedData);
});
});
18 changes: 15 additions & 3 deletions packages/blue-sdk-viem/contracts/GetToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,28 @@ import {IWstEth} from "./interfaces/IWstEth.sol";

struct TokenResponse {
uint256 decimals;
bool hasSymbol;
string symbol;
bool hasName;
string name;
uint256 stEthPerWstEth;
}

contract GetToken {
function query(IERC20 token, bool isWstEth) external view returns (TokenResponse memory res) {
res.decimals = token.decimals();
res.symbol = token.symbol();
res.name = token.name();
try token.name() returns (string memory name) {
res.hasName = true;
res.name = name;
} catch {}

try token.symbol() returns (string memory symbol) {
res.hasSymbol = true;
res.symbol = symbol;
} catch {}

try token.decimals() returns (uint8 decimals) {
res.decimals = decimals;
} catch {}

if (isWstEth) res.stEthPerWstEth = IWstEth(address(token)).stEthPerToken();
}
Expand Down
16 changes: 10 additions & 6 deletions packages/blue-sdk-viem/src/fetch/Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export async function fetchToken(
return new ConstantWrappedToken(
{ ...token, address },
unwrapToken,
Number(token.decimals),
token.decimals,
);

return new Token({ ...token, address });
Expand All @@ -79,7 +79,7 @@ export async function fetchToken(
address,
abi: erc20Abi,
functionName: "decimals",
}),
}).catch(() => undefined),
readContract(client, {
...parameters,
address,
Expand All @@ -91,7 +91,9 @@ export async function fetchToken(
address,
abi: erc20Abi_bytes32,
functionName: "symbol",
}).then(decodeBytes32String),
})
.then(decodeBytes32String)
.catch(() => undefined),
),
readContract(client, {
...parameters,
Expand All @@ -104,15 +106,17 @@ export async function fetchToken(
address,
abi: erc20Abi_bytes32,
functionName: "name",
}).then(decodeBytes32String),
})
.then(decodeBytes32String)
.catch(() => undefined),
),
]);

const token = {
address,
decimals: Number.parseInt(decimals.toString()),
symbol,
name,
symbol,
decimals,
};

switch (address) {
Expand Down
4 changes: 3 additions & 1 deletion packages/blue-sdk-viem/src/queries/GetToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export const abi = [
name: "decimals",
type: "uint256",
},
{ internalType: "bool", name: "hasSymbol", type: "bool" },
{ internalType: "string", name: "symbol", type: "string" },
{ internalType: "bool", name: "hasName", type: "bool" },
{ internalType: "string", name: "name", type: "string" },
{
internalType: "uint256",
Expand All @@ -36,4 +38,4 @@ export const abi = [
] as const;

export const code =
"0x60808060405234601557610340908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c63287861f914610025575f80fd5b346101ad5760403660031901126101ad576004356001600160a01b03811691908290036101ad5760243580151581036101ad576080820182811067ffffffffffffffff82111761023d576040525f8252602082019260608452604083016060815260608401925f845260405163313ce56760e01b8152602081600481875afa80156101b9575f90610200575b60ff168652506040516395d89b4160e01b81525f81600481875afa9081156101b9575f916101e6575b5086526040516306fdde0360e01b81525f81600481875afa9081156101b9575f916101c4575b508252610150575b610145915061013260405195869560208752516020870152516080604087015260a0860190610251565b9051848203601f19016060860152610251565b905160808301520390f35b6020600492604051938480926301afd7c160e11b82525afa80156101b9575f90610181575b61014592508352610108565b506020823d6020116101b1575b8161019b60209383610275565b810103126101ad576101459151610175565b5f80fd5b3d915061018e565b6040513d5f823e3d90fd5b6101e091503d805f833e6101d88183610275565b810190610297565b5f610100565b6101fa91503d805f833e6101d88183610275565b5f6100da565b506020813d602011610235575b8161021a60209383610275565b810103126101ad575160ff811681036101ad5760ff906100b1565b3d915061020d565b634e487b7160e01b5f52604160045260245ffd5b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90601f8019910116810190811067ffffffffffffffff82111761023d57604052565b6020818303126101ad5780519067ffffffffffffffff82116101ad570181601f820112156101ad5780519067ffffffffffffffff821161023d57604051926102e9601f8401601f191660200185610275565b828452602083830101116101ad57815f9260208093018386015e830101529056fea26469706673582212204029d875a2a9b244354fa7f1fc88d7b3d1ed680b6f90febd3e2794ee5f5e0dc064736f6c634300081b0033";
"0x60808060405234601557610381908161001a8239f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c63287861f914610025575f80fd5b346101c65760403660031901126101c6576004356001600160a01b03811691908290036101c65760243580151581036101c65760c0820182811067ffffffffffffffff82111761027e576040525f825260208201925f845260408301906060825260608401905f825260808501906060825260a08601945f86526040516306fdde0360e01b81525f81600481865afa5f9181610262575b50610256575b506040516395d89b4160e01b81525f81600481865afa5f9181610232575b50610226575b5060405163313ce56760e01b8152602081600481865afa5f91816101e8575b506101dd575b50610169575b5061014361015e936040519788976020895251602089015251151560408801525160c0606088015260e0870190610292565b91511515608086015251848203601f190160a0860152610292565b905160c08301520390f35b6020600491604051928380926301afd7c160e11b82525afa9081156101d2575f9161019a575b508452610143610111565b90506020813d6020116101ca575b816101b5602093836102b6565b810103126101c6575161015e61018f565b5f80fd5b3d91506101a8565b6040513d5f823e3d90fd5b60ff1687525f61010b565b9091506020813d60201161021e575b81610204602093836102b6565b810103126101c6575160ff811681036101c657905f610105565b3d91506101f7565b6001895285525f6100e6565b61024f9192503d805f833e61024781836102b6565b8101906102d8565b905f6100e0565b6001855283525f6100c2565b6102779192503d805f833e61024781836102b6565b905f6100bc565b634e487b7160e01b5f52604160045260245ffd5b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90601f8019910116810190811067ffffffffffffffff82111761027e57604052565b6020818303126101c65780519067ffffffffffffffff82116101c6570181601f820112156101c65780519067ffffffffffffffff821161027e576040519261032a601f8401601f1916602001856102b6565b828452602083830101116101c657815f9260208093018386015e830101529056fea2646970667358221220dff7800207ff93ada53a101a16f58240d78a80116545865cc793f9dbeb97fd7764736f6c634300081b0033";
4 changes: 2 additions & 2 deletions packages/blue-sdk-viem/src/signatures/permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import type { TypedDataDefinition } from "viem";

export interface PermitArgs {
name: string;
name?: string;
address: Address;
owner: Address;
spender: Address;
Expand Down Expand Up @@ -36,7 +36,7 @@ export const getPermitTypedData = (
const { usdc } = getChainAddresses(chainId);

const domain = {
name: name,
name,
version: address === usdc ? "2" : "1",
chainId,
verifyingContract: address,
Expand Down
11 changes: 10 additions & 1 deletion packages/blue-sdk-viem/test/Token.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ExchangeRateWrappedToken,
addresses,
} from "@morpho-org/blue-sdk";
import { randomAddress } from "@morpho-org/test";
import { Token } from "../src/augment/Token.js";

const { mkr, usdc, stEth, wstEth } = addresses[ChainId.EthMainnet];
Expand Down Expand Up @@ -41,7 +42,7 @@ describe("augment/Token", () => {
expect(value).toStrictEqual(expectedData);
});

test("Should fetch MKR token data", async ({ client }) => {
test("should fetch MKR token data", async ({ client }) => {
const expectedData = new Token({
address: mkr,
decimals: 18,
Expand All @@ -53,4 +54,12 @@ describe("augment/Token", () => {

expect(value).toStrictEqual(expectedData);
});

test("should fetch invalid ERC20", async ({ client }) => {
const expectedData = new Token({ address: randomAddress() });

const value = await Token.fetch(expectedData.address, client);

expect(value).toStrictEqual(expectedData);
});
});
2 changes: 1 addition & 1 deletion packages/blue-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"test": "vitest"
},
"dependencies": {
"keccak256": "^1.0.6"
"@noble/hashes": "^1.5.0"
},
"peerDependencies": {
"@morpho-org/morpho-ts": "workspace:^"
Expand Down
30 changes: 18 additions & 12 deletions packages/blue-sdk/src/market/MarketUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import keccak256 from "keccak256";

import { keccak_256 } from "@noble/hashes/sha3";
import { bytesToHex, hexToBytes } from "@noble/hashes/utils";
import {
LIQUIDATION_CURSOR,
MAX_LIQUIDATION_INCENTIVE_FACTOR,
Expand All @@ -8,7 +8,6 @@ import {
} from "../constants.js";
import { MathLib, type RoundingDirection, SharesMath } from "../math/index.js";
import type { BigIntish, MarketId } from "../types.js";

import type { InputMarketParams } from "./MarketParams.js";

/**
Expand All @@ -20,15 +19,22 @@ export namespace MarketUtils {
* @param market The market params.
*/
export function getMarketId(market: InputMarketParams) {
return `0x${keccak256(
`0x${
market.loanToken.substring(2).toLowerCase().padStart(64, "0") +
market.collateralToken.substring(2).toLowerCase().padStart(64, "0") +
market.oracle.substring(2).padStart(64, "0") +
market.irm.substring(2).toLowerCase().padStart(64, "0") +
BigInt(market.lltv).toString(16).padStart(64, "0")
}`,
).toString("hex")}` as MarketId;
return `0x${bytesToHex(
keccak_256(
hexToBytes(
`${
market.loanToken.substring(2).toLowerCase().padStart(64, "0") +
market.collateralToken
.substring(2)
.toLowerCase()
.padStart(64, "0") +
market.oracle.substring(2).padStart(64, "0") +
market.irm.substring(2).toLowerCase().padStart(64, "0") +
BigInt(market.lltv).toString(16).padStart(64, "0")
}`,
),
),
)}` as MarketId;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/blue-sdk/src/token/ConstantWrappedToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class ConstantWrappedToken extends WrappedToken {
constructor(
token: InputToken,
underlying: Address,
underlyingDecimals: BigIntish = 18n,
underlyingDecimals: BigIntish = 0,
) {
super(token, underlying);

Expand Down
39 changes: 18 additions & 21 deletions packages/blue-sdk/src/token/Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import type { Address, BigIntish } from "../types.js";

export interface InputToken {
address: Address;
decimals: BigIntish;
symbol: string;
name?: string;
symbol?: string;
decimals?: BigIntish;
price?: BigIntish;
}

export class Token implements InputToken {
Expand All @@ -23,46 +24,41 @@ export class Token implements InputToken {
public readonly address: Address;

/**
* The token's number of decimals.
* The token's name.
*/
public readonly decimals: number;
public readonly name?: string;

/**
* The token's symbol.
*/
public readonly symbol: string;
public readonly symbol?: string;

/**
* The name of the token (defaults to the symbol).
* The token's number of decimals. Defaults to 0.
*/
public readonly name: string;

constructor({ address, decimals, symbol, name }: InputToken) {
this.address = address;
this.decimals = Number(decimals);
this.symbol = symbol;
this.name = name ?? symbol;
}
}
public readonly decimals: number;

export class TokenWithPrice extends Token {
/**
* Price of the token in USD (scaled by WAD).
*/
public price?: bigint;

constructor(token: InputToken, price?: bigint) {
super(token);
constructor({ address, name, symbol, decimals = 0, price }: InputToken) {
this.address = address;
this.name = name;
this.symbol = symbol;
this.decimals = Number(decimals);

this.price = price;
if (price != null) this.price = BigInt(price);
}

/**
* Quotes an amount in USD (scaled by WAD) in this token.
* Returns `undefined` iff the token's price is undefined.
* @param amount The amount of USD to quote.
*/
fromUsd(amount: bigint, rounding: RoundingDirection = "Down") {
if (this.price == null) return null;
if (this.price == null) return;

return MathLib.mulDiv(
amount,
Expand All @@ -74,10 +70,11 @@ export class TokenWithPrice extends Token {

/**
* Quotes an amount of tokens in USD (scaled by WAD).
* Returns `undefined` iff the token's price is undefined.
* @param amount The amount of tokens to quote.
*/
toUsd(amount: bigint, rounding: RoundingDirection = "Down") {
if (this.price == null) return null;
if (this.price == null) return;

return MathLib.mulDiv(
amount,
Expand Down
10 changes: 10 additions & 0 deletions packages/blue-sdk/src/vault/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ export interface InputVault extends InputVaultConfig {
}

export class Vault extends VaultToken implements InputVault {
/**
* The vault's share token's name.
*/
public declare readonly name: string;

/**
* The vault's share token's symbol.
*/
public declare readonly symbol: string;

/**
* The MetaMorpho vault's owner address.
*/
Expand Down
Loading

0 comments on commit 39a2c08

Please sign in to comment.