@temporalabs/treasury 0.1.0
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/LICENSE +201 -0
- package/NOTICE +10 -0
- package/README.md +153 -0
- package/THIRD_PARTY_NOTICES.md +366 -0
- package/dist/abi/erc4626.d.ts +243 -0
- package/dist/abi/erc4626.js +146 -0
- package/dist/abi/erc4626.js.map +1 -0
- package/dist/build.d.ts +88 -0
- package/dist/build.js +124 -0
- package/dist/build.js.map +1 -0
- package/dist/client.d.ts +429 -0
- package/dist/client.js +248 -0
- package/dist/client.js.map +1 -0
- package/dist/config/earn.d.ts +47 -0
- package/dist/config/earn.js +46 -0
- package/dist/config/earn.js.map +1 -0
- package/dist/disclosures.d.ts +14 -0
- package/dist/disclosures.js +28 -0
- package/dist/disclosures.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/links.d.ts +21 -0
- package/dist/links.js +32 -0
- package/dist/links.js.map +1 -0
- package/dist/mcp/server.d.ts +33 -0
- package/dist/mcp/server.js +346 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp-server.mjs +56281 -0
- package/dist/position.d.ts +142 -0
- package/dist/position.js +354 -0
- package/dist/position.js.map +1 -0
- package/dist/preflight.d.ts +62 -0
- package/dist/preflight.js +165 -0
- package/dist/preflight.js.map +1 -0
- package/dist/quote.d.ts +55 -0
- package/dist/quote.js +83 -0
- package/dist/quote.js.map +1 -0
- package/dist/redact.d.ts +44 -0
- package/dist/redact.js +92 -0
- package/dist/redact.js.map +1 -0
- package/dist/registry-schema.d.ts +127 -0
- package/dist/registry-schema.js +124 -0
- package/dist/registry-schema.js.map +1 -0
- package/dist/registry.d.ts +26 -0
- package/dist/registry.js +62 -0
- package/dist/registry.js.map +1 -0
- package/dist/units.d.ts +8 -0
- package/dist/units.js +24 -0
- package/dist/units.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +14 -0
- package/dist/version.js.map +1 -0
- package/package.json +58 -0
- package/registry/vaults.json +68 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The depositor-facing ERC-4626 + ERC-20 surface, and nothing else — no admin, allocator or
|
|
3
|
+
* operator entry points, because the client never calls any. This fragment is the whole interface
|
|
4
|
+
* a depositor needs on a standard 4626 chassis (Morpho Vault V2, IPOR Fusion).
|
|
5
|
+
* Enzyme is NOT 4626 (`buyShares` via the comptroller) and is not covered here.
|
|
6
|
+
*/
|
|
7
|
+
export const erc4626Abi = [
|
|
8
|
+
// --- ERC-20 ---
|
|
9
|
+
{ type: "function", name: "name", stateMutability: "view", inputs: [], outputs: [{ type: "string" }] },
|
|
10
|
+
{ type: "function", name: "symbol", stateMutability: "view", inputs: [], outputs: [{ type: "string" }] },
|
|
11
|
+
{ type: "function", name: "decimals", stateMutability: "view", inputs: [], outputs: [{ type: "uint8" }] },
|
|
12
|
+
{ type: "function", name: "totalSupply", stateMutability: "view", inputs: [], outputs: [{ type: "uint256" }] },
|
|
13
|
+
{
|
|
14
|
+
type: "function",
|
|
15
|
+
name: "balanceOf",
|
|
16
|
+
stateMutability: "view",
|
|
17
|
+
inputs: [{ name: "account", type: "address" }],
|
|
18
|
+
outputs: [{ type: "uint256" }],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
type: "function",
|
|
22
|
+
name: "allowance",
|
|
23
|
+
stateMutability: "view",
|
|
24
|
+
inputs: [
|
|
25
|
+
{ name: "owner", type: "address" },
|
|
26
|
+
{ name: "spender", type: "address" },
|
|
27
|
+
],
|
|
28
|
+
outputs: [{ type: "uint256" }],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: "function",
|
|
32
|
+
name: "approve",
|
|
33
|
+
stateMutability: "nonpayable",
|
|
34
|
+
inputs: [
|
|
35
|
+
{ name: "spender", type: "address" },
|
|
36
|
+
// `value`, not `amount`: these names are now USER-VISIBLE as `UnsignedCall.args`, and an
|
|
37
|
+
// operator reads them next to a block explorer's own form, which is labelled from the
|
|
38
|
+
// verified contract's ABI. EIP-20 and OpenZeppelin's implementation both name this `value`.
|
|
39
|
+
// Encoding is unaffected — a parameter binds by position and type, never by name.
|
|
40
|
+
{ name: "value", type: "uint256" },
|
|
41
|
+
],
|
|
42
|
+
outputs: [{ type: "bool" }],
|
|
43
|
+
},
|
|
44
|
+
// --- ERC-4626 ---
|
|
45
|
+
{ type: "function", name: "asset", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
|
|
46
|
+
{ type: "function", name: "totalAssets", stateMutability: "view", inputs: [], outputs: [{ type: "uint256" }] },
|
|
47
|
+
{
|
|
48
|
+
type: "function",
|
|
49
|
+
name: "convertToAssets",
|
|
50
|
+
stateMutability: "view",
|
|
51
|
+
inputs: [{ name: "shares", type: "uint256" }],
|
|
52
|
+
outputs: [{ type: "uint256" }],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: "function",
|
|
56
|
+
name: "convertToShares",
|
|
57
|
+
stateMutability: "view",
|
|
58
|
+
inputs: [{ name: "assets", type: "uint256" }],
|
|
59
|
+
outputs: [{ type: "uint256" }],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: "function",
|
|
63
|
+
name: "previewDeposit",
|
|
64
|
+
stateMutability: "view",
|
|
65
|
+
inputs: [{ name: "assets", type: "uint256" }],
|
|
66
|
+
outputs: [{ type: "uint256" }],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: "function",
|
|
70
|
+
name: "previewRedeem",
|
|
71
|
+
stateMutability: "view",
|
|
72
|
+
inputs: [{ name: "shares", type: "uint256" }],
|
|
73
|
+
outputs: [{ type: "uint256" }],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: "function",
|
|
77
|
+
name: "maxDeposit",
|
|
78
|
+
stateMutability: "view",
|
|
79
|
+
inputs: [{ name: "receiver", type: "address" }],
|
|
80
|
+
outputs: [{ type: "uint256" }],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: "function",
|
|
84
|
+
name: "maxRedeem",
|
|
85
|
+
stateMutability: "view",
|
|
86
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
87
|
+
outputs: [{ type: "uint256" }],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
type: "function",
|
|
91
|
+
name: "deposit",
|
|
92
|
+
stateMutability: "nonpayable",
|
|
93
|
+
inputs: [
|
|
94
|
+
{ name: "assets", type: "uint256" },
|
|
95
|
+
{ name: "receiver", type: "address" },
|
|
96
|
+
],
|
|
97
|
+
outputs: [{ name: "shares", type: "uint256" }],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
type: "function",
|
|
101
|
+
name: "previewWithdraw",
|
|
102
|
+
stateMutability: "view",
|
|
103
|
+
inputs: [{ name: "assets", type: "uint256" }],
|
|
104
|
+
outputs: [{ type: "uint256" }],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: "function",
|
|
108
|
+
name: "maxWithdraw",
|
|
109
|
+
stateMutability: "view",
|
|
110
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
111
|
+
outputs: [{ type: "uint256" }],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: "function",
|
|
115
|
+
name: "withdraw",
|
|
116
|
+
stateMutability: "nonpayable",
|
|
117
|
+
inputs: [
|
|
118
|
+
{ name: "assets", type: "uint256" },
|
|
119
|
+
{ name: "receiver", type: "address" },
|
|
120
|
+
{ name: "owner", type: "address" },
|
|
121
|
+
],
|
|
122
|
+
outputs: [{ name: "shares", type: "uint256" }],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
type: "function",
|
|
126
|
+
name: "redeem",
|
|
127
|
+
stateMutability: "nonpayable",
|
|
128
|
+
inputs: [
|
|
129
|
+
{ name: "shares", type: "uint256" },
|
|
130
|
+
{ name: "receiver", type: "address" },
|
|
131
|
+
{ name: "owner", type: "address" },
|
|
132
|
+
],
|
|
133
|
+
outputs: [{ name: "assets", type: "uint256" }],
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
/**
|
|
137
|
+
* Revert selectors a depositor pre-flight must be able to name. Each was observed
|
|
138
|
+
* live on Base (2026-09-11, blocks 51154060–51154242), not taken from documentation.
|
|
139
|
+
*/
|
|
140
|
+
export const knownRevertSelectors = {
|
|
141
|
+
/** OpenZeppelin AccessManaged — IPOR Fusion PlasmaVault `deposit` restricted to a role (800 = WHITELIST). */
|
|
142
|
+
AccessManagedUnauthorized: "0x068ca9d8",
|
|
143
|
+
/** Morpho Vault V2 wrapper around the USDC pull failing on allowance — access is OPEN, the call reached the money. */
|
|
144
|
+
TransferFromReverted: "0xe65b7a77",
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=erc4626.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erc4626.js","sourceRoot":"","sources":["../../src/abi/erc4626.ts"],"names":[],"mappings":"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"}
|
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type Address, type Hex } from "viem";
|
|
2
|
+
import { type VaultEntry } from "./registry-schema.js";
|
|
3
|
+
/**
|
|
4
|
+
* An unsigned call. This is the only thing this package ever produces on the write side.
|
|
5
|
+
* Whoever holds the key decides whether to sign it — a wallet, an operator, a policy-engine
|
|
6
|
+
* signer, a token-bound account. The skill supplies intent; the consumer supplies verification.
|
|
7
|
+
*/
|
|
8
|
+
export interface UnsignedCall {
|
|
9
|
+
chainId: number;
|
|
10
|
+
to: Address;
|
|
11
|
+
data: Hex;
|
|
12
|
+
/**
|
|
13
|
+
* The same call `data` encodes, in the form a block explorer's "Write Contract" tab asks for:
|
|
14
|
+
* a full signature with parameter names, e.g. `approve(address spender, uint256 value)`.
|
|
15
|
+
* See `encodeCall` for why this cannot drift from `data`.
|
|
16
|
+
*/
|
|
17
|
+
function: string;
|
|
18
|
+
/**
|
|
19
|
+
* The arguments of `function`, by name, as strings — `{ spender: "0x…", value: "1000000" }`.
|
|
20
|
+
* Values are raw contract units (the same integers `data` carries), NOT human decimals, because
|
|
21
|
+
* that is what an explorer's form takes. `description` is the human-readable sentence.
|
|
22
|
+
*/
|
|
23
|
+
args: Record<string, string>;
|
|
24
|
+
value: "0x0";
|
|
25
|
+
/** What a human should read before anyone signs this. */
|
|
26
|
+
description: string;
|
|
27
|
+
/** Which step this is in a multi-call intent (approve → deposit). */
|
|
28
|
+
step: number;
|
|
29
|
+
of: number;
|
|
30
|
+
/**
|
|
31
|
+
* How to set the gas limit. Measured on Morpho Vault V2: deposit/redeem gas depends on the time
|
|
32
|
+
* elapsed since the vault's last interest accrual, so an estimate taken now under-counts the
|
|
33
|
+
* storage writes the mined block will do — the tx dies out-of-gas while every simulation
|
|
34
|
+
* succeeds. Buffer the estimate; do not sign an unbuffered one.
|
|
35
|
+
*/
|
|
36
|
+
gasAdvice: string;
|
|
37
|
+
/**
|
|
38
|
+
* A read the signer must see satisfied — THROUGH THE RPC IT WILL SEND THROUGH — before it
|
|
39
|
+
* estimates or sends this call. Present only where a step depends on an earlier step's state.
|
|
40
|
+
*
|
|
41
|
+
* Why this is a field and not a sentence: the provider answering `eth_estimateGas` can be
|
|
42
|
+
* a replica one block behind the one that served the previous step's receipt. Measured on both
|
|
43
|
+
* real Cash-Plus round trips (2026-09-13, blocks 51253xxx and 51266819→51266821): approve
|
|
44
|
+
* confirmed, deposit's estimate reverted "ERC20: transfer amount exceeds allowance", the
|
|
45
|
+
* allowance was on-chain. A signer that reads this precondition until it holds is
|
|
46
|
+
* deterministic; a signer that retries on a string match is guessing.
|
|
47
|
+
*/
|
|
48
|
+
precondition?: Precondition;
|
|
49
|
+
}
|
|
50
|
+
/** `read(contract).call(args) >= minimum` (raw units) on the sending RPC before this call goes out. */
|
|
51
|
+
export interface Precondition {
|
|
52
|
+
read: "allowance";
|
|
53
|
+
contract: Address;
|
|
54
|
+
owner: Address;
|
|
55
|
+
spender: Address;
|
|
56
|
+
/** Raw token units, as a decimal string — compare as integers, never as floats. */
|
|
57
|
+
minimum: string;
|
|
58
|
+
why: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* `approve(vault, assets)` on the asset token, then `deposit(assets, receiver)` on the vault.
|
|
62
|
+
* `account` is the depositor — the address that signs both calls and whose allowance step 2
|
|
63
|
+
* depends on; it is what the precondition names.
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildDeposit(vault: VaultEntry, args: {
|
|
66
|
+
assetsHuman: string;
|
|
67
|
+
receiver: Address;
|
|
68
|
+
account: Address;
|
|
69
|
+
}): UnsignedCall[];
|
|
70
|
+
/**
|
|
71
|
+
* USDC-denominated withdrawal — the caller never handles share amounts.
|
|
72
|
+
*
|
|
73
|
+
* - `{ assetsHuman }` → ERC-4626 `withdraw(assets, receiver, owner)`: the vault burns whatever
|
|
74
|
+
* shares that many assets cost at the time of inclusion.
|
|
75
|
+
* - `{ all: true, sharesExact }` → `redeem(shares, receiver, owner)` with the EXACT share balance
|
|
76
|
+
* the caller read from `earn_balance` (as a string, never through a float): the only way to
|
|
77
|
+
* empty an account without leaving dust or asking for more than is owned.
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildWithdraw(vault: VaultEntry, args: {
|
|
80
|
+
receiver: Address;
|
|
81
|
+
owner: Address;
|
|
82
|
+
} & ({
|
|
83
|
+
assetsHuman: string;
|
|
84
|
+
all?: false;
|
|
85
|
+
} | {
|
|
86
|
+
all: true;
|
|
87
|
+
sharesExact: string;
|
|
88
|
+
})): UnsignedCall[];
|
package/dist/build.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { encodeFunctionData, getAbiItem } from "viem";
|
|
2
|
+
import { erc4626Abi } from "./abi/erc4626.js";
|
|
3
|
+
import { erc4626Chassis } from "./registry-schema.js";
|
|
4
|
+
import { parseAmount, formatAmount } from "./units.js";
|
|
5
|
+
/**
|
|
6
|
+
* 🔴 ONE CALL SITE PRODUCES BOTH `data` AND ITS DECODING, FROM THE SAME ARGUMENT TUPLE.
|
|
7
|
+
*
|
|
8
|
+
* The obvious implementation of #11 is a second step that decodes the finished calldata back into
|
|
9
|
+
* names and values. That is two sources for one fact, and two sources drift: a decoder pointed at a
|
|
10
|
+
* stale ABI, or simply not re-run when an argument order changes, produces a signature and an
|
|
11
|
+
* argument list that disagree with the bytes an operator is about to sign — and the operator is
|
|
12
|
+
* using this field precisely BECAUSE they cannot read the bytes. Silent, and wrong in the one
|
|
13
|
+
* direction that matters.
|
|
14
|
+
*
|
|
15
|
+
* So there is no decode step. `data` is encoded from `args`, and the names are read off the same
|
|
16
|
+
* ABI entry `encodeFunctionData` resolves; the values ARE the tuple, stringified. The only way for
|
|
17
|
+
* the two to disagree is for viem to encode a different function than `getAbiItem` returns for the
|
|
18
|
+
* same name and ABI. (This is the same rule `linksFor` follows for a vault's links: derive from one
|
|
19
|
+
* row, never reconcile two sources that agree today.)
|
|
20
|
+
*/
|
|
21
|
+
function encodeCall(abi, functionName, args) {
|
|
22
|
+
const item = getAbiItem({ abi, name: functionName, args });
|
|
23
|
+
if (item === undefined || item.type !== "function") {
|
|
24
|
+
throw new Error(`${functionName} is not a function on this ABI; this client cannot build a call for it`);
|
|
25
|
+
}
|
|
26
|
+
// A names/values length mismatch would silently drop or misalign an argument in the map an
|
|
27
|
+
// operator types into a form. `encodeFunctionData` rejects the same mismatch, but it must be
|
|
28
|
+
// impossible for THIS map to be built from one, whichever of the two runs first.
|
|
29
|
+
if (item.inputs.length !== args.length) {
|
|
30
|
+
throw new Error(`${functionName} takes ${item.inputs.length} argument(s), got ${args.length}`);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
data: encodeFunctionData({ abi, functionName, args }),
|
|
34
|
+
function: `${functionName}(${item.inputs.map((i, n) => `${i.type} ${i.name || `arg${n}`}`).join(", ")})`,
|
|
35
|
+
args: Object.fromEntries(item.inputs.map((i, n) => [i.name || `arg${n}`, String(args[n])])),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const GAS_ADVICE = "Set gas limit = eth_estimateGas × 1.5. Measured: an unbuffered estimate ran out of gas on a Morpho Vault V2 redeem (310,505 gas) while simulation and prior-block re-simulation both succeeded — accrual work grows with elapsed time between estimate and inclusion.";
|
|
39
|
+
function assert4626(vault) {
|
|
40
|
+
if (!erc4626Chassis.has(vault.chassis)) {
|
|
41
|
+
throw new Error(`${vault.symbol} is on ${vault.chassis}, which has no ERC-4626 deposit/redeem path; this client does not build calls for it`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* `approve(vault, assets)` on the asset token, then `deposit(assets, receiver)` on the vault.
|
|
46
|
+
* `account` is the depositor — the address that signs both calls and whose allowance step 2
|
|
47
|
+
* depends on; it is what the precondition names.
|
|
48
|
+
*/
|
|
49
|
+
export function buildDeposit(vault, args) {
|
|
50
|
+
assert4626(vault);
|
|
51
|
+
const assets = parseAmount(args.assetsHuman, vault.asset.decimals, `deposit amount (${vault.asset.symbol})`);
|
|
52
|
+
const pretty = `${formatAmount(assets, vault.asset.decimals)} ${vault.asset.symbol}`;
|
|
53
|
+
return [
|
|
54
|
+
{
|
|
55
|
+
chainId: vault.chainId,
|
|
56
|
+
to: vault.asset.address,
|
|
57
|
+
...encodeCall(erc4626Abi, "approve", [vault.address, assets]),
|
|
58
|
+
value: "0x0",
|
|
59
|
+
description: `Approve ${vault.symbol} vault (${vault.address}) to pull ${pretty}`,
|
|
60
|
+
step: 1,
|
|
61
|
+
of: 2,
|
|
62
|
+
gasAdvice: GAS_ADVICE,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
chainId: vault.chainId,
|
|
66
|
+
to: vault.address,
|
|
67
|
+
...encodeCall(erc4626Abi, "deposit", [assets, args.receiver]),
|
|
68
|
+
value: "0x0",
|
|
69
|
+
description: `Deposit ${pretty} into ${vault.name}; shares minted to ${args.receiver}`,
|
|
70
|
+
step: 2,
|
|
71
|
+
of: 2,
|
|
72
|
+
gasAdvice: GAS_ADVICE,
|
|
73
|
+
precondition: {
|
|
74
|
+
read: "allowance",
|
|
75
|
+
contract: vault.asset.address,
|
|
76
|
+
owner: args.account,
|
|
77
|
+
spender: vault.address,
|
|
78
|
+
minimum: assets.toString(),
|
|
79
|
+
why: "Do not estimate or send this until allowance(owner, spender) >= minimum reads back on the RPC you will send through. The receipt for step 1 can come from a node ahead of the one that simulates step 2 (measured twice on real funds).",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* USDC-denominated withdrawal — the caller never handles share amounts.
|
|
86
|
+
*
|
|
87
|
+
* - `{ assetsHuman }` → ERC-4626 `withdraw(assets, receiver, owner)`: the vault burns whatever
|
|
88
|
+
* shares that many assets cost at the time of inclusion.
|
|
89
|
+
* - `{ all: true, sharesExact }` → `redeem(shares, receiver, owner)` with the EXACT share balance
|
|
90
|
+
* the caller read from `earn_balance` (as a string, never through a float): the only way to
|
|
91
|
+
* empty an account without leaving dust or asking for more than is owned.
|
|
92
|
+
*/
|
|
93
|
+
export function buildWithdraw(vault, args) {
|
|
94
|
+
assert4626(vault);
|
|
95
|
+
if (args.all) {
|
|
96
|
+
const shares = parseAmount(args.sharesExact, vault.shareDecimals, `share balance (${vault.symbol})`);
|
|
97
|
+
return [
|
|
98
|
+
{
|
|
99
|
+
chainId: vault.chainId,
|
|
100
|
+
to: vault.address,
|
|
101
|
+
...encodeCall(erc4626Abi, "redeem", [shares, args.receiver, args.owner]),
|
|
102
|
+
value: "0x0",
|
|
103
|
+
description: `Withdraw EVERYTHING from ${vault.name}: redeem ${formatAmount(shares, vault.shareDecimals)} ${vault.symbol} (the exact balance) for ${vault.asset.symbol}, paid to ${args.receiver}`,
|
|
104
|
+
step: 1,
|
|
105
|
+
of: 1,
|
|
106
|
+
gasAdvice: GAS_ADVICE,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
const assets = parseAmount(args.assetsHuman, vault.asset.decimals, `withdraw amount (${vault.asset.symbol})`);
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
chainId: vault.chainId,
|
|
114
|
+
to: vault.address,
|
|
115
|
+
...encodeCall(erc4626Abi, "withdraw", [assets, args.receiver, args.owner]),
|
|
116
|
+
value: "0x0",
|
|
117
|
+
description: `Withdraw ${formatAmount(assets, vault.asset.decimals)} ${vault.asset.symbol} from ${vault.name}, paid to ${args.receiver}; the vault burns the shares that costs at inclusion`,
|
|
118
|
+
step: 1,
|
|
119
|
+
of: 1,
|
|
120
|
+
gasAdvice: GAS_ADVICE,
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAsD,MAAM,MAAM,CAAC;AAC1G,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAmB,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA6DvD;;;;;;;;;;;;;;;GAeG;AACH,SAAS,UAAU,CACjB,GAAS,EACT,YAAoB,EACpB,IAAwB;IAExB,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAW,CAA4B,CAAC;IAC/F,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,wEAAwE,CAAC,CAAC;IAC3G,CAAC;IACD,2FAA2F;IAC3F,6FAA6F;IAC7F,iFAAiF;IACjF,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,UAAU,IAAI,CAAC,MAAM,CAAC,MAAM,qBAAqB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO;QACL,IAAI,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAW,CAAC;QAC9D,QAAQ,EAAE,GAAG,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACxG,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAC5F,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,GAAG,uQAAuQ,CAAC;AAE3R,SAAS,UAAU,CAAC,KAAiB;IACnC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,OAAO,sFAAsF,CAC7H,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAiB,EAAE,IAAkE;IAChH,UAAU,CAAC,KAAK,CAAC,CAAC;IAClB,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,mBAAmB,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7G,MAAM,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IACrF,OAAO;QACL;YACE,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;YACvB,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC7D,KAAK,EAAE,KAAK;YACZ,WAAW,EAAE,WAAW,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,OAAO,aAAa,MAAM,EAAE;YACjF,IAAI,EAAE,CAAC;YACP,EAAE,EAAE,CAAC;YACL,SAAS,EAAE,UAAU;SACtB;QACD;YACE,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,EAAE,EAAE,KAAK,CAAC,OAAO;YACjB,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7D,KAAK,EAAE,KAAK;YACZ,WAAW,EAAE,WAAW,MAAM,SAAS,KAAK,CAAC,IAAI,sBAAsB,IAAI,CAAC,QAAQ,EAAE;YACtF,IAAI,EAAE,CAAC;YACP,EAAE,EAAE,CAAC;YACL,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;gBAC7B,KAAK,EAAE,IAAI,CAAC,OAAO;gBACnB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE;gBAC1B,GAAG,EAAE,yOAAyO;aAC/O;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAiB,EACjB,IAAyH;IAEzH,UAAU,CAAC,KAAK,CAAC,CAAC;IAClB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,aAAa,EAAE,kBAAkB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACrG,OAAO;YACL;gBACE,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,EAAE,EAAE,KAAK,CAAC,OAAO;gBACjB,GAAG,UAAU,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACxE,KAAK,EAAE,KAAK;gBACZ,WAAW,EAAE,4BAA4B,KAAK,CAAC,IAAI,YAAY,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,MAAM,4BAA4B,KAAK,CAAC,KAAK,CAAC,MAAM,aAAa,IAAI,CAAC,QAAQ,EAAE;gBAClM,IAAI,EAAE,CAAC;gBACP,EAAE,EAAE,CAAC;gBACL,SAAS,EAAE,UAAU;aACtB;SACF,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,oBAAoB,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9G,OAAO;QACL;YACE,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,EAAE,EAAE,KAAK,CAAC,OAAO;YACjB,GAAG,UAAU,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,KAAK,EAAE,KAAK;YACZ,WAAW,EAAE,YAAY,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,IAAI,aAAa,IAAI,CAAC,QAAQ,sDAAsD;YAC5L,IAAI,EAAE,CAAC;YACP,EAAE,EAAE,CAAC;YACL,SAAS,EAAE,UAAU;SACtB;KACF,CAAC;AACJ,CAAC"}
|