@morpho-org/blue-sdk 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -6
- package/src/addresses.ts +261 -0
- package/src/chain/chain.constants.ts +235 -0
- package/src/chain/chain.test.ts +51 -0
- package/src/chain/chain.types.ts +42 -0
- package/src/chain/chain.utils.ts +44 -0
- package/src/constants.ts +18 -0
- package/src/errors.ts +75 -0
- package/src/ethers/ethers.test.ts +17 -0
- package/src/ethers/safeGetAddress.ts +4 -0
- package/src/ethers/safeParseUnits.ts +29 -0
- package/src/evm.ts +172 -0
- package/src/helpers/format/format.test.ts +340 -0
- package/src/helpers/format/format.ts +416 -0
- package/src/helpers/getChecksumedAddress.ts +15 -0
- package/{lib/helpers/isZeroAddressOrUnset.d.ts → src/helpers/isZeroAddressOrUnset.ts} +7 -1
- package/src/helpers/locale.ts +108 -0
- package/src/holding/Holding.ts +109 -0
- package/src/market/Market.ts +479 -0
- package/src/market/MarketConfig.ts +108 -0
- package/src/market/MarketUtils.test.ts +25 -0
- package/src/market/MarketUtils.ts +467 -0
- package/src/maths/AdaptiveCurveIrmLib.ts +143 -0
- package/src/maths/MathLib.ts +208 -0
- package/src/maths/MathUtils.ts +31 -0
- package/src/maths/SharesMath.ts +40 -0
- package/src/notifications.ts +167 -0
- package/src/position/Position.ts +251 -0
- package/src/signatures/index.ts +18 -0
- package/src/signatures/manager.ts +50 -0
- package/src/signatures/permit.ts +126 -0
- package/src/signatures/permit2.ts +120 -0
- package/src/signatures/types.ts +18 -0
- package/src/signatures/utils.ts +83 -0
- package/src/tests/mocks/markets.ts +110 -0
- package/src/token/ERC20Metadata.ts +124 -0
- package/src/token/Token.ts +83 -0
- package/src/token/TokenNamespace.ts +76 -0
- package/src/token/WrappedToken.ts +142 -0
- package/src/types.ts +37 -0
- package/src/user/User.ts +32 -0
- package/src/user/user.types.ts +23 -0
- package/src/vault/Vault.ts +370 -0
- package/src/vault/VaultAllocation.ts +58 -0
- package/src/vault/VaultConfig.ts +55 -0
- package/src/vault/VaultUtils.ts +47 -0
- package/lib/addresses.d.ts +0 -168
- package/lib/addresses.js +0 -169
- package/lib/chain/chain.constants.d.ts +0 -3
- package/lib/chain/chain.constants.js +0 -232
- package/lib/chain/chain.types.d.ts +0 -20
- package/lib/chain/chain.types.js +0 -30
- package/lib/chain/chain.utils.d.ts +0 -14
- package/lib/chain/chain.utils.js +0 -30
- package/lib/chain/index.js +0 -18
- package/lib/constants.d.ts +0 -8
- package/lib/constants.js +0 -13
- package/lib/errors.d.ts +0 -37
- package/lib/errors.js +0 -71
- package/lib/ethers/index.js +0 -18
- package/lib/ethers/safeGetAddress.d.ts +0 -1
- package/lib/ethers/safeGetAddress.js +0 -6
- package/lib/ethers/safeParseUnits.d.ts +0 -2
- package/lib/ethers/safeParseUnits.js +0 -25
- package/lib/evm.d.ts +0 -36
- package/lib/evm.js +0 -113
- package/lib/helpers/format/format.d.ts +0 -98
- package/lib/helpers/format/format.js +0 -301
- package/lib/helpers/format/index.js +0 -17
- package/lib/helpers/getChecksumedAddress.d.ts +0 -7
- package/lib/helpers/getChecksumedAddress.js +0 -17
- package/lib/helpers/index.js +0 -20
- package/lib/helpers/isZeroAddressOrUnset.js +0 -14
- package/lib/helpers/locale.d.ts +0 -36
- package/lib/helpers/locale.js +0 -86
- package/lib/holding/Holding.d.ts +0 -60
- package/lib/holding/Holding.js +0 -31
- package/lib/holding/index.js +0 -17
- package/lib/index.d.ts +0 -33
- package/lib/index.js +0 -62
- package/lib/market/Market.d.ts +0 -159
- package/lib/market/Market.js +0 -240
- package/lib/market/MarketConfig.d.ts +0 -44
- package/lib/market/MarketConfig.js +0 -56
- package/lib/market/MarketUtils.d.ts +0 -165
- package/lib/market/MarketUtils.js +0 -182
- package/lib/market/index.js +0 -19
- package/lib/maths/AdaptiveCurveIrmLib.d.ts +0 -37
- package/lib/maths/AdaptiveCurveIrmLib.js +0 -116
- package/lib/maths/MathLib.d.ts +0 -94
- package/lib/maths/MathLib.js +0 -153
- package/lib/maths/MathUtils.d.ts +0 -15
- package/lib/maths/MathUtils.js +0 -33
- package/lib/maths/SharesMath.d.ts +0 -12
- package/lib/maths/SharesMath.js +0 -22
- package/lib/maths/index.js +0 -20
- package/lib/notifications.d.ts +0 -98
- package/lib/notifications.js +0 -52
- package/lib/position/Position.d.ts +0 -118
- package/lib/position/Position.js +0 -145
- package/lib/position/index.js +0 -17
- package/lib/signatures/index.d.ts +0 -12
- package/lib/signatures/index.js +0 -39
- package/lib/signatures/manager.d.ts +0 -10
- package/lib/signatures/manager.js +0 -37
- package/lib/signatures/permit.d.ts +0 -21
- package/lib/signatures/permit.js +0 -101
- package/lib/signatures/permit2.d.ts +0 -20
- package/lib/signatures/permit2.js +0 -91
- package/lib/signatures/types.d.ts +0 -13
- package/lib/signatures/types.js +0 -2
- package/lib/signatures/utils.d.ts +0 -6
- package/lib/signatures/utils.js +0 -44
- package/lib/tests/mocks/markets.d.ts +0 -17
- package/lib/tests/mocks/markets.js +0 -108
- package/lib/token/ERC20Metadata.d.ts +0 -249
- package/lib/token/ERC20Metadata.js +0 -81
- package/lib/token/Token.d.ts +0 -45
- package/lib/token/Token.js +0 -39
- package/lib/token/TokenNamespace.d.ts +0 -18
- package/lib/token/TokenNamespace.js +0 -55
- package/lib/token/WrappedToken.d.ts +0 -42
- package/lib/token/WrappedToken.js +0 -87
- package/lib/token/index.js +0 -18
- package/lib/types.d.ts +0 -29
- package/lib/types.js +0 -23
- package/lib/user/User.d.ts +0 -20
- package/lib/user/User.js +0 -11
- package/lib/user/index.js +0 -18
- package/lib/user/user.types.d.ts +0 -18
- package/lib/user/user.types.js +0 -2
- package/lib/vault/Vault.d.ts +0 -167
- package/lib/vault/Vault.js +0 -156
- package/lib/vault/VaultAllocation.d.ts +0 -38
- package/lib/vault/VaultAllocation.js +0 -18
- package/lib/vault/VaultConfig.d.ts +0 -23
- package/lib/vault/VaultConfig.js +0 -26
- package/lib/vault/VaultUtils.d.ts +0 -17
- package/lib/vault/VaultUtils.js +0 -17
- package/lib/vault/index.js +0 -20
- /package/{lib/chain/index.d.ts → src/chain/index.ts} +0 -0
- /package/{lib/ethers/index.d.ts → src/ethers/index.ts} +0 -0
- /package/{lib/helpers/format/index.d.ts → src/helpers/format/index.ts} +0 -0
- /package/{lib/helpers/index.d.ts → src/helpers/index.ts} +0 -0
- /package/{lib/holding/index.d.ts → src/holding/index.ts} +0 -0
- /package/{lib/market/index.d.ts → src/market/index.ts} +0 -0
- /package/{lib/maths/index.d.ts → src/maths/index.ts} +0 -0
- /package/{lib/position/index.d.ts → src/position/index.ts} +0 -0
- /package/{lib/token/index.d.ts → src/token/index.ts} +0 -0
- /package/{lib/user/index.d.ts → src/user/index.ts} +0 -0
- /package/{lib/vault/index.d.ts → src/vault/index.ts} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getChainAddresses } from "../addresses";
|
|
2
|
+
import { ChainId } from "../chain";
|
|
3
|
+
|
|
4
|
+
import { SignatureMessage } from "./types";
|
|
5
|
+
import { getMessage } from "./utils";
|
|
6
|
+
|
|
7
|
+
export interface ManagerApprovalSignatureArgs {
|
|
8
|
+
authorizer: string;
|
|
9
|
+
authorized: string;
|
|
10
|
+
isAuthorized: boolean;
|
|
11
|
+
nonce: bigint;
|
|
12
|
+
deadline: bigint;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const getManagerApprovalMessage = (
|
|
16
|
+
args: ManagerApprovalSignatureArgs,
|
|
17
|
+
chainId: ChainId
|
|
18
|
+
): SignatureMessage => {
|
|
19
|
+
const domain = {
|
|
20
|
+
chainId: chainId.toString(),
|
|
21
|
+
verifyingContract: getChainAddresses(chainId).morpho,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const types = {
|
|
25
|
+
Authorization: [
|
|
26
|
+
{
|
|
27
|
+
name: "authorizer",
|
|
28
|
+
type: "address",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "authorized",
|
|
32
|
+
type: "address",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "isAuthorized",
|
|
36
|
+
type: "bool",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "nonce",
|
|
40
|
+
type: "uint256",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "deadline",
|
|
44
|
+
type: "uint256",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return getMessage(domain, types, args);
|
|
50
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { addresses, getChainAddresses } from "../addresses";
|
|
2
|
+
import { ChainId } from "../chain";
|
|
3
|
+
import { Token } from "../token";
|
|
4
|
+
import { Address } from "../types";
|
|
5
|
+
|
|
6
|
+
import { SignatureMessage } from "./types";
|
|
7
|
+
import { getMessage } from "./utils";
|
|
8
|
+
|
|
9
|
+
export interface PermitArgs {
|
|
10
|
+
erc20: Token;
|
|
11
|
+
owner: Address;
|
|
12
|
+
spender: Address;
|
|
13
|
+
allowance: bigint;
|
|
14
|
+
nonce: bigint;
|
|
15
|
+
deadline: bigint;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Permit signature for ERC20 tokens, following EIP-2612.
|
|
20
|
+
* Docs: https://eips.ethereum.org/EIPS/eip-2612
|
|
21
|
+
*/
|
|
22
|
+
export const getPermitMessage = (
|
|
23
|
+
{ deadline, owner, nonce, spender, erc20, allowance }: PermitArgs,
|
|
24
|
+
chainId: ChainId
|
|
25
|
+
): SignatureMessage => {
|
|
26
|
+
const { usdc, dai } = getChainAddresses(chainId);
|
|
27
|
+
|
|
28
|
+
const domain = {
|
|
29
|
+
name: erc20.name,
|
|
30
|
+
version: erc20.address === usdc ? "2" : "1",
|
|
31
|
+
chainId: chainId.toString(),
|
|
32
|
+
verifyingContract: erc20.address,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (erc20.address === dai)
|
|
36
|
+
return getMessage(
|
|
37
|
+
domain,
|
|
38
|
+
{
|
|
39
|
+
Permit: [
|
|
40
|
+
{
|
|
41
|
+
name: "holder",
|
|
42
|
+
type: "address",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "spender",
|
|
46
|
+
type: "address",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "nonce",
|
|
50
|
+
type: "uint256",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "expiry",
|
|
54
|
+
type: "uint256",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "allowed",
|
|
58
|
+
type: "bool",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
holder: owner,
|
|
64
|
+
spender,
|
|
65
|
+
allowed: allowance > 0n,
|
|
66
|
+
nonce,
|
|
67
|
+
expiry: deadline,
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const types = {
|
|
72
|
+
Permit: [
|
|
73
|
+
{
|
|
74
|
+
name: "owner",
|
|
75
|
+
type: "address",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "spender",
|
|
79
|
+
type: "address",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "value",
|
|
83
|
+
type: "uint256",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "nonce",
|
|
87
|
+
type: "uint256",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "deadline",
|
|
91
|
+
type: "uint256",
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
const value = {
|
|
96
|
+
owner,
|
|
97
|
+
spender,
|
|
98
|
+
value: allowance,
|
|
99
|
+
nonce,
|
|
100
|
+
deadline,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return getMessage(domain, types, value);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const WITH_SIMPLE_PERMIT: {
|
|
107
|
+
[id in ChainId]: (Address | undefined)[];
|
|
108
|
+
} = {
|
|
109
|
+
[ChainId.EthMainnet]: [
|
|
110
|
+
addresses[ChainId.EthMainnet].wbIB01,
|
|
111
|
+
addresses[ChainId.EthMainnet].wbC3M,
|
|
112
|
+
addresses[ChainId.EthMainnet].wstEth,
|
|
113
|
+
addresses[ChainId.EthMainnet].sDai,
|
|
114
|
+
addresses[ChainId.EthMainnet].osEth,
|
|
115
|
+
addresses[ChainId.EthMainnet].usdc,
|
|
116
|
+
addresses[ChainId.EthMainnet].dai,
|
|
117
|
+
],
|
|
118
|
+
[ChainId.EthGoerliTestnet]: [
|
|
119
|
+
"0x0aCd15Fb54034492c392596B56ED415bD07e70d7", // Fake DAI
|
|
120
|
+
"0xD8134205b0328F5676aaeFb3B2a0DC15f4029d8C", // Real sDAI
|
|
121
|
+
],
|
|
122
|
+
[ChainId.BaseMainnet]: [addresses[ChainId.BaseMainnet].usdc],
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const hasSimplePermit = (chainId: ChainId, address: Address) =>
|
|
126
|
+
WITH_SIMPLE_PERMIT[chainId]?.includes(address);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { getChainAddresses } from "../addresses";
|
|
2
|
+
import { ChainId } from "../chain";
|
|
3
|
+
import { MathLib } from "../maths";
|
|
4
|
+
import { Address } from "../types";
|
|
5
|
+
|
|
6
|
+
import { SignatureMessage } from "./types";
|
|
7
|
+
import { getMessage } from "./utils";
|
|
8
|
+
|
|
9
|
+
export interface Permit2Args {
|
|
10
|
+
erc20: Address;
|
|
11
|
+
allowance: bigint;
|
|
12
|
+
nonce: bigint;
|
|
13
|
+
deadline: bigint;
|
|
14
|
+
spender: Address;
|
|
15
|
+
expiration?: bigint;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Permit2TransferFromArgs {
|
|
19
|
+
erc20: Address;
|
|
20
|
+
allowance: bigint;
|
|
21
|
+
spender: Address;
|
|
22
|
+
nonce: bigint;
|
|
23
|
+
deadline: bigint;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const getPermit2TransferFromMessage = (
|
|
27
|
+
args: Permit2TransferFromArgs,
|
|
28
|
+
chainId: ChainId
|
|
29
|
+
) => {
|
|
30
|
+
const domain = {
|
|
31
|
+
name: "Permit2",
|
|
32
|
+
chainId: chainId.toString(),
|
|
33
|
+
verifyingContract: getChainAddresses(chainId).permit2,
|
|
34
|
+
};
|
|
35
|
+
const types = {
|
|
36
|
+
PermitTransferFrom: [
|
|
37
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
38
|
+
{ name: "spender", type: "address" },
|
|
39
|
+
{ name: "nonce", type: "uint256" },
|
|
40
|
+
{ name: "deadline", type: "uint256" },
|
|
41
|
+
],
|
|
42
|
+
TokenPermissions: [
|
|
43
|
+
{ name: "token", type: "address" },
|
|
44
|
+
{ name: "amount", type: "uint256" },
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
const value = {
|
|
48
|
+
permitted: {
|
|
49
|
+
token: args.erc20,
|
|
50
|
+
amount: MathLib.min(args.allowance, MathLib.MAX_UINT_160),
|
|
51
|
+
},
|
|
52
|
+
spender: args.spender,
|
|
53
|
+
nonce: args.nonce,
|
|
54
|
+
deadline: args.deadline,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return getMessage(domain, types, value);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const getPermit2Message = (
|
|
61
|
+
args: Permit2Args,
|
|
62
|
+
chainId: ChainId
|
|
63
|
+
): SignatureMessage => {
|
|
64
|
+
const domain = {
|
|
65
|
+
name: "Permit2",
|
|
66
|
+
chainId: chainId.toString(),
|
|
67
|
+
verifyingContract: getChainAddresses(chainId).permit2,
|
|
68
|
+
};
|
|
69
|
+
const types = {
|
|
70
|
+
PermitSingle: [
|
|
71
|
+
{
|
|
72
|
+
name: "details",
|
|
73
|
+
type: "PermitDetails",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "spender",
|
|
77
|
+
type: "address",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "sigDeadline",
|
|
81
|
+
type: "uint256",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
PermitDetails: [
|
|
85
|
+
{
|
|
86
|
+
name: "token",
|
|
87
|
+
type: "address",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "amount",
|
|
91
|
+
type: "uint160",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "expiration",
|
|
95
|
+
type: "uint48",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "nonce",
|
|
99
|
+
type: "uint48",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
const value = {
|
|
104
|
+
details: {
|
|
105
|
+
token: args.erc20,
|
|
106
|
+
amount: MathLib.min(args.allowance, MathLib.MAX_UINT_160),
|
|
107
|
+
// Use an unlimited expiration because it most
|
|
108
|
+
// closely mimics how a standard approval works.
|
|
109
|
+
expiration: MathLib.min(
|
|
110
|
+
args.expiration ?? MathLib.MAX_UINT_48,
|
|
111
|
+
MathLib.MAX_UINT_48
|
|
112
|
+
),
|
|
113
|
+
nonce: args.nonce,
|
|
114
|
+
},
|
|
115
|
+
spender: args.spender,
|
|
116
|
+
sigDeadline: args.deadline,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return getMessage(domain, types, value);
|
|
120
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TypedDataDomain } from "ethers";
|
|
2
|
+
|
|
3
|
+
export interface SignatureData {
|
|
4
|
+
domain: TypedDataDomain;
|
|
5
|
+
types: Record<
|
|
6
|
+
string,
|
|
7
|
+
{
|
|
8
|
+
name: string;
|
|
9
|
+
type: string;
|
|
10
|
+
}[]
|
|
11
|
+
>;
|
|
12
|
+
value: object;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SignatureMessage {
|
|
16
|
+
hash: string;
|
|
17
|
+
data: SignatureData;
|
|
18
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Signature,
|
|
3
|
+
Signer,
|
|
4
|
+
TypedDataDomain,
|
|
5
|
+
TypedDataEncoder,
|
|
6
|
+
TypedDataField,
|
|
7
|
+
ZeroAddress,
|
|
8
|
+
recoverAddress,
|
|
9
|
+
} from "ethers";
|
|
10
|
+
|
|
11
|
+
import { InvalidSignatureError } from "../errors";
|
|
12
|
+
import { Address } from "../types";
|
|
13
|
+
|
|
14
|
+
import { SignatureMessage } from "./types";
|
|
15
|
+
|
|
16
|
+
export async function safeSignTypedData(
|
|
17
|
+
signer: Signer,
|
|
18
|
+
domain: TypedDataDomain,
|
|
19
|
+
types: Record<string, TypedDataField[]>,
|
|
20
|
+
value: Record<string, any>
|
|
21
|
+
) {
|
|
22
|
+
const populated = await TypedDataEncoder.resolveNames(
|
|
23
|
+
domain,
|
|
24
|
+
types,
|
|
25
|
+
value,
|
|
26
|
+
(name: string) => {
|
|
27
|
+
return signer.resolveName(name) as Promise<string>;
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
// Fix the chainId parsing issue
|
|
32
|
+
// Tracking of https://github.com/ethers-io/ethers.js/issues/4649
|
|
33
|
+
const initialPayload = TypedDataEncoder.getPayload(
|
|
34
|
+
populated.domain,
|
|
35
|
+
types,
|
|
36
|
+
populated.value
|
|
37
|
+
);
|
|
38
|
+
const provider = signer.provider;
|
|
39
|
+
const unsafeChainId = Number(initialPayload.domain.chainId);
|
|
40
|
+
|
|
41
|
+
if (provider && "send" in provider && Number.isSafeInteger(unsafeChainId)) {
|
|
42
|
+
const correctedPayload = {
|
|
43
|
+
...initialPayload,
|
|
44
|
+
domain: {
|
|
45
|
+
...initialPayload.domain,
|
|
46
|
+
chainId: unsafeChainId, // that is safe now
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
return Signature.from(
|
|
50
|
+
// @ts-ignore if send is defined in the provider, it accepts raw RPC call args
|
|
51
|
+
await signer.provider!.send("eth_signTypedData_v4", [
|
|
52
|
+
// Doing the same thing that inside of the signTypedData function.
|
|
53
|
+
await signer.getAddress().then((r) => r.toLowerCase()),
|
|
54
|
+
JSON.stringify(correctedPayload),
|
|
55
|
+
])
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return Signature.from(
|
|
60
|
+
await signer.signTypedData(populated.domain, types, populated.value)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function verifySignature(
|
|
65
|
+
signature: Signature,
|
|
66
|
+
hash: string,
|
|
67
|
+
signerAddress: Address
|
|
68
|
+
) {
|
|
69
|
+
const recoveredAddress = recoverAddress(hash, signature);
|
|
70
|
+
|
|
71
|
+
if (recoveredAddress === ZeroAddress || recoveredAddress !== signerAddress)
|
|
72
|
+
throw new InvalidSignatureError(hash, signerAddress, recoveredAddress);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function getMessage(
|
|
76
|
+
domain: TypedDataDomain,
|
|
77
|
+
types: Record<string, TypedDataField[]>,
|
|
78
|
+
value: Record<string, any>
|
|
79
|
+
): SignatureMessage {
|
|
80
|
+
const hash = TypedDataEncoder.hash(domain, types, value);
|
|
81
|
+
|
|
82
|
+
return { data: { domain, types, value }, hash };
|
|
83
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { ZeroAddress, parseUnits } from "ethers";
|
|
2
|
+
|
|
3
|
+
import { MarketConfig } from "../../market";
|
|
4
|
+
|
|
5
|
+
export const MAINNET_MARKETS = {
|
|
6
|
+
eth_wstEth: new MarketConfig({
|
|
7
|
+
loanToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
8
|
+
collateralToken: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
|
|
9
|
+
oracle: "0x2a01EB9496094dA03c4E364Def50f5aD1280AD72",
|
|
10
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
11
|
+
lltv: parseUnits("0.945"),
|
|
12
|
+
}),
|
|
13
|
+
eth_rEth: new MarketConfig({
|
|
14
|
+
loanToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
15
|
+
collateralToken: "0xae78736Cd615f374D3085123A210448E74Fc6393",
|
|
16
|
+
oracle: "0x1b4A3F92e5Fffd1d35A98751c9FE4472483579bB",
|
|
17
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
18
|
+
lltv: parseUnits("0.945"),
|
|
19
|
+
}),
|
|
20
|
+
usdt_wbtc: new MarketConfig({
|
|
21
|
+
loanToken: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
22
|
+
collateralToken: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
|
|
23
|
+
oracle: "0x008bF4B1cDA0cc9f0e882E0697f036667652E1ef",
|
|
24
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
25
|
+
lltv: parseUnits("0.86"),
|
|
26
|
+
}),
|
|
27
|
+
usdt_wstEth: new MarketConfig({
|
|
28
|
+
loanToken: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
29
|
+
collateralToken: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
|
|
30
|
+
oracle: "0x95DB30fAb9A3754e42423000DF27732CB2396992",
|
|
31
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
32
|
+
lltv: parseUnits("0.86"),
|
|
33
|
+
}),
|
|
34
|
+
|
|
35
|
+
usdc_wbtc: new MarketConfig({
|
|
36
|
+
// USDC(wBTC, 86%, Chainlink, AdaptiveCurve)
|
|
37
|
+
loanToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
38
|
+
collateralToken: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
|
|
39
|
+
oracle: "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
40
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
41
|
+
lltv: parseUnits("0.86"),
|
|
42
|
+
}),
|
|
43
|
+
usdc_wstEth: new MarketConfig({
|
|
44
|
+
// USDC(wstETH, 86%, Chainlink, AdaptiveCurve)
|
|
45
|
+
loanToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
46
|
+
collateralToken: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
|
|
47
|
+
oracle: "0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
|
|
48
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
49
|
+
lltv: parseUnits("0.86"),
|
|
50
|
+
}),
|
|
51
|
+
usdc_sDai: new MarketConfig({
|
|
52
|
+
// USDC(wstETH, 86%, Chainlink, AdaptiveCurve)
|
|
53
|
+
loanToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
54
|
+
collateralToken: "0x83F20F44975D03b1b09e64809B757c47f942BEeA",
|
|
55
|
+
oracle: "0x6CAFE228eC0B0bC2D076577d56D35Fe704318f6d",
|
|
56
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
57
|
+
lltv: parseUnits("0.965"),
|
|
58
|
+
}),
|
|
59
|
+
idle_usdc: new MarketConfig({
|
|
60
|
+
loanToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
61
|
+
collateralToken: ZeroAddress,
|
|
62
|
+
oracle: ZeroAddress,
|
|
63
|
+
irm: ZeroAddress,
|
|
64
|
+
lltv: 0n,
|
|
65
|
+
}),
|
|
66
|
+
|
|
67
|
+
crvUsd_stkcvxcrvUSDTWBTCWETH: new MarketConfig({
|
|
68
|
+
collateralToken: "0xb0Ce26C88e4e7DCa51968b6047f44646f5064278",
|
|
69
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
70
|
+
lltv: parseUnits("0.86"),
|
|
71
|
+
loanToken: "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",
|
|
72
|
+
oracle: "0x077Af6c2D4A75D4145d141F9e9421864C3940CB3",
|
|
73
|
+
}),
|
|
74
|
+
crvUsd_stkcvxcrvUSDCWBTCWETH: new MarketConfig({
|
|
75
|
+
collateralToken: "0x0ea1a65A2c255f24Ee8D81eA6AaC54Decd9d269e",
|
|
76
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
77
|
+
lltv: parseUnits("0.86"),
|
|
78
|
+
loanToken: "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",
|
|
79
|
+
oracle: "0xd2F7C3B2fC97cC7b6AfDd76D163394680EFc35b9",
|
|
80
|
+
}),
|
|
81
|
+
crvUsd_stkcvxcrvCRVUSDTBTCWSTETH: new MarketConfig({
|
|
82
|
+
collateralToken: "0x3ce8Ec9f3d89aD0A2DdbCC3FDB8991BD241Fc82E",
|
|
83
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
84
|
+
lltv: parseUnits("0.86"),
|
|
85
|
+
loanToken: "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",
|
|
86
|
+
oracle: "0xa9f7900476F43C45Ebf56cEa669B9c960C176112",
|
|
87
|
+
}),
|
|
88
|
+
crvUsd_stkcvxTryLSD: new MarketConfig({
|
|
89
|
+
collateralToken: "0x6BA072F0d22806F2C52e9792AF47f2D59103BEBE",
|
|
90
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
91
|
+
lltv: parseUnits("0.86"),
|
|
92
|
+
loanToken: "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",
|
|
93
|
+
oracle: "0x18B0d7311a97c5377445C80c768ab5201Bb27B5a",
|
|
94
|
+
}),
|
|
95
|
+
crvUsd_stkcvxcrvUSDETHCRV: new MarketConfig({
|
|
96
|
+
collateralToken: "0xAc904BAfBb5FB04Deb2b6198FdCEedE75a78Ce5a",
|
|
97
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
98
|
+
lltv: parseUnits("0.86"),
|
|
99
|
+
loanToken: "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",
|
|
100
|
+
oracle: "0xad7e157815df05029125B568E39d5402550d60bb",
|
|
101
|
+
}),
|
|
102
|
+
|
|
103
|
+
usda_re7Eth: new MarketConfig({
|
|
104
|
+
collateralToken: "0x78Fc2c2eD1A4cDb5402365934aE5648aDAd094d0",
|
|
105
|
+
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC",
|
|
106
|
+
lltv: parseUnits("0.86"),
|
|
107
|
+
loanToken: "0x0000206329b97DB379d5E1Bf586BbDB969C63274",
|
|
108
|
+
oracle: "0x76052A2A28fDCB8124f4686C63C68355b142de3B",
|
|
109
|
+
}),
|
|
110
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Contract,
|
|
3
|
+
ContractRunner,
|
|
4
|
+
Interface,
|
|
5
|
+
decodeBytes32String,
|
|
6
|
+
isHexString,
|
|
7
|
+
} from "ethers";
|
|
8
|
+
import { ERC20__factory } from "ethers-types";
|
|
9
|
+
import { ERC20, ERC20Interface } from "ethers-types/dist/token/ERC20/ERC20";
|
|
10
|
+
|
|
11
|
+
import addresses from "@morpho-org/blue-sdk/src/addresses";
|
|
12
|
+
|
|
13
|
+
import { ChainId } from "../chain";
|
|
14
|
+
|
|
15
|
+
export const isBytes32ERC20Metadata = (address: string, chainId: ChainId) => {
|
|
16
|
+
switch (chainId) {
|
|
17
|
+
case ChainId.EthMainnet:
|
|
18
|
+
return [addresses[ChainId.EthMainnet].mkr].includes(address);
|
|
19
|
+
default:
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const decodeString = (bytes32OrStr: string) => {
|
|
25
|
+
if (isHexString(bytes32OrStr, 32)) return decodeBytes32String(bytes32OrStr);
|
|
26
|
+
|
|
27
|
+
return bytes32OrStr;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const _bytes32ERC20Abi = [
|
|
31
|
+
...ERC20__factory.abi.filter(
|
|
32
|
+
(fragment) =>
|
|
33
|
+
!("name" in fragment) ||
|
|
34
|
+
(fragment.name !== "name" && fragment.name !== "symbol")
|
|
35
|
+
),
|
|
36
|
+
{
|
|
37
|
+
inputs: [],
|
|
38
|
+
name: "symbol",
|
|
39
|
+
outputs: [
|
|
40
|
+
{
|
|
41
|
+
name: "symbol",
|
|
42
|
+
type: "bytes32",
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
stateMutability: "view",
|
|
46
|
+
type: "function",
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
{
|
|
50
|
+
inputs: [],
|
|
51
|
+
name: "name",
|
|
52
|
+
outputs: [
|
|
53
|
+
{
|
|
54
|
+
name: "name",
|
|
55
|
+
type: "bytes32",
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
stateMutability: "view",
|
|
59
|
+
type: "function",
|
|
60
|
+
},
|
|
61
|
+
] as const;
|
|
62
|
+
|
|
63
|
+
export class Bytes32ERC20__factory {
|
|
64
|
+
static readonly abi = _bytes32ERC20Abi;
|
|
65
|
+
|
|
66
|
+
static createInterface() {
|
|
67
|
+
return new Interface(_bytes32ERC20Abi) as ERC20Interface;
|
|
68
|
+
}
|
|
69
|
+
static connect(address: string, runner?: ContractRunner | null) {
|
|
70
|
+
const erc20 = new Contract(
|
|
71
|
+
address,
|
|
72
|
+
_bytes32ERC20Abi,
|
|
73
|
+
runner
|
|
74
|
+
) as unknown as ERC20;
|
|
75
|
+
|
|
76
|
+
const name = erc20.name.bind(erc20);
|
|
77
|
+
erc20.name = Object.assign(
|
|
78
|
+
(...args: Parameters<typeof name>) => name(...args).then(decodeString),
|
|
79
|
+
name
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const symbol = erc20.symbol.bind(erc20);
|
|
83
|
+
erc20.symbol = Object.assign(
|
|
84
|
+
(...args: Parameters<typeof symbol>) =>
|
|
85
|
+
symbol(...args).then(decodeString),
|
|
86
|
+
symbol
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
return erc20;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export class ERC20Metadata__factory {
|
|
94
|
+
static connect(
|
|
95
|
+
address: string,
|
|
96
|
+
chainId: ChainId,
|
|
97
|
+
runner?: ContractRunner | null
|
|
98
|
+
) {
|
|
99
|
+
if (isBytes32ERC20Metadata(address, chainId))
|
|
100
|
+
return Bytes32ERC20__factory.connect(address, runner);
|
|
101
|
+
|
|
102
|
+
const erc20 = ERC20__factory.connect(address, runner);
|
|
103
|
+
|
|
104
|
+
const name = erc20.name.bind(erc20);
|
|
105
|
+
erc20.name = Object.assign(
|
|
106
|
+
(...args: Parameters<typeof name>) =>
|
|
107
|
+
name(...args).catch(() =>
|
|
108
|
+
Bytes32ERC20__factory.connect(address, runner).name(...args)
|
|
109
|
+
),
|
|
110
|
+
name
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const symbol = erc20.symbol.bind(erc20);
|
|
114
|
+
erc20.symbol = Object.assign(
|
|
115
|
+
(...args: Parameters<typeof symbol>) =>
|
|
116
|
+
symbol(...args).catch(() =>
|
|
117
|
+
Bytes32ERC20__factory.connect(address, runner).symbol(...args)
|
|
118
|
+
),
|
|
119
|
+
symbol
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
return erc20;
|
|
123
|
+
}
|
|
124
|
+
}
|