@0xmonaco/contracts 1.0.50 → 1.0.53
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/dist/abis/sweeper.d.ts +212 -8
- package/dist/abis/sweeper.js +265 -8
- package/dist/abis/sweeperFactory.d.ts +752 -5
- package/dist/abis/sweeperFactory.js +1027 -65
- package/dist/index.d.ts +980 -29
- package/dist/sweeper.d.ts +31 -14
- package/dist/sweeper.js +22 -16
- package/package.json +1 -1
package/dist/sweeper.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Off-chain derivation of Monaco sweeper deposit addresses.
|
|
3
3
|
*
|
|
4
|
-
* A sweeper is an EIP-1167 clone deployed by `SweeperFactory` at a
|
|
5
|
-
* address determined by the (clientId, user, deposit target) triple it
|
|
6
|
-
* bound to. The address can therefore be shown to a user — and funded —
|
|
7
|
-
* any contract exists there, without an RPC round trip.
|
|
4
|
+
* A sweeper is an EIP-1167-style clone deployed by `SweeperFactory` at a
|
|
5
|
+
* CREATE2 address determined by the (clientId, user, deposit target) triple it
|
|
6
|
+
* is bound to. The address can therefore be shown to a user — and funded —
|
|
7
|
+
* before any contract exists there, without an RPC round trip. The clone
|
|
8
|
+
* delegates to the factory's fixed *forwarder* (which looks up the current
|
|
9
|
+
* sweeper implementation per call), so implementation upgrades never move
|
|
10
|
+
* addresses — and the forwarder, not the implementation, is the derivation
|
|
11
|
+
* input. The factory is deployed at the same address on every supported
|
|
12
|
+
* chain, which makes the derived deposit address chain-invariant too.
|
|
8
13
|
*
|
|
9
14
|
* The client id is the application's identifier as used for rollup deposits
|
|
10
15
|
* (the string `sdk.login` takes). It is hashed **byte-for-byte**: two
|
|
@@ -53,10 +58,15 @@ export type DepositTarget = "spot" | "margin";
|
|
|
53
58
|
*/
|
|
54
59
|
export declare function encodeDepositApplicationData(clientId: string, target: DepositTarget): string;
|
|
55
60
|
export interface SweeperAddressInput {
|
|
56
|
-
/** Address of the deployed `SweeperFactory
|
|
61
|
+
/** Address of the deployed `SweeperFactory` (the same on every chain). */
|
|
57
62
|
factory: string;
|
|
58
|
-
/**
|
|
59
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Address of the factory's `SweeperForwarder` — the fixed delegation
|
|
65
|
+
* target every clone points at (`factory.forwarder()`). NOT the sweeper
|
|
66
|
+
* implementation: the implementation is upgradeable and deliberately
|
|
67
|
+
* outside the derivation.
|
|
68
|
+
*/
|
|
69
|
+
forwarder: string;
|
|
60
70
|
/**
|
|
61
71
|
* The application's client id, exactly as registered — hashed
|
|
62
72
|
* byte-for-byte, so any other spelling derives a different address.
|
|
@@ -82,14 +92,21 @@ export interface SweeperAddressInput {
|
|
|
82
92
|
* @throws If any address is malformed, the client id is empty, or the deposit
|
|
83
93
|
* target is not exactly `"spot"` or `"margin"`.
|
|
84
94
|
*/
|
|
85
|
-
export declare function predictSweeperAddress({ factory,
|
|
95
|
+
export declare function predictSweeperAddress({ factory, forwarder, clientId, user, depositTarget }: SweeperAddressInput): Hex;
|
|
86
96
|
/**
|
|
87
|
-
* The clone's immutable args:
|
|
88
|
-
* (
|
|
89
|
-
* deposit parameter
|
|
97
|
+
* The clone's immutable args:
|
|
98
|
+
* `abi.encode(address user, string clientId, address hubToken)` (the contract
|
|
99
|
+
* calls the string `applicationId`, matching the rollup's deposit parameter
|
|
100
|
+
* name).
|
|
101
|
+
*
|
|
102
|
+
* The hub token is zero for every user-facing deposit address; a non-zero
|
|
103
|
+
* value derives the factory's internal hub-side "unswap receiver" for that
|
|
104
|
+
* token, which the sweeping service uses when bridged funds must be swapped
|
|
105
|
+
* back before depositing.
|
|
90
106
|
*
|
|
91
|
-
* Length-prefixed rather than packed, so no
|
|
107
|
+
* Length-prefixed rather than packed, so no triple can be confused with
|
|
108
|
+
* another.
|
|
92
109
|
*/
|
|
93
|
-
export declare function sweeperImmutableArgs(user: string, clientId: string): Hex;
|
|
110
|
+
export declare function sweeperImmutableArgs(user: string, clientId: string, hubToken?: string): Hex;
|
|
94
111
|
/** The clone's creation code, mirroring OpenZeppelin `Clones._cloneCodeWithImmutableArgs`. */
|
|
95
|
-
export declare function sweeperCloneInitCode(
|
|
112
|
+
export declare function sweeperCloneInitCode(forwarder: string, args: Hex): Hex;
|
package/dist/sweeper.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { keccak_256 } from "@noble/hashes/sha3";
|
|
2
2
|
const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
3
|
-
/** EIP-1167-with-immutable-args runtime prefix, up to the
|
|
3
|
+
/** EIP-1167-with-immutable-args runtime prefix, up to the delegation target. */
|
|
4
4
|
const CLONE_RUNTIME_PREFIX = "3d81600a3d39f3363d3d373d3d3d363d73";
|
|
5
|
-
/** EIP-1167-with-immutable-args runtime suffix, after the
|
|
5
|
+
/** EIP-1167-with-immutable-args runtime suffix, after the delegation target. */
|
|
6
6
|
const CLONE_RUNTIME_SUFFIX = "5af43d82803e903d91602b57fd5bf3";
|
|
7
7
|
/** Byte length of the clone runtime code, excluding the immutable args. */
|
|
8
8
|
const CLONE_RUNTIME_LENGTH = 45;
|
|
@@ -55,38 +55,44 @@ function assertDepositTarget(value) {
|
|
|
55
55
|
* @throws If any address is malformed, the client id is empty, or the deposit
|
|
56
56
|
* target is not exactly `"spot"` or `"margin"`.
|
|
57
57
|
*/
|
|
58
|
-
export function predictSweeperAddress({ factory,
|
|
58
|
+
export function predictSweeperAddress({ factory, forwarder, clientId, user, depositTarget = "spot" }) {
|
|
59
59
|
const factoryAddress = assertAddress(factory, "factory");
|
|
60
|
-
const
|
|
60
|
+
const forwarderAddress = assertAddress(forwarder, "forwarder");
|
|
61
61
|
const userAddress = assertNonZeroUser(assertAddress(user, "user"));
|
|
62
62
|
assertClientId(clientId);
|
|
63
63
|
// The bound string is the encoded application data, not the bare client id:
|
|
64
64
|
// it is what the clone carries and what a sweep puts on-chain.
|
|
65
65
|
const boundClientId = encodeDepositApplicationData(clientId, depositTarget);
|
|
66
|
-
const initCode = sweeperCloneInitCode(
|
|
66
|
+
const initCode = sweeperCloneInitCode(forwarderAddress, sweeperImmutableArgs(userAddress, boundClientId));
|
|
67
67
|
const preimage = concatBytes(Uint8Array.of(0xff), hexToBytes(factoryAddress), SALT, keccak_256(hexToBytes(initCode)));
|
|
68
68
|
return toChecksumAddress(`0x${bytesToHex(keccak_256(preimage).slice(12))}`);
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
|
-
* The clone's immutable args:
|
|
72
|
-
* (
|
|
73
|
-
* deposit parameter
|
|
71
|
+
* The clone's immutable args:
|
|
72
|
+
* `abi.encode(address user, string clientId, address hubToken)` (the contract
|
|
73
|
+
* calls the string `applicationId`, matching the rollup's deposit parameter
|
|
74
|
+
* name).
|
|
74
75
|
*
|
|
75
|
-
*
|
|
76
|
+
* The hub token is zero for every user-facing deposit address; a non-zero
|
|
77
|
+
* value derives the factory's internal hub-side "unswap receiver" for that
|
|
78
|
+
* token, which the sweeping service uses when bridged funds must be swapped
|
|
79
|
+
* back before depositing.
|
|
80
|
+
*
|
|
81
|
+
* Length-prefixed rather than packed, so no triple can be confused with
|
|
82
|
+
* another.
|
|
76
83
|
*/
|
|
77
|
-
export function sweeperImmutableArgs(user, clientId) {
|
|
84
|
+
export function sweeperImmutableArgs(user, clientId, hubToken = "0x0000000000000000000000000000000000000000") {
|
|
78
85
|
const userAddress = assertNonZeroUser(assertAddress(user, "user"));
|
|
86
|
+
const hubTokenAddress = assertAddress(hubToken, "hubToken");
|
|
79
87
|
assertClientId(clientId);
|
|
80
|
-
return `0x${word(userAddress.slice(2))}${word("
|
|
88
|
+
return `0x${word(userAddress.slice(2))}${word("60")}${word(hubTokenAddress.slice(2))}${encodeStringTail(clientId)}`;
|
|
81
89
|
}
|
|
82
90
|
/** The clone's creation code, mirroring OpenZeppelin `Clones._cloneCodeWithImmutableArgs`. */
|
|
83
|
-
export function sweeperCloneInitCode(
|
|
84
|
-
const
|
|
91
|
+
export function sweeperCloneInitCode(forwarder, args) {
|
|
92
|
+
const forwarderAddress = assertAddress(forwarder, "forwarder");
|
|
85
93
|
const argsHex = args.slice(2);
|
|
86
94
|
const runtimeLength = argsHex.length / 2 + CLONE_RUNTIME_LENGTH;
|
|
87
|
-
return `0x61${runtimeLength.toString(16).padStart(4, "0")}${CLONE_RUNTIME_PREFIX}${
|
|
88
|
-
.slice(2)
|
|
89
|
-
.toLowerCase()}${CLONE_RUNTIME_SUFFIX}${argsHex}`;
|
|
95
|
+
return `0x61${runtimeLength.toString(16).padStart(4, "0")}${CLONE_RUNTIME_PREFIX}${forwarderAddress.slice(2).toLowerCase()}${CLONE_RUNTIME_SUFFIX}${argsHex}`;
|
|
90
96
|
}
|
|
91
97
|
function assertAddress(value, label) {
|
|
92
98
|
if (!ADDRESS.test(value)) {
|