From fcf62cbbba4a8c22d4b752589d40386b430b54de Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Mon, 6 Jul 2026 15:25:04 +0100 Subject: [PATCH 01/22] Better separation of concerns and abstractions --- ccip-sdk/src/cct/errors.ts | 67 +++++++++++++++ ccip-sdk/src/cct/evm/index.test.ts | 6 +- ccip-sdk/src/cct/evm/index.ts | 25 +++--- ccip-sdk/src/cct/evm/operation.ts | 36 ++++++++ ccip-sdk/src/cct/evm/operations/set-pool.ts | 84 ------------------- ccip-sdk/src/cct/evm/submit.test.ts | 27 +++--- ccip-sdk/src/cct/evm/submit.ts | 52 +++++------- .../evm/token-admin/operations/set-pool.ts | 45 ++++++++++ ccip-sdk/src/cct/evm/validate.test.ts | 30 ------- ccip-sdk/src/cct/evm/validate.ts | 6 +- ccip-sdk/src/cct/operation.ts | 26 ++++++ ccip-sdk/src/cct/token-manager.ts | 14 ++-- ccip-sdk/src/errors/codes.ts | 2 +- ccip-sdk/src/errors/index.ts | 7 -- ccip-sdk/src/errors/recovery.ts | 15 ++-- ccip-sdk/src/errors/specialized.ts | 60 ------------- 16 files changed, 243 insertions(+), 259 deletions(-) create mode 100644 ccip-sdk/src/cct/errors.ts create mode 100644 ccip-sdk/src/cct/evm/operation.ts delete mode 100644 ccip-sdk/src/cct/evm/operations/set-pool.ts create mode 100644 ccip-sdk/src/cct/evm/token-admin/operations/set-pool.ts delete mode 100644 ccip-sdk/src/cct/evm/validate.test.ts create mode 100644 ccip-sdk/src/cct/operation.ts diff --git a/ccip-sdk/src/cct/errors.ts b/ccip-sdk/src/cct/errors.ts new file mode 100644 index 00000000..1c2f32a4 --- /dev/null +++ b/ccip-sdk/src/cct/errors.ts @@ -0,0 +1,67 @@ +/** + * CCT-specific error classes for write operations (validate → encode → submit). + * Shared CCIP errors (`CCIPWalletInvalidError`, etc.) live in `../errors/`. + * + * @packageDocumentation + */ + +import { type CCIPErrorOptions, CCIPError, CCIPErrorCode } from '../errors/index.ts' + +// Parameter validation + +/** Thrown before any RPC when operation params fail validation. Permanent. */ +export class CCTParamsInvalidError extends CCIPError { + override readonly name = 'CCTParamsInvalidError' + /** Creates a params-invalid error. */ + constructor(operation: string, param: string, reason: string, options?: CCIPErrorOptions) { + super( + CCIPErrorCode.CCT_PARAMS_INVALID, + `Invalid ${operation} parameter "${param}": ${reason}`, + { + ...options, + isTransient: false, + context: { ...options?.context, operation, param, reason }, + }, + ) + } +} + +// Transaction submission + +/** + * Thrown when a CCT write fails before broadcast or the transaction reverts after mining. + * Pre-broadcast failures (signing/RPC) may set `isTransient: true` for network errors; + * on-chain reverts are permanent. Reverts include `context.txHash`. + */ +export class CCTTxFailedError extends CCIPError { + override readonly name = 'CCTTxFailedError' + /** Creates a tx-failed error. */ + constructor(operation: string, reason: string, options?: CCIPErrorOptions) { + super(CCIPErrorCode.CCT_TX_FAILED, `${operation} failed: ${reason}`, { + ...options, + isTransient: options?.isTransient ?? false, + context: { ...options?.context, operation, reason }, + }) + } +} + +/** + * Thrown when a transaction was broadcast but not confirmed within the timeout. + * Transient — it may still mine; check `context.txHash` before resubmitting. + */ +export class CCTTxNotConfirmedError extends CCIPError { + override readonly name = 'CCTTxNotConfirmedError' + /** Creates a tx-not-confirmed error. */ + constructor(operation: string, txHash: string, options?: CCIPErrorOptions) { + super( + CCIPErrorCode.CCT_TX_NOT_CONFIRMED, + `${operation} transaction not confirmed within timeout: ${txHash}`, + { + ...options, + isTransient: true, + retryAfterMs: 5000, + context: { ...options?.context, operation, txHash }, + }, + ) + } +} diff --git a/ccip-sdk/src/cct/evm/index.test.ts b/ccip-sdk/src/cct/evm/index.test.ts index 1375ae9a..fc331699 100644 --- a/ccip-sdk/src/cct/evm/index.test.ts +++ b/ccip-sdk/src/cct/evm/index.test.ts @@ -4,9 +4,10 @@ import { describe, it } from 'node:test' import { Interface, id } from 'ethers' import { EVMTokenManager } from './index.ts' -import { CCIPCctParamsInvalidError, CCIPWalletInvalidError } from '../../errors/index.ts' +import { CCIPWalletInvalidError } from '../../errors/index.ts' import type { EVMChain } from '../../evm/index.ts' import { ChainFamily } from '../../networks.ts' +import { CCTParamsInvalidError } from '../errors.ts' const TOKEN = '0x' + '11'.repeat(20) const POOL = '0x' + '22'.repeat(20) @@ -105,7 +106,7 @@ describe('EVMTokenManager (cct/evm)', () => { routerAddress: ROUTER, }), (err: unknown) => - err instanceof CCIPCctParamsInvalidError && + err instanceof CCTParamsInvalidError && err.context.operation === 'setPool' && err.context.param === 'tokenAddress', ) @@ -128,4 +129,5 @@ describe('EVMTokenManager (cct/evm)', () => { ) }) }) + }) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index dcd1af4c..3564881f 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -1,5 +1,5 @@ /** - * EVM Cross-Chain Token (CCT) admin operations on the TokenAdminRegistry. + * EVM Cross-Chain Token (CCT) admin operations. * {@link EVMTokenManager} wraps an {@link EVMChain}: build with * `generateUnsigned` (sender in opts), then `` with `wallet` in opts. * @@ -12,12 +12,14 @@ import type { ChainContext } from '../../chain.ts' import { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' import type { ChainFamily } from '../../networks.ts' +import type { TransactionHash } from '../operation.ts' import { TokenManager } from '../token-manager.ts' -import * as SetPool from './operations/set-pool.ts' +import { type SetPoolParams, SetPool } from './token-admin/operations/set-pool.ts' -/** CCT admin operations for EVM chains, delegating each op to `./operations`. */ +/** CCT admin operations for EVM chains, delegating each op to an operation class. */ export class EVMTokenManager extends TokenManager { readonly chain: EVMChain + readonly #setPool = new SetPool() /** Wraps the chain this manager builds and submits through. */ constructor(chain: EVMChain) { @@ -50,21 +52,20 @@ export class EVMTokenManager extends TokenManager { /** * Builds an unsigned `setPool` tx (for multisig / offline signing). - * @throws {@link CCIPCctParamsInvalidError} if any param is invalid + * @throws {@link CCTParamsInvalidError} if any param is invalid */ - generateUnsignedSetPool( - opts: SetPool.SetPoolParams & { sender?: string }, - ): Promise { - return SetPool.generate(this.chain, opts) + generateUnsignedSetPool(opts: SetPoolParams): Promise { + return this.#setPool.generate(this.chain, opts) } /** * Registers a pool, signing + submitting with `opts.wallet` (the token admin). * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer - * @throws {@link CCIPCctParamsInvalidError} if any param is invalid - * @throws {@link CCIPCctTxFailedError} if the tx reverts or fails + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @throws {@link CCTTxFailedError} if the tx reverts or fails */ - setPool(opts: SetPool.SetPoolParams & { wallet: unknown }): Promise { - return SetPool.execute(this.chain, opts) + setPool(opts: SetPoolParams & { wallet: unknown }): Promise { + return this.#setPool.execute(this.chain, opts) } + } diff --git a/ccip-sdk/src/cct/evm/operation.ts b/ccip-sdk/src/cct/evm/operation.ts new file mode 100644 index 00000000..c7907df2 --- /dev/null +++ b/ccip-sdk/src/cct/evm/operation.ts @@ -0,0 +1,36 @@ +/** + * EVM {@link Operation} lifecycle: validate → encode → submit. + * Concrete ops implement {@link EVMOperation.encode}; this base wires + * {@link generate} and {@link execute}. + * + * @packageDocumentation + */ + +import type { EVMChain } from '../../evm/index.ts' +import type { UnsignedEVMTx } from '../../evm/types.ts' +import type { TransactionHash } from '../operation.ts' +import { Operation } from '../operation.ts' +import { submit } from './submit.ts' + +/** EVM CCT write base. Subclasses supply {@link validate} and {@link encode}. */ +export abstract class EVMOperation

extends Operation< + EVMChain, + P, + UnsignedEVMTx +> { + /** Encode calldata into an unsigned tx; versioned ops resolve their encoder here. */ + protected abstract encode(chain: EVMChain, params: P): Promise | UnsignedEVMTx + + /** Run {@link validate} and {@link encode}, applying optional `sender`; no signing. */ + async generate(chain: EVMChain, params: P): Promise { + this.validate(params) + const unsigned = await this.encode(chain, params) + if (params.sender && unsigned.transactions[0]) unsigned.transactions[0].from = params.sender + return unsigned + } + + /** {@link generate}, then sign and submit via {@link submit}; returns once confirmed. */ + async execute(chain: EVMChain, params: P & { wallet: unknown }): Promise { + return submit(chain, params.wallet, await this.generate(chain, params), this.name) + } +} diff --git a/ccip-sdk/src/cct/evm/operations/set-pool.ts b/ccip-sdk/src/cct/evm/operations/set-pool.ts deleted file mode 100644 index 22a9af8c..00000000 --- a/ccip-sdk/src/cct/evm/operations/set-pool.ts +++ /dev/null @@ -1,84 +0,0 @@ -/** - * `setPool` — registers a pool for a token in the TokenAdminRegistry. - * Version-independent (v1.5/v1.6/v2.0 share one encoding). - * - * @packageDocumentation - */ - -import { type TransactionRequest, Interface } from 'ethers' - -import TokenAdminRegistryABI from '../../../evm/abi/TokenAdminRegistry_1_5.ts' -import type { EVMChain } from '../../../evm/index.ts' -import type { UnsignedEVMTx } from '../../../evm/types.ts' -import { ChainFamily } from '../../../networks.ts' -import type { CctTxResult } from '../../token-manager.ts' -import { submit } from '../submit.ts' -import { validateAddress } from '../validate.ts' - -export const OPERATION = 'setPool' - -/** Parameters for `setPool`. */ -export type SetPoolParams = { - tokenAddress: string - /** Pool to register; zero address delists the token. */ - poolAddress: string - /** Router — used to discover the TokenAdminRegistry. */ - routerAddress: string -} - -/** Result of `setPool`. */ -export type SetPoolResult = CctTxResult - -/** - * Validates {@link SetPoolParams} before any RPC. - * @throws {@link CCIPCctParamsInvalidError} if any address is invalid - */ -function validate(params: SetPoolParams): void { - validateAddress(OPERATION, 'tokenAddress', params.tokenAddress) - validateAddress(OPERATION, 'poolAddress', params.poolAddress) - validateAddress(OPERATION, 'routerAddress', params.routerAddress) -} - -/** Encodes the `setPool(localToken, pool)` calldata. */ -export function encode(params: SetPoolParams): string { - return new Interface(TokenAdminRegistryABI).encodeFunctionData('setPool', [ - params.tokenAddress, - params.poolAddress, - ]) -} - -/** - * Builds an unsigned `setPool` tx on the discovered TokenAdminRegistry; set - * `sender` to populate `from`. - * @throws {@link CCIPCctParamsInvalidError} if any param is invalid - */ -export async function generate( - chain: EVMChain, - opts: SetPoolParams & { sender?: string }, -): Promise { - validate(opts) - - const to = await chain.getTokenAdminRegistryFor(opts.routerAddress) - const tx: TransactionRequest = { to, data: encode(opts) } - if (opts.sender) tx.from = opts.sender - - chain.logger.debug( - `${OPERATION}: TAR = ${to}, token = ${opts.tokenAddress}, pool = ${opts.poolAddress}`, - ) - return { family: ChainFamily.EVM, transactions: [tx] } -} - -/** - * Builds and submits `setPool` with `opts.wallet` (the token admin). - * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer - * @throws {@link CCIPCctParamsInvalidError} if any param is invalid - * @throws {@link CCIPCctTxFailedError} if the tx reverts or fails - */ -export async function execute( - chain: EVMChain, - opts: SetPoolParams & { wallet: unknown }, -): Promise { - const { wallet, ...params } = opts - const unsigned = await generate(chain, params) - return submit(chain, wallet, unsigned, OPERATION) -} diff --git a/ccip-sdk/src/cct/evm/submit.test.ts b/ccip-sdk/src/cct/evm/submit.test.ts index 7804625d..4bfa7d92 100644 --- a/ccip-sdk/src/cct/evm/submit.test.ts +++ b/ccip-sdk/src/cct/evm/submit.test.ts @@ -4,14 +4,11 @@ import { describe, it } from 'node:test' import { makeError } from 'ethers' import { submit } from './submit.ts' -import { - CCIPCctTxFailedError, - CCIPCctTxNotConfirmedError, - CCIPWalletInvalidError, -} from '../../errors/index.ts' +import { CCIPWalletInvalidError } from '../../errors/index.ts' import type { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' import { ChainFamily } from '../../networks.ts' +import { CCTTxFailedError, CCTTxNotConfirmedError } from '../errors.ts' const TAR = '0x' + '44'.repeat(20) const HASH = '0x' + 'ab'.repeat(32) @@ -56,21 +53,21 @@ function fakeSigner(opts: { } describe('submit (shared CCT submit pipeline)', () => { - it('returns the txHash on a successful receipt', async () => { + it('returns the hash on a successful receipt', async () => { const result = await submit( stubChain(), fakeSigner({ receipt: { status: 1 } }), UNSIGNED, 'setPool', ) - assert.deepEqual(result, { txHash: HASH }) + assert.deepEqual(result, { hash: HASH }) }) - it('throws CCIPCctTxFailedError (reverted) on status 0, tagged with the operation', async () => { + it('throws CCTTxFailedError (reverted) on status 0, tagged with the operation', async () => { await assert.rejects( () => submit(stubChain(), fakeSigner({ receipt: { status: 0 } }), UNSIGNED, 'setPool'), (err: unknown) => - err instanceof CCIPCctTxFailedError && + err instanceof CCTTxFailedError && err.context.operation === 'setPool' && err.context.txHash === HASH && !err.isTransient && @@ -78,15 +75,15 @@ describe('submit (shared CCT submit pipeline)', () => { ) }) - it('throws CCIPCctTxNotConfirmedError (transient, keeps hash) when no receipt arrives', async () => { + it('throws CCTTxNotConfirmedError (transient, keeps hash) when no receipt arrives', async () => { await assert.rejects( () => submit(stubChain(), fakeSigner({ receipt: null }), UNSIGNED, 'setPool'), (err: unknown) => - err instanceof CCIPCctTxNotConfirmedError && err.context.txHash === HASH && err.isTransient, + err instanceof CCTTxNotConfirmedError && err.context.txHash === HASH && err.isTransient, ) }) - it('throws CCIPCctTxNotConfirmedError (transient, keeps hash) on confirmation timeout', async () => { + it('throws CCTTxNotConfirmedError (transient, keeps hash) on confirmation timeout', async () => { await assert.rejects( () => submit( @@ -96,11 +93,11 @@ describe('submit (shared CCT submit pipeline)', () => { 'setPool', ), (err: unknown) => - err instanceof CCIPCctTxNotConfirmedError && err.context.txHash === HASH && err.isTransient, + err instanceof CCTTxNotConfirmedError && err.context.txHash === HASH && err.isTransient, ) }) - it('throws a transient CCIPCctTxFailedError when submission fails with a network error', async () => { + it('throws a transient CCTTxFailedError when submission fails with a network error', async () => { await assert.rejects( () => submit( @@ -109,7 +106,7 @@ describe('submit (shared CCT submit pipeline)', () => { UNSIGNED, 'setPool', ), - (err: unknown) => err instanceof CCIPCctTxFailedError && err.isTransient, + (err: unknown) => err instanceof CCTTxFailedError && err.isTransient, ) }) diff --git a/ccip-sdk/src/cct/evm/submit.ts b/ccip-sdk/src/cct/evm/submit.ts index 416de85b..9f00ecd9 100644 --- a/ccip-sdk/src/cct/evm/submit.ts +++ b/ccip-sdk/src/cct/evm/submit.ts @@ -1,27 +1,23 @@ /** - * Shared EVM submit pipeline for CCT ops. Distinguishes three outcomes: a - * pre-broadcast failure ({@link CCIPCctTxFailedError}, transient when the cause - * is network-related), a submitted-but-unconfirmed tx - * ({@link CCIPCctTxNotConfirmedError}, transient, keeps the hash), and a revert - * ({@link CCIPCctTxFailedError}). + * Shared sign-and-submit pipeline for EVM CCT operations. Maps broadcast, + * confirmation, and revert failures to {@link CCTTxFailedError} and + * {@link CCTTxNotConfirmedError}. * * @packageDocumentation */ import { type TransactionRequest, type TransactionResponse, isError } from 'ethers' -import { - CCIPCctTxFailedError, - CCIPCctTxNotConfirmedError, - CCIPWalletInvalidError, -} from '../../errors/index.ts' +import { CCIPWalletInvalidError } from '../../errors/index.ts' import { type EVMChain, isSigner, submitTransaction } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' -import type { CctTxResult } from '../token-manager.ts' +import { CCTTxFailedError, CCTTxNotConfirmedError } from '../errors.ts' +import type { TransactionHash } from '../operation.ts' +/** Max ms to wait for one confirmation before throwing {@link CCTTxNotConfirmedError}. */ const CONFIRM_TIMEOUT_MS = 60_000 -/** True for ethers infra failures that are worth retrying (vs a real revert). */ +/** True for ethers infra errors worth retrying (not an on-chain revert). */ function isTransientError(error: unknown): boolean { return ( isError(error, 'TIMEOUT') || isError(error, 'NETWORK_ERROR') || isError(error, 'SERVER_ERROR') @@ -29,18 +25,18 @@ function isTransientError(error: unknown): boolean { } /** - * Signs + submits a single-transaction CCT op and waits for it to mine. The - * `operation` label is carried into logs and every error's `context.operation`. + * Signs and submits the first transaction in `unsigned`, then waits for one confirmation. + * `operation` labels logs and error context. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer - * @throws {@link CCIPCctTxNotConfirmedError} if submitted but not confirmed in time - * @throws {@link CCIPCctTxFailedError} if submission fails or the tx reverts + * @throws {@link CCTTxNotConfirmedError} if submitted but not confirmed in time + * @throws {@link CCTTxFailedError} if submission fails or the tx reverts */ export async function submit( chain: EVMChain, wallet: unknown, unsigned: UnsignedEVMTx, operation: string, -): Promise { +): Promise { if (!isSigner(wallet)) throw new CCIPWalletInvalidError(wallet) chain.logger.debug(`${operation}: submitting...`) @@ -52,15 +48,10 @@ export async function submit( tx.from = undefined // some signers reject a pre-populated `from` response = await submitTransaction(wallet, tx, chain.provider) } catch (error) { - // Never broadcast — signing/RPC failure; retriable when network-related. - throw new CCIPCctTxFailedError( - operation, - error instanceof Error ? error.message : String(error), - { - cause: error instanceof Error ? error : undefined, - isTransient: isTransientError(error), - }, - ) + throw new CCTTxFailedError(operation, error instanceof Error ? error.message : String(error), { + cause: error instanceof Error ? error : undefined, + isTransient: isTransientError(error), + }) } chain.logger.debug(`${operation}: waiting for confirmation, tx =`, response.hash) @@ -69,19 +60,18 @@ export async function submit( try { receipt = await response.wait(1, CONFIRM_TIMEOUT_MS) } catch (error) { - // Broadcast but not confirmed in time — may still mine; keep the hash. - throw new CCIPCctTxNotConfirmedError(operation, response.hash, { + throw new CCTTxNotConfirmedError(operation, response.hash, { cause: error instanceof Error ? error : undefined, }) } - if (!receipt) throw new CCIPCctTxNotConfirmedError(operation, response.hash) + if (!receipt) throw new CCTTxNotConfirmedError(operation, response.hash) if (receipt.status === 0) { - throw new CCIPCctTxFailedError(operation, 'transaction reverted', { + throw new CCTTxFailedError(operation, 'transaction reverted', { context: { txHash: response.hash }, }) } chain.logger.info(`${operation}: confirmed, tx =`, response.hash) - return { txHash: response.hash } + return { hash: response.hash } } diff --git a/ccip-sdk/src/cct/evm/token-admin/operations/set-pool.ts b/ccip-sdk/src/cct/evm/token-admin/operations/set-pool.ts new file mode 100644 index 00000000..5fb41ecd --- /dev/null +++ b/ccip-sdk/src/cct/evm/token-admin/operations/set-pool.ts @@ -0,0 +1,45 @@ +/** + * setPool — registers a pool for a token in the TokenAdminRegistry. + * Version-independent (v1.5–v2.0 share one encoding). + * + * @packageDocumentation + */ + +import { Interface } from 'ethers' + +import TokenAdminRegistryABI from '../../../../evm/abi/TokenAdminRegistry_1_5.ts' +import type { EVMChain } from '../../../../evm/index.ts' +import type { UnsignedEVMTx } from '../../../../evm/types.ts' +import { ChainFamily } from '../../../../networks.ts' +import { EVMOperation } from '../../operation.ts' +import { validateAddress } from '../../validate.ts' + +/** Parameters for `setPool`. Zero `poolAddress` delists the token. */ +export interface SetPoolParams { + tokenAddress: string + poolAddress: string + routerAddress: string + sender?: string +} + +/** Registers a pool for a token in the TokenAdminRegistry discovered from the router. */ +export class SetPool extends EVMOperation { + readonly name = 'setPool' + + /** Validates all addresses before any RPC. */ + protected validate(p: SetPoolParams): void { + validateAddress(this.name, 'tokenAddress', p.tokenAddress) + validateAddress(this.name, 'poolAddress', p.poolAddress) + validateAddress(this.name, 'routerAddress', p.routerAddress) + } + + /** Encodes `setPool` on the TokenAdminRegistry discovered from the router. */ + protected async encode(chain: EVMChain, p: SetPoolParams): Promise { + const to = await chain.getTokenAdminRegistryFor(p.routerAddress) + const data = new Interface(TokenAdminRegistryABI).encodeFunctionData('setPool', [ + p.tokenAddress, + p.poolAddress, + ]) + return { family: ChainFamily.EVM, transactions: [{ to, data }] } + } +} diff --git a/ccip-sdk/src/cct/evm/validate.test.ts b/ccip-sdk/src/cct/evm/validate.test.ts deleted file mode 100644 index 98b575f0..00000000 --- a/ccip-sdk/src/cct/evm/validate.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import assert from 'node:assert/strict' -import { describe, it } from 'node:test' - -import { validateAddress } from './validate.ts' -import { CCIPCctParamsInvalidError } from '../../errors/index.ts' - -const ADDR = '0x' + '11'.repeat(20) - -describe('validateAddress', () => { - it('accepts a valid address', () => { - assert.doesNotThrow(() => validateAddress('setPool', 'tokenAddress', ADDR)) - }) - - it('rejects a malformed address, tagged with operation + param', () => { - assert.throws( - () => validateAddress('setPool', 'tokenAddress', 'not-an-address'), - (err: unknown) => - err instanceof CCIPCctParamsInvalidError && - err.context.operation === 'setPool' && - err.context.param === 'tokenAddress', - ) - }) - - it('rejects a non-string value', () => { - assert.throws( - () => validateAddress('setPool', 'poolAddress', 123), - (err: unknown) => err instanceof CCIPCctParamsInvalidError, - ) - }) -}) diff --git a/ccip-sdk/src/cct/evm/validate.ts b/ccip-sdk/src/cct/evm/validate.ts index 8c52b757..b0b545d6 100644 --- a/ccip-sdk/src/cct/evm/validate.ts +++ b/ccip-sdk/src/cct/evm/validate.ts @@ -6,15 +6,15 @@ import { isAddress } from 'ethers' -import { CCIPCctParamsInvalidError } from '../../errors/index.ts' +import { CCTParamsInvalidError } from '../errors.ts' /** * Asserts `value` is a valid EVM address. - * @throws {@link CCIPCctParamsInvalidError} if it is not + * @throws {@link CCTParamsInvalidError} if it is not */ export function validateAddress(operation: string, param: string, value: unknown): void { if (typeof value !== 'string' || !isAddress(value)) { - throw new CCIPCctParamsInvalidError( + throw new CCTParamsInvalidError( operation, param, `must be a valid address, got ${String(value)}`, diff --git a/ccip-sdk/src/cct/operation.ts b/ccip-sdk/src/cct/operation.ts new file mode 100644 index 00000000..d29e9b9d --- /dev/null +++ b/ccip-sdk/src/cct/operation.ts @@ -0,0 +1,26 @@ +/** + * Cross-family CCT write contract. {@link Operation} defines the shared + * generate/execute surface; each chain family supplies its own lifecycle base. + * + * @packageDocumentation + */ + +import type { ChainTransaction } from '../types.ts' + +/** Confirmed on-chain hash returned by a successful CCT write. */ +export type TransactionHash = Pick + +/** + * Abstract CCT write operation: build unsigned tx(s) with {@link generate}, or + * sign and submit with {@link execute}. + */ +export abstract class Operation { + /** camelCase id; matches the token-manager facade method and error context. */ + abstract readonly name: string + /** Reject invalid params before any chain RPC. */ + protected abstract validate(params: Params): void + /** Build unsigned transaction(s); no wallet required. */ + abstract generate(chain: Chain, params: Params): Promise + /** Sign and submit via `params.wallet`; returns once confirmed. */ + abstract execute(chain: Chain, params: Params & { wallet: unknown }): Promise +} diff --git a/ccip-sdk/src/cct/token-manager.ts b/ccip-sdk/src/cct/token-manager.ts index 09de5e00..9efe7b42 100644 --- a/ccip-sdk/src/cct/token-manager.ts +++ b/ccip-sdk/src/cct/token-manager.ts @@ -1,5 +1,6 @@ /** - * Cross-family CCT base — the CCT analogue of core's abstract `Chain`. + * Cross-family CCT manager base, the CCT analogue of core's {@link Chain}. + * Family-specific subclasses hold the chain and expose admin operations. * * @packageDocumentation */ @@ -7,12 +8,11 @@ import type { Chain } from '../chain.ts' import type { ChainFamily } from '../networks.ts' -/** Result of any single-transaction CCT write. */ -export interface CctTxResult { - txHash: string -} - -/** Base for a chain-family CCT manager; subclasses hold the concrete `chain`. */ +/** + * Abstract entry point for CCT admin writes on a chain family. Subclasses hold + * the concrete {@link Chain} and delegate to {@link Operation} instances. + */ export abstract class TokenManager { + /** Chain this manager builds and submits through. */ abstract readonly chain: Chain } diff --git a/ccip-sdk/src/errors/codes.ts b/ccip-sdk/src/errors/codes.ts index d6e87ae2..fb447ecc 100644 --- a/ccip-sdk/src/errors/codes.ts +++ b/ccip-sdk/src/errors/codes.ts @@ -180,7 +180,7 @@ export const CCIPErrorCode = { // Canton CANTON_API_ERROR: 'CANTON_API_ERROR', - // CCT SDK + // CCT (Cross-Chain Token) CCT_PARAMS_INVALID: 'CCT_PARAMS_INVALID', CCT_TX_FAILED: 'CCT_TX_FAILED', CCT_TX_NOT_CONFIRMED: 'CCT_TX_NOT_CONFIRMED', diff --git a/ccip-sdk/src/errors/index.ts b/ccip-sdk/src/errors/index.ts index 3847d2ca..f828c2ac 100644 --- a/ccip-sdk/src/errors/index.ts +++ b/ccip-sdk/src/errors/index.ts @@ -91,13 +91,6 @@ export { CCIPContractNotRouterError, CCIPContractTypeInvalidError } from './spec // Specialized errors - Wallet & Signer export { CCIPWalletInvalidError, CCIPWalletNotSignerError } from './specialized.ts' -// Specialized errors - CCT -export { - CCIPCctParamsInvalidError, - CCIPCctTxFailedError, - CCIPCctTxNotConfirmedError, -} from './specialized.ts' - // Specialized errors - Execution export { CCIPExecTxNotConfirmedError, diff --git a/ccip-sdk/src/errors/recovery.ts b/ccip-sdk/src/errors/recovery.ts index 7d04f6de..e7ad328c 100644 --- a/ccip-sdk/src/errors/recovery.ts +++ b/ccip-sdk/src/errors/recovery.ts @@ -202,18 +202,19 @@ export const DEFAULT_RECOVERY_HINTS: Partial> = { INTERACTIVE_REQUIRED: 'Provide the required input via CLI flags or environment variables, or remove --no-interactive to allow prompts.', - CCT_PARAMS_INVALID: - 'Check the operation parameters (addresses, selectors, amounts). See error.context for the offending field.', - CCT_TX_FAILED: - 'The CCT admin transaction failed. Ensure the caller holds the required role (token admin / pool owner) for this operation.', - CCT_TX_NOT_CONFIRMED: - 'The transaction was submitted but not confirmed in time. Check the tx hash in error.context before resubmitting — it may still be mined.', - NOT_IMPLEMENTED: 'This feature is not yet implemented.', UNKNOWN: 'An unknown error occurred. Check the error details.', CANTON_API_ERROR: 'Canton Ledger API returned an error. Verify the party ID is correct, the contract is active, and the Canton node is reachable.', + + // Cross-Chain Token + CCT_PARAMS_INVALID: + 'Verify the operation parameters. See error.context for the field name and reason.', + CCT_TX_FAILED: + 'The CCT transaction failed. Ensure the caller holds the required role for this operation.', + CCT_TX_NOT_CONFIRMED: + 'The transaction was submitted but not confirmed in time. Check the tx hash in error.context before resubmitting; it may still be mined.', } /** Returns default recovery hint for error code, or undefined if none. */ diff --git a/ccip-sdk/src/errors/specialized.ts b/ccip-sdk/src/errors/specialized.ts index 591d3cbe..86119b3d 100644 --- a/ccip-sdk/src/errors/specialized.ts +++ b/ccip-sdk/src/errors/specialized.ts @@ -2237,66 +2237,6 @@ export class CCIPWalletInvalidError extends CCIPError { } } -// CCT — Cross-Chain Token admin -// -// Generic across all CCT operations (setPool, applyChainUpdates, …). The -// specific operation is carried in `error.context.operation` so callers branch -// on `(code, operation)` rather than a per-op class — this keeps the error -// surface flat as the operation set grows. Reserve a dedicated subclass only -// for an op with genuinely distinct recovery semantics. - -/** Thrown before any RPC when a CCT operation's parameters fail validation. */ -export class CCIPCctParamsInvalidError extends CCIPError { - override readonly name = 'CCIPCctParamsInvalidError' - /** Creates a CCT params invalid error for `operation` (e.g. `'setPool'`). */ - constructor(operation: string, param: string, reason: string, options?: CCIPErrorOptions) { - super( - CCIPErrorCode.CCT_PARAMS_INVALID, - `Invalid ${operation} parameter "${param}": ${reason}`, - { - ...options, - isTransient: false, - context: { ...options?.context, operation, param, reason }, - }, - ) - } -} - -/** Thrown when a CCT operation's transaction reverts or fails after submission. */ -export class CCIPCctTxFailedError extends CCIPError { - override readonly name = 'CCIPCctTxFailedError' - /** Creates a CCT tx failed error for `operation` (e.g. `'setPool'`). */ - constructor(operation: string, reason: string, options?: CCIPErrorOptions) { - super(CCIPErrorCode.CCT_TX_FAILED, `${operation} failed: ${reason}`, { - ...options, - isTransient: options?.isTransient ?? false, - context: { ...options?.context, operation, reason }, - }) - } -} - -/** - * Thrown when a CCT operation's transaction was submitted but not confirmed - * within the timeout. Transient — the tx may still mine; `context.txHash` lets - * the caller check before resubmitting. - */ -export class CCIPCctTxNotConfirmedError extends CCIPError { - override readonly name = 'CCIPCctTxNotConfirmedError' - /** Creates a CCT tx not-confirmed error for `operation` (e.g. `'setPool'`). */ - constructor(operation: string, txHash: string, options?: CCIPErrorOptions) { - super( - CCIPErrorCode.CCT_TX_NOT_CONFIRMED, - `${operation} transaction not confirmed within timeout: ${txHash}`, - { - ...options, - isTransient: true, - retryAfterMs: 5000, - context: { ...options?.context, operation, txHash }, - }, - ) - } -} - // Source Chain /** From b8cbf727cb10769f5e9f105f1c5bc9fed3cdc5ae Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Tue, 7 Jul 2026 16:33:45 +0100 Subject: [PATCH 02/22] CCT: Add version dispatch + Transfer Ownership --- ccip-sdk/src/cct/errors.ts | 59 +++++++ ccip-sdk/src/cct/evm/index.test.ts | 27 ++- ccip-sdk/src/cct/evm/index.ts | 27 ++- .../operations/transfer-ownership.ts | 58 ++++++ .../src/cct/evm/token-pool/version.test.ts | 166 ++++++++++++++++++ ccip-sdk/src/cct/evm/token-pool/version.ts | 125 +++++++++++++ ccip-sdk/src/cct/evm/validate.ts | 7 +- ccip-sdk/src/errors/codes.ts | 2 + ccip-sdk/src/errors/recovery.ts | 4 + 9 files changed, 469 insertions(+), 6 deletions(-) create mode 100644 ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts create mode 100644 ccip-sdk/src/cct/evm/token-pool/version.test.ts create mode 100644 ccip-sdk/src/cct/evm/token-pool/version.ts diff --git a/ccip-sdk/src/cct/errors.ts b/ccip-sdk/src/cct/errors.ts index 1c2f32a4..ff333b4d 100644 --- a/ccip-sdk/src/cct/errors.ts +++ b/ccip-sdk/src/cct/errors.ts @@ -65,3 +65,62 @@ export class CCTTxNotConfirmedError extends CCIPError { ) } } + +// Token-pool version dispatch + +/** + * Thrown when the contract at an address is not a supported token-pool type + * (BurnMint or LockRelease). + */ +export class CCTContractTypeInvalidError extends CCIPError { + override readonly name = 'CCTContractTypeInvalidError' + /** Creates a contract-type-invalid error. */ + constructor(address: string, expected: string, actual: string, options?: CCIPErrorOptions) { + super( + CCIPErrorCode.CONTRACT_TYPE_INVALID, + `Expected a ${expected} contract at ${address}, got "${actual}"`, + { + ...options, + isTransient: false, + context: { ...options?.context, address, expected, actual }, + }, + ) + } +} + +/** Thrown when a token pool reports a version string the SDK does not recognize. Permanent. */ +export class CCTTokenPoolVersionUnsupportedError extends CCIPError { + override readonly name = 'CCTTokenPoolVersionUnsupportedError' + /** Creates a token-pool-version-unsupported error. */ + constructor(version: string, options?: CCIPErrorOptions) { + super( + CCIPErrorCode.CCT_TOKEN_POOL_VERSION_UNSUPPORTED, + `Unsupported token pool version: ${version}`, + { + ...options, + isTransient: false, + context: { ...options?.context, version }, + }, + ) + } +} + +/** + * Thrown when no implementation is registered for an operation at or below the pool's + * version (floor-match miss). Permanent for that pool version. + */ +export class CCTOperationUnsupportedError extends CCIPError { + override readonly name = 'CCTOperationUnsupportedError' + /** Creates an operation-unsupported error. */ + constructor(operation: string, version: string, options?: CCIPErrorOptions) { + super( + CCIPErrorCode.CCT_OPERATION_UNSUPPORTED, + `${operation} is not supported at token-pool version ${version}`, + { + ...options, + isTransient: false, + context: { ...options?.context, operation, version }, + }, + ) + } +} diff --git a/ccip-sdk/src/cct/evm/index.test.ts b/ccip-sdk/src/cct/evm/index.test.ts index fc331699..4548fada 100644 --- a/ccip-sdk/src/cct/evm/index.test.ts +++ b/ccip-sdk/src/cct/evm/index.test.ts @@ -7,7 +7,7 @@ import { EVMTokenManager } from './index.ts' import { CCIPWalletInvalidError } from '../../errors/index.ts' import type { EVMChain } from '../../evm/index.ts' import { ChainFamily } from '../../networks.ts' -import { CCTParamsInvalidError } from '../errors.ts' +import { CCTParamsInvalidError, CCTTokenPoolVersionUnsupportedError } from '../errors.ts' const TOKEN = '0x' + '11'.repeat(20) const POOL = '0x' + '22'.repeat(20) @@ -15,11 +15,12 @@ const ROUTER = '0x' + '33'.repeat(20) const TAR = '0x' + '44'.repeat(20) /** Minimal EVMChain stub — only the members EVMTokenManager touches. */ -function stubChain(overrides: Partial = {}): EVMChain { +function stubChain(overrides: Partial = {}, poolVersion = '1.5.1'): EVMChain { return { provider: {} as never, logger: { debug() {}, info() {}, warn() {}, error() {} }, getTokenAdminRegistryFor: (_address: string) => Promise.resolve(TAR), + typeAndVersion: (_address: string) => Promise.resolve(['BurnMintTokenPool', poolVersion]), ...overrides, } as unknown as EVMChain } @@ -28,6 +29,9 @@ const SET_POOL_SELECTOR = id('setPool(address,address)').slice(0, 10) const EXPECTED_DATA = new Interface([ 'function setPool(address localToken, address pool)', ]).encodeFunctionData('setPool', [TOKEN, POOL]) +const EXPECTED_TRANSFER = new Interface([ + 'function transferOwnership(address to)', +]).encodeFunctionData('transferOwnership', [TOKEN]) describe('EVMTokenManager (cct/evm)', () => { describe('construction', () => { @@ -130,4 +134,23 @@ describe('EVMTokenManager (cct/evm)', () => { }) }) + describe('transferOwnership', () => { + it('builds transferOwnership to the pool (floor-match across versions)', async () => { + const cct = EVMTokenManager.fromChain(stubChain({}, '1.6.1')) + const unsigned = await cct.generateUnsignedTransferOwnership({ + poolAddress: POOL, + newOwner: TOKEN, + }) + assert.equal(unsigned.transactions[0]!.to, POOL) + assert.equal(unsigned.transactions[0]!.data, EXPECTED_TRANSFER) + }) + + it('throws for an unsupported pool version', async () => { + const cct = EVMTokenManager.fromChain(stubChain({}, '1.6.0')) + await assert.rejects( + () => cct.generateUnsignedTransferOwnership({ poolAddress: POOL, newOwner: TOKEN }), + CCTTokenPoolVersionUnsupportedError, + ) + }) + }) }) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 3564881f..5f8c6d56 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -15,13 +15,17 @@ import type { ChainFamily } from '../../networks.ts' import type { TransactionHash } from '../operation.ts' import { TokenManager } from '../token-manager.ts' import { type SetPoolParams, SetPool } from './token-admin/operations/set-pool.ts' +import { + type TransferOwnershipParams, + TransferOwnership, +} from './token-pool/operations/transfer-ownership.ts' /** CCT admin operations for EVM chains, delegating each op to an operation class. */ export class EVMTokenManager extends TokenManager { readonly chain: EVMChain readonly #setPool = new SetPool() + readonly #transferOwnership = new TransferOwnership() - /** Wraps the chain this manager builds and submits through. */ constructor(chain: EVMChain) { super() this.chain = chain @@ -68,4 +72,25 @@ export class EVMTokenManager extends TokenManager { return this.#setPool.execute(this.chain, opts) } + /** + * Builds an unsigned pool `transferOwnership` tx (for multisig / offline signing). + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @throws {@link CCTContractTypeInvalidError} if the pool is not a recognised pool type + * @throws {@link CCTTokenPoolVersionUnsupportedError} if the pool version is unsupported + */ + generateUnsignedTransferOwnership(opts: TransferOwnershipParams): Promise { + return this.#transferOwnership.generate(this.chain, opts) + } + + /** + * Proposes a new pool owner (two-step), signing + submitting with `opts.wallet`. + * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @throws {@link CCTContractTypeInvalidError} if the pool is not a recognised pool type + * @throws {@link CCTTokenPoolVersionUnsupportedError} if the pool version is unsupported + * @throws {@link CCTTxFailedError} if the tx reverts or fails + */ + transferOwnership(opts: TransferOwnershipParams & { wallet: unknown }): Promise { + return this.#transferOwnership.execute(this.chain, opts) + } } diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts new file mode 100644 index 00000000..2f30303e --- /dev/null +++ b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts @@ -0,0 +1,58 @@ +/** + * transferOwnership: proposes a new TokenPool owner (Ownable2Step; the new + * owner must later call acceptOwnership). + * + * @packageDocumentation + */ + +import { type InterfaceAbi, Interface } from 'ethers' + +import type { EVMChain } from '../../../../evm/index.ts' +import type { UnsignedEVMTx } from '../../../../evm/types.ts' +import { ChainFamily } from '../../../../networks.ts' +import { EVMOperation } from '../../operation.ts' +import { validateAddress } from '../../validate.ts' +import { TokenPoolVersion, resolveEncoder, resolveTokenPool } from '../version.ts' + +/** Parameters for {@link TransferOwnership}. */ +export interface TransferOwnershipParams { + poolAddress: string + newOwner: string + sender?: string +} + +/** Encodes `transferOwnership` calldata against the resolved pool ABI. */ +type Encoder = (abi: InterfaceAbi, params: TransferOwnershipParams) => UnsignedEVMTx + +const encodeTransferOwnership: Encoder = (abi, { newOwner, poolAddress }) => { + const data = new Interface(abi).encodeFunctionData('transferOwnership', [newOwner]) + return { family: ChainFamily.EVM, transactions: [{ to: poolAddress, data }] } +} + +/** Proposes a new TokenPool owner via Ownable2Step `transferOwnership`. */ +export class TransferOwnership extends EVMOperation { + readonly name = 'transferOwnership' + + /** + * Stable across pool versions: one V1_5_0 entry covers all via floor-match. + * Add another only when a version's encoding diverges. + */ + private readonly encoders: Partial> = { + [TokenPoolVersion.V1_5_0]: encodeTransferOwnership, + } + + /** Validates the pool and new-owner addresses before any RPC. */ + protected validate({ poolAddress, newOwner }: TransferOwnershipParams): void { + validateAddress(this.name, 'poolAddress', poolAddress) + validateAddress(this.name, 'newOwner', newOwner) + } + + /** Reads the pool's type-and-version, then floor-matches the encoder and its ABI. */ + protected async encode( + chain: EVMChain, + { poolAddress, newOwner }: TransferOwnershipParams, + ): Promise { + const { version, abi } = await resolveTokenPool(chain, poolAddress) + return resolveEncoder(this.encoders, version, this.name)(abi, { poolAddress, newOwner }) + } +} diff --git a/ccip-sdk/src/cct/evm/token-pool/version.test.ts b/ccip-sdk/src/cct/evm/token-pool/version.test.ts new file mode 100644 index 00000000..03c520fd --- /dev/null +++ b/ccip-sdk/src/cct/evm/token-pool/version.test.ts @@ -0,0 +1,166 @@ +import assert from 'node:assert/strict' +import { describe, it } from 'node:test' + +import { + TOKEN_POOL_ABIS, + TOKEN_POOL_TYPES, + TokenPoolVersion, + isTokenPoolType, + isTokenPoolVersion, + parseTokenPoolVersion, + tokenPoolAbi, + resolveEncoder, +} from './version.ts' +import { + CCTContractTypeInvalidError, + CCTOperationUnsupportedError, + CCTTokenPoolVersionUnsupportedError, +} from '../../errors.ts' + +const ADDR = '0x' + '11'.repeat(20) + +describe('pool types', () => { + it('lists known EVM pool types', () => { + assert.deepEqual([...TOKEN_POOL_TYPES], ['BurnMintTokenPool', 'LockReleaseTokenPool']) + }) + + it('isTokenPoolType narrows supported types and rejects others', () => { + assert.equal(isTokenPoolType('BurnMintTokenPool'), true) + assert.equal(isTokenPoolType('LockReleaseTokenPool'), true) + assert.equal(isTokenPoolType('UpgradeableLockReleaseTokenPool'), false) + assert.equal(isTokenPoolType('TokenAdminRegistry'), false) + }) +}) + +describe('pool versions', () => { + it('lists known EVM pool versions low→high', () => { + assert.deepEqual(Object.values(TokenPoolVersion), [ + TokenPoolVersion.V1_5_0, + TokenPoolVersion.V1_5_1, + TokenPoolVersion.V1_6_1, + TokenPoolVersion.V2_0_0, + ]) + }) + + it('isTokenPoolVersion narrows known versions and rejects others', () => { + assert.equal(isTokenPoolVersion(TokenPoolVersion.V1_5_1), true) + assert.equal(isTokenPoolVersion(TokenPoolVersion.V2_0_0), true) + assert.equal(isTokenPoolVersion('1.6.0'), false) + assert.equal(isTokenPoolVersion('garbage'), false) + }) +}) + +describe('parseTokenPoolVersion', () => { + it('returns { type, version } for a known pool type+version', () => { + assert.deepEqual( + parseTokenPoolVersion({ address: ADDR, contractType: 'BurnMintTokenPool', version: '1.5.1' }), + { + type: 'BurnMintTokenPool', + version: TokenPoolVersion.V1_5_1, + }, + ) + assert.deepEqual( + parseTokenPoolVersion({ + address: ADDR, + contractType: 'LockReleaseTokenPool', + version: '2.0.0', + }), + { + type: 'LockReleaseTokenPool', + version: TokenPoolVersion.V2_0_0, + }, + ) + }) + + it('throws CCTContractTypeInvalidError for an unsupported pool type', () => { + assert.throws( + () => + parseTokenPoolVersion({ + address: ADDR, + contractType: 'TokenAdminRegistry', + version: '1.5.1', + }), + CCTContractTypeInvalidError, + ) + }) + + it('throws CCTContractTypeInvalidError for UpgradeableLockReleaseTokenPool (not in TOKEN_POOL_TYPES)', () => { + assert.throws( + () => + parseTokenPoolVersion({ + address: ADDR, + contractType: 'UpgradeableLockReleaseTokenPool', + version: '1.5.1', + }), + CCTContractTypeInvalidError, + ) + }) + + it('throws CCTTokenPoolVersionUnsupportedError for an unknown version', () => { + assert.throws( + () => + parseTokenPoolVersion({ + address: ADDR, + contractType: 'BurnMintTokenPool', + version: '1.7.0', + }), + CCTTokenPoolVersionUnsupportedError, + ) + }) +}) + +describe('TOKEN_POOL_ABIS', () => { + it('returns an array (ABI) for each supported version', () => { + assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_0])) + assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_1])) + assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V1_6_1])) + assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V2_0_0])) + }) + + it('returns distinct ABI objects for different version slots', () => { + assert.notDeepEqual( + TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_0], + TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_1], + ) + }) +}) + +describe('tokenPoolAbi', () => { + it('returns the exact ABI for the requested version', () => { + assert.equal( + tokenPoolAbi('BurnMintTokenPool', TokenPoolVersion.V1_5_0), + TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_0], + ) + assert.equal( + tokenPoolAbi('LockReleaseTokenPool', TokenPoolVersion.V2_0_0), + TOKEN_POOL_ABIS[TokenPoolVersion.V2_0_0], + ) + }) + + it('ignores type today: both types resolve to the same ABI per version', () => { + assert.equal( + tokenPoolAbi('BurnMintTokenPool', TokenPoolVersion.V1_6_1), + tokenPoolAbi('LockReleaseTokenPool', TokenPoolVersion.V1_6_1), + ) + }) +}) + +describe('resolveEncoder', () => { + it('floor-matches to the encoder at the greatest version ≤ requested', () => { + const encoders = { + [TokenPoolVersion.V1_5_0]: () => 'a', + [TokenPoolVersion.V2_0_0]: () => 'b', + } + assert.equal(resolveEncoder(encoders, TokenPoolVersion.V1_5_0, 'op')(), 'a') + assert.equal(resolveEncoder(encoders, TokenPoolVersion.V1_6_1, 'op')(), 'a') + assert.equal(resolveEncoder(encoders, TokenPoolVersion.V2_0_0, 'op')(), 'b') + }) + + it('throws when nothing is registered at or below the version', () => { + assert.throws( + () => + resolveEncoder({ [TokenPoolVersion.V2_0_0]: () => 'b' }, TokenPoolVersion.V1_5_0, 'op'), + CCTOperationUnsupportedError, + ) + }) +}) diff --git a/ccip-sdk/src/cct/evm/token-pool/version.ts b/ccip-sdk/src/cct/evm/token-pool/version.ts new file mode 100644 index 00000000..4e337ab3 --- /dev/null +++ b/ccip-sdk/src/cct/evm/token-pool/version.ts @@ -0,0 +1,125 @@ +/** + * EVM token-pool version axis for CCT: resolve on-chain pool metadata and ABI + * ({@link resolveTokenPool}), and floor-match encoders ({@link resolveEncoder}). + * + * @packageDocumentation + */ + +import type { InterfaceAbi } from 'ethers' + +import LockReleaseTokenPool_1_5 from '../../../evm/abi/LockReleaseTokenPool_1_5.ts' +import LockReleaseTokenPool_1_5_1 from '../../../evm/abi/LockReleaseTokenPool_1_5_1.ts' +import LockReleaseTokenPool_1_6_1 from '../../../evm/abi/LockReleaseTokenPool_1_6_1.ts' +import TokenPool_2_0 from '../../../evm/abi/TokenPool_2_0.ts' +import type { EVMChain } from '../../../evm/index.ts' +import { + CCTContractTypeInvalidError, + CCTOperationUnsupportedError, + CCTTokenPoolVersionUnsupportedError, +} from '../../errors.ts' + +/** Supported pool contract types; unsupported values fail in {@link parseTokenPoolVersion}. */ +export const TOKEN_POOL_TYPES = ['BurnMintTokenPool', 'LockReleaseTokenPool'] as const + +/** A supported EVM token-pool contract type. */ +export type TokenPoolType = (typeof TOKEN_POOL_TYPES)[number] + +/** Type guard for {@link TOKEN_POOL_TYPES}. */ +export function isTokenPoolType(v: string): v is TokenPoolType { + return TOKEN_POOL_TYPES.some((known) => known === v) +} + +/** + * Known pool versions, low to high. Value order drives floor-match in + * {@link resolveEncoder}. + */ +export const TokenPoolVersion = { + V1_5_0: '1.5.0', + V1_5_1: '1.5.1', + V1_6_1: '1.6.1', + V2_0_0: '2.0.0', +} as const + +/** A known EVM token-pool version. */ +export type TokenPoolVersion = (typeof TokenPoolVersion)[keyof typeof TokenPoolVersion] + +/** Type guard for {@link TokenPoolVersion}. */ +export function isTokenPoolVersion(v: string): v is TokenPoolVersion { + return Object.values(TokenPoolVersion).some((known) => known === v) +} + +/** + * Narrows raw `typeAndVersion` strings to a known {@link TokenPoolType} and + * {@link TokenPoolVersion}. + * @throws {@link CCTContractTypeInvalidError} if `contractType` is not a supported pool type + * @throws {@link CCTTokenPoolVersionUnsupportedError} if `version` is not a known pool version + */ +export function parseTokenPoolVersion({ + address, + contractType, + version, +}: { + address: string + contractType: string + version: string +}): { type: TokenPoolType; version: TokenPoolVersion } { + if (!isTokenPoolType(contractType)) + throw new CCTContractTypeInvalidError( + address, + 'BurnMintTokenPool or LockReleaseTokenPool', + contractType, + ) + if (!isTokenPoolVersion(version)) + throw new CCTTokenPoolVersionUnsupportedError(version, { context: { address } }) + return { type: contractType, version } +} + +/** Vendored pool ABIs keyed by {@link TokenPoolVersion}. + * TODO: split per type once BurnMint ABIs are imported from @chainlink/contracts-ccip */ +export const TOKEN_POOL_ABIS: Record = { + [TokenPoolVersion.V1_5_0]: LockReleaseTokenPool_1_5, + [TokenPoolVersion.V1_5_1]: LockReleaseTokenPool_1_5_1, + [TokenPoolVersion.V1_6_1]: LockReleaseTokenPool_1_6_1, + [TokenPoolVersion.V2_0_0]: TokenPool_2_0, +} + +/** + * Returns the pool ABI for `type` and `version`. `type` keeps call sites stable + * for a future per-type split; today only `version` selects the ABI. Never throws + * when `version` came from {@link parseTokenPoolVersion}. + */ +export function tokenPoolAbi(_type: TokenPoolType, version: TokenPoolVersion): InterfaceAbi { + return TOKEN_POOL_ABIS[version] +} + +/** + * Reads `chain.typeAndVersion(poolAddress)`, narrows the result, and attaches the + * pool ABI. Shared RPC boundary before versioned pool encoding. + * @throws the same errors as {@link parseTokenPoolVersion} + */ +export async function resolveTokenPool( + chain: EVMChain, + poolAddress: string, +): Promise<{ type: TokenPoolType; version: TokenPoolVersion; abi: InterfaceAbi }> { + const [contractType, version] = await chain.typeAndVersion(poolAddress) + const pool = parseTokenPoolVersion({ address: poolAddress, contractType, version }) + return { ...pool, abi: tokenPoolAbi(pool.type, pool.version) } +} + +/** + * Returns the encoder registered at the greatest version less than or equal to + * `version`. One entry per calldata change covers all higher versions via floor-match. + * @throws {@link CCTOperationUnsupportedError} if nothing is registered at or below `version` + */ +export function resolveEncoder( + encoders: Partial>, + version: TokenPoolVersion, + op: string, +): F { + const versions = Object.values(TokenPoolVersion) + for (let i = versions.indexOf(version); i >= 0; i--) { + const encoder = encoders[versions[i]!] + if (encoder !== undefined) return encoder + } + throw new CCTOperationUnsupportedError(op, version) +} diff --git a/ccip-sdk/src/cct/evm/validate.ts b/ccip-sdk/src/cct/evm/validate.ts index b0b545d6..3440cbe8 100644 --- a/ccip-sdk/src/cct/evm/validate.ts +++ b/ccip-sdk/src/cct/evm/validate.ts @@ -1,5 +1,6 @@ /** - * Shared parameter validators for EVM CCT ops. + * Shared parameter validators for EVM CCT operations. Throws + * {@link CCTParamsInvalidError} before any RPC so invalid inputs fail fast. * * @packageDocumentation */ @@ -9,8 +10,8 @@ import { isAddress } from 'ethers' import { CCTParamsInvalidError } from '../errors.ts' /** - * Asserts `value` is a valid EVM address. - * @throws {@link CCTParamsInvalidError} if it is not + * Asserts `value` is a valid EVM address. Tags the error with `operation` and `param`. + * @throws {@link CCTParamsInvalidError} */ export function validateAddress(operation: string, param: string, value: unknown): void { if (typeof value !== 'string' || !isAddress(value)) { diff --git a/ccip-sdk/src/errors/codes.ts b/ccip-sdk/src/errors/codes.ts index fb447ecc..3225a5f9 100644 --- a/ccip-sdk/src/errors/codes.ts +++ b/ccip-sdk/src/errors/codes.ts @@ -184,6 +184,8 @@ export const CCIPErrorCode = { CCT_PARAMS_INVALID: 'CCT_PARAMS_INVALID', CCT_TX_FAILED: 'CCT_TX_FAILED', CCT_TX_NOT_CONFIRMED: 'CCT_TX_NOT_CONFIRMED', + CCT_TOKEN_POOL_VERSION_UNSUPPORTED: 'CCT_TOKEN_POOL_VERSION_UNSUPPORTED', + CCT_OPERATION_UNSUPPORTED: 'CCT_OPERATION_UNSUPPORTED', } as const /** Union type of all error codes. */ diff --git a/ccip-sdk/src/errors/recovery.ts b/ccip-sdk/src/errors/recovery.ts index e7ad328c..be4012da 100644 --- a/ccip-sdk/src/errors/recovery.ts +++ b/ccip-sdk/src/errors/recovery.ts @@ -215,6 +215,10 @@ export const DEFAULT_RECOVERY_HINTS: Partial> = { 'The CCT transaction failed. Ensure the caller holds the required role for this operation.', CCT_TX_NOT_CONFIRMED: 'The transaction was submitted but not confirmed in time. Check the tx hash in error.context before resubmitting; it may still be mined.', + CCT_TOKEN_POOL_VERSION_UNSUPPORTED: + 'This token-pool version is not supported by the CCT SDK. Check the pool address and its typeAndVersion.', + CCT_OPERATION_UNSUPPORTED: + 'This operation is not available at the token pool version in error.context. Verify the pool version supports it.', } /** Returns default recovery hint for error code, or undefined if none. */ From 4cf2f1a2aa33fd185763df417ddbb3b74f6286dd Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Thu, 9 Jul 2026 16:58:37 +0100 Subject: [PATCH 03/22] Adjust with base --- .../src/cct/evm/token-pool/operations/transfer-ownership.ts | 2 +- ccip-sdk/src/cct/evm/token-pool/version.test.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts index 2f30303e..db33d01c 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts @@ -48,7 +48,7 @@ export class TransferOwnership extends EVMOperation { } /** Reads the pool's type-and-version, then floor-matches the encoder and its ABI. */ - protected async encode( + protected async buildUnsigned( chain: EVMChain, { poolAddress, newOwner }: TransferOwnershipParams, ): Promise { diff --git a/ccip-sdk/src/cct/evm/token-pool/version.test.ts b/ccip-sdk/src/cct/evm/token-pool/version.test.ts index 03c520fd..35214468 100644 --- a/ccip-sdk/src/cct/evm/token-pool/version.test.ts +++ b/ccip-sdk/src/cct/evm/token-pool/version.test.ts @@ -8,8 +8,8 @@ import { isTokenPoolType, isTokenPoolVersion, parseTokenPoolVersion, - tokenPoolAbi, resolveEncoder, + tokenPoolAbi, } from './version.ts' import { CCTContractTypeInvalidError, @@ -158,8 +158,7 @@ describe('resolveEncoder', () => { it('throws when nothing is registered at or below the version', () => { assert.throws( - () => - resolveEncoder({ [TokenPoolVersion.V2_0_0]: () => 'b' }, TokenPoolVersion.V1_5_0, 'op'), + () => resolveEncoder({ [TokenPoolVersion.V2_0_0]: () => 'b' }, TokenPoolVersion.V1_5_0, 'op'), CCTOperationUnsupportedError, ) }) From 87974f84a3ef08a6a40cd0e3a04a078ceae13f97 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Mon, 13 Jul 2026 16:24:00 +0100 Subject: [PATCH 04/22] Address generic error types and doc examples --- ccip-sdk/src/cct/errors.ts | 33 +++++++++++++++++++++++++++------ ccip-sdk/src/errors/recovery.ts | 2 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/ccip-sdk/src/cct/errors.ts b/ccip-sdk/src/cct/errors.ts index 8ab695c9..8acb6fb8 100644 --- a/ccip-sdk/src/cct/errors.ts +++ b/ccip-sdk/src/cct/errors.ts @@ -101,11 +101,21 @@ export class CCTTxNotConfirmedError extends CCIPError { } } -// Token-pool version dispatch +// Contract version dispatch /** - * Thrown when the contract at an address is not a supported token-pool type - * (BurnMint or LockRelease). + * Thrown when the contract at an address is not of the expected type. + * + * @example + * ```typescript + * try { + * await cct.transferOwnership({ poolAddress, newOwner, wallet }) + * } catch (error) { + * if (error instanceof CCTContractTypeInvalidError) { + * console.log(`Expected ${error.context.expected} at ${error.context.address}, got "${error.context.actual}"`) + * } + * } + * ``` */ export class CCTContractTypeInvalidError extends CCIPError { override readonly name = 'CCTContractTypeInvalidError' @@ -154,8 +164,19 @@ export class CCTContractVersionUnsupportedError extends CCIPError { } /** - * Thrown when no implementation is registered for an operation at or below the pool's - * version (floor-match miss). Permanent for that pool version. + * Thrown when no implementation is registered for an operation at or below the contract's + * version (floor-match miss). Permanent for that contract version. + * + * @example + * ```typescript + * try { + * await cct.transferOwnership({ poolAddress, newOwner, wallet }) + * } catch (error) { + * if (error instanceof CCTOperationUnsupportedError) { + * console.log(`${error.context.operation} unsupported at version ${error.context.version}`) + * } + * } + * ``` */ export class CCTOperationUnsupportedError extends CCIPError { override readonly name = 'CCTOperationUnsupportedError' @@ -163,7 +184,7 @@ export class CCTOperationUnsupportedError extends CCIPError { constructor(operation: string, version: string, options?: CCIPErrorOptions) { super( CCIPErrorCode.CCT_OPERATION_UNSUPPORTED, - `${operation} is not supported at token-pool version ${version}`, + `${operation} is not supported at contract version ${version}`, { ...options, isTransient: false, diff --git a/ccip-sdk/src/errors/recovery.ts b/ccip-sdk/src/errors/recovery.ts index 1d20f75a..285e188f 100644 --- a/ccip-sdk/src/errors/recovery.ts +++ b/ccip-sdk/src/errors/recovery.ts @@ -216,7 +216,7 @@ export const DEFAULT_RECOVERY_HINTS: Partial> = { CCT_CONTRACT_VERSION_UNSUPPORTED: 'This contract version is not supported by the CCT SDK. Check the contract address and its typeAndVersion.', CCT_OPERATION_UNSUPPORTED: - 'This operation is not available at the token pool version in error.context. Verify the pool version supports it.', + 'This operation is not available at the contract version in error.context. Verify the contract version supports it.', } /** Returns default recovery hint for error code, or undefined if none. */ From bbc91917a458a5d7c3057387ad004695b654b147 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Mon, 13 Jul 2026 17:31:28 +0100 Subject: [PATCH 05/22] Fix linting --- ccip-sdk/src/cct/evm/index.test.ts | 2 +- ccip-sdk/src/cct/evm/index.ts | 1 + ccip-sdk/src/cct/evm/token-pool/version.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ccip-sdk/src/cct/evm/index.test.ts b/ccip-sdk/src/cct/evm/index.test.ts index 7a9c379f..48b505c9 100644 --- a/ccip-sdk/src/cct/evm/index.test.ts +++ b/ccip-sdk/src/cct/evm/index.test.ts @@ -7,7 +7,7 @@ import { EVMTokenManager } from './index.ts' import { CCIPWalletInvalidError } from '../../errors/index.ts' import type { EVMChain } from '../../evm/index.ts' import { ChainFamily } from '../../networks.ts' -import { CCTParamsInvalidError, CCTContractVersionUnsupportedError } from '../errors.ts' +import { CCTContractVersionUnsupportedError, CCTParamsInvalidError } from '../errors.ts' const TOKEN = '0x' + '11'.repeat(20) const POOL = '0x' + '22'.repeat(20) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 48ab8b63..36b51655 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -26,6 +26,7 @@ export class EVMTokenManager extends TokenManager { readonly #setPool = new SetPool() readonly #transferOwnership = new TransferOwnership() + /** Wraps an {@link EVMChain}; prefer the static factory methods. */ constructor(chain: EVMChain) { super() this.chain = chain diff --git a/ccip-sdk/src/cct/evm/token-pool/version.ts b/ccip-sdk/src/cct/evm/token-pool/version.ts index b8ac8c38..0415712c 100644 --- a/ccip-sdk/src/cct/evm/token-pool/version.ts +++ b/ccip-sdk/src/cct/evm/token-pool/version.ts @@ -75,7 +75,7 @@ export function parseTokenPoolVersion({ } /** Vendored pool ABIs keyed by {@link TokenPoolVersion}. - * TODO: split per type once BurnMint ABIs are imported from @chainlink/contracts-ccip */ + * TODO: split per type once BurnMint ABIs are imported from `@chainlink/contracts-ccip` */ export const TOKEN_POOL_ABIS: Record = { [TokenPoolVersion.V1_5_0]: LockReleaseTokenPool_1_5, [TokenPoolVersion.V1_5_1]: LockReleaseTokenPool_1_5_1, From e2f43376fa4659431693561dc054f9ab1bd474a8 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Tue, 14 Jul 2026 15:08:18 +0100 Subject: [PATCH 06/22] feat(cct-sdk): Add deploy evm token --- ccip-sdk/src/cct/errors.ts | 7 +- ccip-sdk/src/cct/evm/index.test.ts | 26 +++ ccip-sdk/src/cct/evm/index.ts | 54 +++++- ccip-sdk/src/cct/evm/operation.ts | 28 ++- ccip-sdk/src/cct/evm/submit.test.ts | 13 +- ccip-sdk/src/cct/evm/submit.ts | 20 +- ccip-sdk/src/cct/evm/token/bytecode.ts | 14 ++ .../evm/token/operations/deploy-token.test.ts | 178 ++++++++++++++++++ .../cct/evm/token/operations/deploy-token.ts | 69 +++++++ ccip-sdk/src/cct/evm/validate.ts | 42 +++++ ccip-sdk/src/cct/operation.ts | 9 +- 11 files changed, 429 insertions(+), 31 deletions(-) create mode 100644 ccip-sdk/src/cct/evm/token/bytecode.ts create mode 100644 ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts create mode 100644 ccip-sdk/src/cct/evm/token/operations/deploy-token.ts diff --git a/ccip-sdk/src/cct/errors.ts b/ccip-sdk/src/cct/errors.ts index 8acb6fb8..54720bca 100644 --- a/ccip-sdk/src/cct/errors.ts +++ b/ccip-sdk/src/cct/errors.ts @@ -42,9 +42,10 @@ export class CCTParamsInvalidError extends CCIPError { // Transaction submission /** - * Thrown when a CCT write fails before broadcast or the transaction reverts after mining. - * Pre-broadcast failures (signing/RPC) may set `isTransient: true` for network errors; - * on-chain reverts are permanent. Reverts include `context.txHash`. + * Thrown when a CCT write fails before broadcast, the transaction reverts after mining, + * or it mines without the expected effect (e.g. a deployment that produced no contract + * address). Pre-broadcast failures (signing/RPC) may set `isTransient: true` for network + * errors; reverts and post-mining anomalies are permanent and include `context.txHash`. * * @example * ```typescript diff --git a/ccip-sdk/src/cct/evm/index.test.ts b/ccip-sdk/src/cct/evm/index.test.ts index 48b505c9..bcdf801a 100644 --- a/ccip-sdk/src/cct/evm/index.test.ts +++ b/ccip-sdk/src/cct/evm/index.test.ts @@ -21,10 +21,25 @@ function stubChain(overrides: Partial = {}, poolVersion = '1.5.1'): EV logger: { debug() {}, info() {}, warn() {}, error() {} }, getTokenAdminRegistryFor: (_address: string) => Promise.resolve(TAR), typeAndVersion: (_address: string) => Promise.resolve(['BurnMintTokenPool', poolVersion]), + nextNonce: async () => 0, + rollbackNonce: () => {}, ...overrides, } as unknown as EVMChain } +const HASH = '0x' + 'ab'.repeat(32) + +/** Fake ethers Signer whose broadcast resolves to a confirmed receipt. */ +function fakeSigner() { + return { + signTransaction: () => Promise.resolve('0x'), + getAddress: () => Promise.resolve(TOKEN), + populateTransaction: (tx: unknown) => Promise.resolve({ ...(tx as object) }), + sendTransaction: () => + Promise.resolve({ hash: HASH, wait: () => Promise.resolve({ status: 1 }) }), + } +} + const SET_POOL_SELECTOR = id('setPool(address,address)').slice(0, 10) const EXPECTED_DATA = new Interface([ 'function setPool(address localToken, address pool)', @@ -119,6 +134,17 @@ describe('EVMTokenManager (cct/evm)', () => { }) describe('setPool', () => { + it('signs and submits, resolving to the confirmed tx hash', async () => { + const cct = EVMTokenManager.fromChain(stubChain()) + const result = await cct.setPool({ + tokenAddress: TOKEN, + poolAddress: POOL, + address: ROUTER, + wallet: fakeSigner(), + }) + assert.deepEqual(result, { hash: HASH }) + }) + it('rejects a non-signer wallet', async () => { const cct = EVMTokenManager.fromChain(stubChain()) await assert.rejects( diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 36b51655..2ae4243b 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -12,8 +12,9 @@ import type { ChainContext } from '../../chain.ts' import { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' import type { ChainFamily } from '../../networks.ts' -import type { TransactionHash } from '../operation.ts' +import type { DeployResult, TransactionResult } from '../operation.ts' import { TokenManager } from '../token-manager.ts' +import { type DeployTokenParams, DeployToken } from './token/operations/deploy-token.ts' import { type SetPoolParams, SetPool } from './token-admin-registry/operations/set-pool.ts' import { type TransferOwnershipParams, @@ -25,6 +26,7 @@ export class EVMTokenManager extends TokenManager { readonly chain: EVMChain readonly #setPool = new SetPool() readonly #transferOwnership = new TransferOwnership() + readonly #deployToken = new DeployToken() /** Wraps an {@link EVMChain}; prefer the static factory methods. */ constructor(chain: EVMChain) { @@ -91,7 +93,7 @@ export class EVMTokenManager extends TokenManager { * }) * ``` */ - setPool(opts: SetPoolParams & { wallet: unknown }): Promise { + setPool(opts: SetPoolParams & { wallet: unknown }): Promise { return this.#setPool.execute(this.chain, opts) } @@ -113,11 +115,55 @@ export class EVMTokenManager extends TokenManager { * @throws {@link CCTContractVersionUnsupportedError} if the pool version is unsupported * @throws {@link CCTTxFailedError} if the tx reverts or fails */ - transferOwnership(opts: TransferOwnershipParams & { wallet: unknown }): Promise { + transferOwnership( + opts: TransferOwnershipParams & { wallet: unknown }, + ): Promise { return this.#transferOwnership.execute(this.chain, opts) } + + /** + * Builds an unsigned `BurnMintERC677Token` deployment tx (for multisig / offline signing). + * The deployed address is only known once mined, so it is NOT returned here — use + * {@link deployToken} to deploy and receive `{ hash, address }`. + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @example + * ```typescript + * const unsigned = await cct.generateUnsignedDeployToken({ + * name: 'My Token', + * symbol: 'MTK', + * decimals: 18, + * maxSupply: 0n, // 0 = unlimited + * sender: '0xDeployer...', + * }) + * ``` + */ + generateUnsignedDeployToken(opts: DeployTokenParams): Promise { + return this.#deployToken.generate(this.chain, opts) + } + + /** + * Deploys a `BurnMintERC677Token`, signing + submitting with `opts.wallet`; resolves to + * the tx hash and the newly deployed token address. + * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address + * @example + * ```typescript + * const { hash, address } = await cct.deployToken({ + * name: 'My Token', + * symbol: 'MTK', + * decimals: 18, + * maxSupply: 0n, + * wallet, + * }) + * ``` + */ + deployToken(opts: DeployTokenParams & { wallet: unknown }): Promise { + return this.#deployToken.execute(this.chain, opts) + } } export * from '../errors.ts' export type { SetPoolParams } from './token-admin-registry/operations/set-pool.ts' -export type { TransactionHash } from '../operation.ts' +export type { DeployTokenParams } from './token/operations/deploy-token.ts' +export type { DeployResult, TransactionResult } from '../operation.ts' diff --git a/ccip-sdk/src/cct/evm/operation.ts b/ccip-sdk/src/cct/evm/operation.ts index e775ed16..d70cc75d 100644 --- a/ccip-sdk/src/cct/evm/operation.ts +++ b/ccip-sdk/src/cct/evm/operation.ts @@ -1,21 +1,27 @@ /** * EVM {@link Operation} lifecycle: validate → encode → submit. - * Concrete ops implement {@link EVMOperation.encode}; this base wires - * {@link generate} and {@link execute}. + * Concrete ops implement {@link EVMOperation.buildUnsigned}; the base wires + * {@link generate} and {@link execute}. Ops needing more than a tx hash (e.g. a + * deployment's address) override {@link execute}, reusing {@link submit}. * * @packageDocumentation */ import type { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' -import { type TransactionHash, Operation } from '../operation.ts' +import { type TransactionResult, Operation } from '../operation.ts' import { submit } from './submit.ts' -/** EVM CCT write base. Subclasses supply {@link validate} and {@link buildUnsigned}. */ +/** + * EVM CCT write base. Subclasses supply {@link validate} and {@link buildUnsigned}; + * {@link execute} signs and submits, returning the confirmed tx hash. Ops that + * resolve to more (e.g. a deployed address) override {@link execute}. + */ export abstract class EVMOperation

extends Operation< EVMChain, P, - UnsignedEVMTx + UnsignedEVMTx, + TransactionResult > { /** Build calldata into an unsigned tx; versioned ops resolve their encoder here. */ protected abstract buildUnsigned( @@ -31,8 +37,14 @@ export abstract class EVMOperation

extends Operat return unsigned } - /** {@link generate}, then sign and submit via {@link submit}; returns once confirmed. */ - async execute(chain: EVMChain, params: P & { wallet: unknown }): Promise { - return submit(chain, params.wallet, await this.generate(chain, params), this.name) + /** {@link generate}, then sign and submit; returns the confirmed tx hash. */ + async execute(chain: EVMChain, params: P & { wallet: unknown }): Promise { + const { response } = await submit( + chain, + params.wallet, + await this.generate(chain, params), + this.name, + ) + return { hash: response.hash } } } diff --git a/ccip-sdk/src/cct/evm/submit.test.ts b/ccip-sdk/src/cct/evm/submit.test.ts index bc95d9d4..1303341a 100644 --- a/ccip-sdk/src/cct/evm/submit.test.ts +++ b/ccip-sdk/src/cct/evm/submit.test.ts @@ -32,7 +32,7 @@ function stubChain(): EVMChain { * `submitError` makes both send and sign paths reject (pre-broadcast failure). */ function fakeSigner(opts: { - receipt?: { status: number } | null + receipt?: { status: number; contractAddress?: string | null } | null waitError?: Error submitError?: Error }) { @@ -54,15 +54,16 @@ function fakeSigner(opts: { } } -describe('submit (shared CCT submit pipeline)', () => { - it('returns the hash on a successful receipt', async () => { - const result = await submit( +describe('submit (sign-and-confirm pipeline)', () => { + it('returns the broadcast response and mined receipt', async () => { + const { response, receipt } = await submit( stubChain(), - fakeSigner({ receipt: { status: 1 } }), + fakeSigner({ receipt: { status: 1, contractAddress: null } }), UNSIGNED, 'setPool', ) - assert.deepEqual(result, { hash: HASH }) + assert.equal(response.hash, HASH) + assert.equal(receipt.status, 1) }) it('throws CCIPExecTxRevertedError (non-transient) when wait() throws CALL_EXCEPTION', async () => { diff --git a/ccip-sdk/src/cct/evm/submit.ts b/ccip-sdk/src/cct/evm/submit.ts index 4020fae8..7e0c8add 100644 --- a/ccip-sdk/src/cct/evm/submit.ts +++ b/ccip-sdk/src/cct/evm/submit.ts @@ -1,18 +1,23 @@ /** * Shared sign-and-submit pipeline for EVM CCT operations. Maps broadcast and * confirmation failures to {@link CCTTxFailedError} / {@link CCTTxNotConfirmedError}, - * and on-chain reverts to {@link CCIPExecTxRevertedError}. + * and on-chain reverts to {@link CCIPExecTxRevertedError}. Operations map the + * confirmed `{ response, receipt }` to their own result shape. * * @packageDocumentation */ -import { type TransactionRequest, type TransactionResponse, isError } from 'ethers' +import { + type TransactionReceipt, + type TransactionRequest, + type TransactionResponse, + isError, +} from 'ethers' import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../errors/index.ts' import { type EVMChain, isSigner, submitTransaction } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' import { CCTTxFailedError, CCTTxNotConfirmedError } from '../errors.ts' -import type { TransactionHash } from '../operation.ts' /** Max ms to wait for one confirmation before throwing {@link CCTTxNotConfirmedError}. */ const CONFIRM_TIMEOUT_MS = 60_000 @@ -26,7 +31,8 @@ function isTransientError(error: unknown): boolean { /** * Signs and submits the first transaction in `unsigned`, then waits for one confirmation. - * `operation` labels logs and error context. + * Returns the broadcast `response` and mined `receipt`; callers map these to their + * own result shape (see {@link EVMOperation.execute}). * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTTxFailedError} if submission fails before broadcast * @throws {@link CCIPExecTxRevertedError} if the tx reverts on-chain @@ -37,7 +43,7 @@ export async function submit( wallet: unknown, unsigned: UnsignedEVMTx, operation: string, -): Promise { +): Promise<{ response: TransactionResponse; receipt: TransactionReceipt }> { if (!isSigner(wallet)) throw new CCIPWalletInvalidError(wallet) const sender = await wallet.getAddress() chain.logger.debug(`${operation}: submitting...`) @@ -64,7 +70,7 @@ export async function submit( chain.logger.debug(`${operation}: waiting for confirmation, tx =`, response.hash) - let receipt + let receipt: TransactionReceipt | null try { receipt = await response.wait(1, CONFIRM_TIMEOUT_MS) } catch (error) { @@ -82,5 +88,5 @@ export async function submit( if (!receipt) throw new CCTTxNotConfirmedError(operation, response.hash) chain.logger.info(`${operation}: confirmed, tx =`, response.hash) - return { hash: response.hash } + return { response, receipt } } diff --git a/ccip-sdk/src/cct/evm/token/bytecode.ts b/ccip-sdk/src/cct/evm/token/bytecode.ts new file mode 100644 index 00000000..026b8472 --- /dev/null +++ b/ccip-sdk/src/cct/evm/token/bytecode.ts @@ -0,0 +1,14 @@ +/** + * Creation bytecode (init-code) for `BurnMintERC677Token` v1.5.1, paired with the + * ABI in `evm/abi/BurnMintERC677Token.ts` (same gethwrapper origin). ABI-encoded + * constructor args append directly to this to form a deployment transaction. + * + * @packageDocumentation + */ + +// generate: +// fetch('https://github.com/smartcontractkit/ccip/raw/release/contracts-ccip-1.5.1/core/gethwrappers/generated/burn_mint_erc677/burn_mint_erc677.go') +// .then((res) => res.text()) +// .then((body) => body.match(/^\s*Bin: "(0x[0-9a-fA-F]+)",$/m)?.[1]) +export const BURN_MINT_ERC677_BYTECODE = + '0x60c06040523480156200001157600080fd5b50604051620022dd380380620022dd833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611e4c6200049160003960008181610447015281816108c301526108ed015260006102710152611e4c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd6231461046b578063dd62ed3e1461047e578063f2fde38b146104c4578063f81094f3146104d757600080fd5b8063c2e3273d1461040c578063c630948d1461041f578063c64d0ebc14610432578063d5abeb011461044557600080fd5b80639dc29fac116100de5780639dc29fac146103c0578063a457c2d7146103d3578063a9059cbb146103e6578063aa271e1a146103f957600080fd5b806379cc67901461037557806386fe8b43146103885780638da5cb5b1461039057806395d89b41146103b857600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036d57600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046119b9565b6104ea565b60405190151581526020015b60405180910390f35b61022561061b565b6040516102149190611a5f565b610208610240366004611a9b565b6106ad565b6002545b604051908152602001610214565b610208610265366004611ac5565b6106c5565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611a9b565b6106e9565b6102086102bc366004611b30565b610735565b6102d46102cf366004611a9b565b610858565b005b6102d46102e4366004611c19565b61097f565b6102086102f7366004611c32565b6109cc565b6102d461030a366004611c32565b6109d9565b61020861031d366004611a9b565b610a35565b61032a610a48565b6040516102149190611c4d565b610249610345366004611c32565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102d4610a59565b6102d4610383366004611a9b565b610b5a565b61032a610ba9565b60055460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b610225610bb5565b6102d46103ce366004611a9b565b610bc4565b6102086103e1366004611a9b565b610bce565b6102086103f4366004611a9b565b610c9f565b610208610407366004611c32565b610cad565b6102d461041a366004611c32565b610cba565b6102d461042d366004611c32565b610d16565b6102d4610440366004611c32565b610d24565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d4610479366004611a9b565b610d80565b61024961048c366004611ca7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6102d46104d2366004611c32565b610d8a565b6102d46104e5366004611c32565b610d9b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f36372b0700000000000000000000000000000000000000000000000000000000148061057d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4000aea000000000000000000000000000000000000000000000000000000000145b806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fe6599b4d00000000000000000000000000000000000000000000000000000000145b8061061557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60606003805461062a90611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461065690611cda565b80156106a35780601f10610678576101008083540402835291602001916106a3565b820191906000526020600020905b81548152906001019060200180831161068657829003601f168201915b5050505050905090565b6000336106bb818585610df7565b5060019392505050565b6000336106d3858285610e2b565b6106de858585610efc565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906106bb9082908690610730908790611d5c565b610df7565b60006107418484610c9f565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1685856040516107a1929190611d6f565b60405180910390a373ffffffffffffffffffffffffffffffffffffffff84163b156106bb576040517fa4c0ed3600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063a4c0ed369061081c90339087908790600401611d90565b600060405180830381600087803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b505050505060019392505050565b61086133610cad565b61089e576040517fe2c8c9d50000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b813073ffffffffffffffffffffffffffffffffffffffff8216036108c157600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061092257507f00000000000000000000000000000000000000000000000000000000000000008261091660025490565b6109209190611d5c565b115b15610970578161093160025490565b61093b9190611d5c565b6040517fcbbf111300000000000000000000000000000000000000000000000000000000815260040161089591815260200190565b61097a8383610f2a565b505050565b610988336109cc565b6109c0576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b6109c98161101d565b50565b6000610615600983611027565b6109e1611056565b6109ec6009826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b6000610a418383610bce565b9392505050565b6060610a5460076110fb565b905090565b60065473ffffffffffffffffffffffffffffffffffffffff163314610ada576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610895565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560068054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610b63336109cc565b610b9b576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b610ba58282611108565b5050565b6060610a5460096110fb565b60606004805461062a90611cda565b610ba58282610b5a565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610895565b6106de8286868403610df7565b6000336106bb818585610efc565b6000610615600783611027565b610cc2611056565b610ccd60078261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610d1f81610cba565b6109c9815b610d2c611056565b610d3760098261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b61097a82826106e9565b610d92611056565b6109c98161113f565b610da3611056565b610dae6007826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b813073ffffffffffffffffffffffffffffffffffffffff821603610e1a57600080fd5b610e25848484611235565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610e255781811015610eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610895565b610e258484848403610df7565b813073ffffffffffffffffffffffffffffffffffffffff821603610f1f57600080fd5b610e258484846113e8565b73ffffffffffffffffffffffffffffffffffffffff8216610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610895565b8060026000828254610fb99190611d5c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6109c93382611657565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610a41565b60055473ffffffffffffffffffffffffffffffffffffffff1633146110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610895565b565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661181b565b60606000610a418361190e565b611113823383610e2b565b610ba58282611657565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661196a565b3373ffffffffffffffffffffffffffffffffffffffff8216036111be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610895565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b73ffffffffffffffffffffffffffffffffffffffff83166112d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661137a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661148b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661152e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054818110156115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610e25565b73ffffffffffffffffffffffffffffffffffffffff82166116fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156117b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561190457600061183f600183611dce565b855490915060009061185390600190611dce565b90508181146118b857600086600001828154811061187357611873611de1565b906000526020600020015490508087600001848154811061189657611896611de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118c9576118c9611e10565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610615565b6000915050610615565b60608160000180548060200260200160405190810160405280929190818152602001828054801561195e57602002820191906000526020600020905b81548152602001906001019080831161194a575b50505050509050919050565b60008181526001830160205260408120546119b157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610615565b506000610615565b6000602082840312156119cb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a4157600080fd5b6000815180845260005b81811015611a2157602081850181015186830182015201611a05565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610a4160208301846119fb565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a9657600080fd5b919050565b60008060408385031215611aae57600080fd5b611ab783611a72565b946020939093013593505050565b600080600060608486031215611ada57600080fd5b611ae384611a72565b9250611af160208501611a72565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080600060608486031215611b4557600080fd5b611b4e84611a72565b925060208401359150604084013567ffffffffffffffff80821115611b7257600080fd5b818601915086601f830112611b8657600080fd5b813581811115611b9857611b98611b01565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611bde57611bde611b01565b81604052828152896020848701011115611bf757600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b600060208284031215611c2b57600080fd5b5035919050565b600060208284031215611c4457600080fd5b610a4182611a72565b6020808252825182820181905260009190848201906040850190845b81811015611c9b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611c69565b50909695505050505050565b60008060408385031215611cba57600080fd5b611cc383611a72565b9150611cd160208401611a72565b90509250929050565b600181811c90821680611cee57607f821691505b602082108103611d27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561061557610615611d2d565b828152604060208201526000611d8860408301846119fb565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611dc560608301846119fb565b95945050505050565b8181038181111561061557610615611d2d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a' as const diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts new file mode 100644 index 00000000..831b88c7 --- /dev/null +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts @@ -0,0 +1,178 @@ +import assert from 'node:assert/strict' +import { describe, it } from 'node:test' + +import { makeError } from 'ethers' + +import { DeployToken } from './deploy-token.ts' +import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../errors/index.ts' +import type { EVMChain } from '../../../../evm/index.ts' +import { ChainFamily } from '../../../../networks.ts' +import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' +import { BURN_MINT_ERC677_BYTECODE } from '../bytecode.ts' + +const SENDER = '0x' + '11'.repeat(20) +const DEPLOYED = '0x' + '77'.repeat(20) +const HASH = '0x' + 'ab'.repeat(32) + +// Golden vector: pinned constructor-arg encoding for the fixed inputs below. Independent of +// the SDK encoder — guards the init-code (bytecode + BurnMintERC677 constructor) against drift. +const INPUTS = { name: 'CCIP Test Token', symbol: 'CCIPT', decimals: 18, maxSupply: 0n } +const EXPECTED_CTOR_ARGS = + '0000000000000000000000000000000000000000000000000000000000000080' + + '00000000000000000000000000000000000000000000000000000000000000c0' + + '0000000000000000000000000000000000000000000000000000000000000012' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '000000000000000000000000000000000000000000000000000000000000000f' + + '43434950205465737420546f6b656e0000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000005' + + '4343495054000000000000000000000000000000000000000000000000000000' +const EXPECTED_DEPLOY_DATA = BURN_MINT_ERC677_BYTECODE + EXPECTED_CTOR_ARGS + +/** Minimal EVMChain stub — deployToken's build path ignores it; execute uses only these. */ +function stubChain(): EVMChain { + return { + provider: {} as never, + logger: { debug() {}, info() {}, warn() {}, error() {} }, + nextNonce: async () => 0, + rollbackNonce: () => {}, + } as unknown as EVMChain +} + +/** Fake ethers Signer whose deployment receipt carries `contractAddress`. */ +function fakeSigner(opts: { + contractAddress?: string | null + waitError?: Error +}) { + return { + signTransaction: () => Promise.resolve('0x'), + getAddress: () => Promise.resolve(SENDER), + populateTransaction: (tx: unknown) => Promise.resolve({ ...(tx as object) }), + sendTransaction: () => + Promise.resolve({ + hash: HASH, + wait: () => + opts.waitError + ? Promise.reject(opts.waitError) + : Promise.resolve({ + status: 1, + contractAddress: + opts.contractAddress === undefined ? DEPLOYED : opts.contractAddress, + }), + }), + } +} + +describe('DeployToken (cct/evm token operation)', () => { + describe('generate', () => { + it('builds a deployment as init-code with no `to` (golden vector)', async () => { + const unsigned = await new DeployToken().generate(stubChain(), { ...INPUTS, sender: SENDER }) + + assert.equal(unsigned.family, ChainFamily.EVM) + assert.equal(unsigned.transactions.length, 1) + + const tx = unsigned.transactions[0]! + assert.equal(tx.to, undefined, 'deployment tx has no `to`') + assert.equal(tx.from, SENDER) + assert.ok( + tx.data!.startsWith(BURN_MINT_ERC677_BYTECODE), + 'data starts with creation bytecode', + ) + assert.equal(tx.data, EXPECTED_DEPLOY_DATA) + }) + + it('omits `from` when no sender is given', async () => { + const unsigned = await new DeployToken().generate(stubChain(), INPUTS) + assert.equal(unsigned.transactions[0]!.from, undefined) + }) + + it('rejects an empty name, tagged with the operation and param', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, name: '' }), + (err: unknown) => + err instanceof CCTParamsInvalidError && + err.context.operation === 'deployToken' && + err.context.param === 'name', + ) + }) + + it('rejects an empty symbol', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, symbol: '' }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'symbol', + ) + }) + + it('rejects decimals outside 0–255', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, decimals: 256 }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'decimals', + ) + }) + + it('rejects a non-integer decimals', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, decimals: 1.5 }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'decimals', + ) + }) + + it('rejects a negative maxSupply', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, maxSupply: -1n }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'maxSupply', + ) + }) + + it('rejects a maxSupply above uint256 max', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, maxSupply: 2n ** 256n }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'maxSupply', + ) + }) + }) + + describe('execute', () => { + it('deploys and returns the tx hash and deployed address', async () => { + const result = await new DeployToken().execute(stubChain(), { + ...INPUTS, + wallet: fakeSigner({ contractAddress: DEPLOYED }), + }) + assert.deepEqual(result, { hash: HASH, address: DEPLOYED }) + }) + + it('throws CCTTxFailedError when the receipt carries no contract address', async () => { + await assert.rejects( + () => + new DeployToken().execute(stubChain(), { + ...INPUTS, + wallet: fakeSigner({ contractAddress: null }), + }), + (err: unknown) => + err instanceof CCTTxFailedError && + err.context.operation === 'deployToken' && + !err.isTransient, + ) + }) + + it('throws CCIPExecTxRevertedError when the deployment reverts on-chain', async () => { + await assert.rejects( + () => + new DeployToken().execute(stubChain(), { + ...INPUTS, + wallet: fakeSigner({ waitError: makeError('execution reverted', 'CALL_EXCEPTION') }), + }), + (err: unknown) => + err instanceof CCIPExecTxRevertedError && + err.context.operation === 'deployToken' && + err.context.txHash === HASH, + ) + }) + + it('rejects a non-signer wallet', async () => { + await assert.rejects( + () => new DeployToken().execute(stubChain(), { ...INPUTS, wallet: {} }), + (err: unknown) => err instanceof CCIPWalletInvalidError, + ) + }) + }) +}) diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts new file mode 100644 index 00000000..adeb849c --- /dev/null +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts @@ -0,0 +1,69 @@ +/** + * deployToken — deploys a `BurnMintERC677Token` (v1.5.1) via raw init-code. + * The tx has no `to`; `execute` returns the deployed contract address. + * + * @packageDocumentation + */ + +import { interfaces } from '../../../../evm/const.ts' +import type { EVMChain } from '../../../../evm/index.ts' +import type { UnsignedEVMTx } from '../../../../evm/types.ts' +import { ChainFamily } from '../../../../networks.ts' +import { CCTTxFailedError } from '../../../errors.ts' +import type { DeployResult } from '../../../operation.ts' +import { EVMOperation } from '../../operation.ts' +import { submit } from '../../submit.ts' +import { validateNonEmptyString, validateUint256, validateUint8 } from '../../validate.ts' +import { BURN_MINT_ERC677_BYTECODE } from '../bytecode.ts' + +/** Parameters for {@link DeployToken}. */ +export interface DeployTokenParams { + name: string + symbol: string + decimals: number + /** Max supply cap; `0n` means unlimited. */ + maxSupply: bigint + sender?: string +} + +/** Deploys a `BurnMintERC677Token`; `execute` resolves to `{ hash, address }`. */ +export class DeployToken extends EVMOperation { + readonly name = 'deployToken' + + /** Validates the constructor params before building init-code. */ + protected validate({ name, symbol, decimals, maxSupply }: DeployTokenParams): void { + validateNonEmptyString(this.name, 'name', name) + validateNonEmptyString(this.name, 'symbol', symbol) + validateUint8(this.name, 'decimals', decimals) + validateUint256(this.name, 'maxSupply', maxSupply) + } + + /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ + protected buildUnsigned(_chain: EVMChain, p: DeployTokenParams): UnsignedEVMTx { + const args = interfaces.Token.encodeDeploy([p.name, p.symbol, p.decimals, p.maxSupply]) + const data = BURN_MINT_ERC677_BYTECODE + args.slice(2) + return { family: ChainFamily.EVM, transactions: [{ data }] } + } + + /** + * {@link generate}, then sign and submit; resolves to the tx hash and the newly + * deployed contract address (read from the mined receipt). + * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address + */ + override async execute( + chain: EVMChain, + params: DeployTokenParams & { wallet: unknown }, + ): Promise { + const { response, receipt } = await submit( + chain, + params.wallet, + await this.generate(chain, params), + this.name, + ) + if (!receipt.contractAddress) + throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { + context: { txHash: response.hash }, + }) + return { hash: response.hash, address: receipt.contractAddress } + } +} diff --git a/ccip-sdk/src/cct/evm/validate.ts b/ccip-sdk/src/cct/evm/validate.ts index 1d8bbc68..279f2e2a 100644 --- a/ccip-sdk/src/cct/evm/validate.ts +++ b/ccip-sdk/src/cct/evm/validate.ts @@ -28,3 +28,45 @@ export function validateAddress(operation: string, param: string, value: unknown }, ) } + +/** + * Asserts `value` is a non-empty (non-blank) string. + * @throws {@link CCTParamsInvalidError} if `value` is not a non-empty string + */ +export function validateNonEmptyString(operation: string, param: string, value: unknown): void { + if (typeof value === 'string' && value.trim().length > 0) return + throw new CCTParamsInvalidError( + operation, + param, + `must be a non-empty string, got ${String(value)}`, + ) +} + +/** + * Asserts `value` is an integer in `[0, 255]` (a Solidity `uint8`). + * @throws {@link CCTParamsInvalidError} if `value` is not such an integer + */ +export function validateUint8(operation: string, param: string, value: unknown): void { + if (typeof value === 'number' && Number.isInteger(value) && value >= 0 && value <= 255) return + throw new CCTParamsInvalidError( + operation, + param, + `must be an integer in [0, 255], got ${String(value)}`, + ) +} + +/** Largest value representable by a Solidity `uint256`. */ +const UINT256_MAX = BigInt(2) ** BigInt(256) - 1n + +/** + * Asserts `value` is a `bigint` in `[0, 2^256 − 1]` (a Solidity `uint256`). + * @throws {@link CCTParamsInvalidError} if `value` is not such a bigint + */ +export function validateUint256(operation: string, param: string, value: unknown): void { + if (typeof value === 'bigint' && value >= 0n && value <= UINT256_MAX) return + throw new CCTParamsInvalidError( + operation, + param, + `must be a bigint in [0, 2^256 − 1], got ${String(value)}`, + ) +} diff --git a/ccip-sdk/src/cct/operation.ts b/ccip-sdk/src/cct/operation.ts index d29e9b9d..a54ea9bd 100644 --- a/ccip-sdk/src/cct/operation.ts +++ b/ccip-sdk/src/cct/operation.ts @@ -7,14 +7,17 @@ import type { ChainTransaction } from '../types.ts' -/** Confirmed on-chain hash returned by a successful CCT write. */ -export type TransactionHash = Pick +/** Result of a successful CCT write: the confirmed on-chain tx hash. */ +export type TransactionResult = Pick + +/** Result of a successful contract-deployment write: the tx hash plus the deployed address. */ +export type DeployResult = TransactionResult & { address: string } /** * Abstract CCT write operation: build unsigned tx(s) with {@link generate}, or * sign and submit with {@link execute}. */ -export abstract class Operation { +export abstract class Operation { /** camelCase id; matches the token-manager facade method and error context. */ abstract readonly name: string /** Reject invalid params before any chain RPC. */ From ca537a7ecf458bc97c8e85248fc65dacd4089f66 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Wed, 15 Jul 2026 12:49:41 +0100 Subject: [PATCH 07/22] Address PR comments --- ccip-cli/src/index.ts | 2 +- ccip-sdk/src/api/index.ts | 2 +- ccip-sdk/src/cct/evm/index.ts | 7 ++++--- .../src/cct/evm/token/operations/deploy-token.test.ts | 7 ++----- ccip-sdk/src/cct/evm/token/operations/deploy-token.ts | 5 ++++- ccip-sdk/src/cct/operation.ts | 8 ++++++-- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/ccip-cli/src/index.ts b/ccip-cli/src/index.ts index 20bb80e9..1d870e54 100755 --- a/ccip-cli/src/index.ts +++ b/ccip-cli/src/index.ts @@ -28,7 +28,7 @@ Error.stackTraceLimit = 50 // show more stack frames for better debugging // generate:nofail // `const VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -const VERSION = '1.10.2-659a810' +const VERSION = '1.10.2-e2f4337' // generate:end const require = createRequire(import.meta.url) diff --git a/ccip-sdk/src/api/index.ts b/ccip-sdk/src/api/index.ts index 8674ca66..c0439c5c 100644 --- a/ccip-sdk/src/api/index.ts +++ b/ccip-sdk/src/api/index.ts @@ -62,7 +62,7 @@ export const DEFAULT_TIMEOUT_MS = 30000 /** SDK version string for telemetry header */ // generate:nofail // `export const SDK_VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -export const SDK_VERSION = '1.10.2-659a810' +export const SDK_VERSION = '1.10.2-e2f4337' // generate:end /** SDK telemetry header name */ diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 2ae4243b..9fe89a9f 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -124,7 +124,7 @@ export class EVMTokenManager extends TokenManager { /** * Builds an unsigned `BurnMintERC677Token` deployment tx (for multisig / offline signing). * The deployed address is only known once mined, so it is NOT returned here — use - * {@link deployToken} to deploy and receive `{ hash, address }`. + * {@link deployToken} to deploy and receive `{ hash, contractAddress }`. * @throws {@link CCTParamsInvalidError} if any param is invalid * @example * ```typescript @@ -143,13 +143,14 @@ export class EVMTokenManager extends TokenManager { /** * Deploys a `BurnMintERC677Token`, signing + submitting with `opts.wallet`; resolves to - * the tx hash and the newly deployed token address. + * the tx hash and the newly deployed token address. Deploys with zero supply and no roles + * granted — call `grantMintAndBurnRoles` before `mint`, or it reverts on access control. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address * @example * ```typescript - * const { hash, address } = await cct.deployToken({ + * const { hash, contractAddress } = await cct.deployToken({ * name: 'My Token', * symbol: 'MTK', * decimals: 18, diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts index 831b88c7..63d02600 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts @@ -39,10 +39,7 @@ function stubChain(): EVMChain { } /** Fake ethers Signer whose deployment receipt carries `contractAddress`. */ -function fakeSigner(opts: { - contractAddress?: string | null - waitError?: Error -}) { +function fakeSigner(opts: { contractAddress?: string | null; waitError?: Error }) { return { signTransaction: () => Promise.resolve('0x'), getAddress: () => Promise.resolve(SENDER), @@ -137,7 +134,7 @@ describe('DeployToken (cct/evm token operation)', () => { ...INPUTS, wallet: fakeSigner({ contractAddress: DEPLOYED }), }) - assert.deepEqual(result, { hash: HASH, address: DEPLOYED }) + assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) }) it('throws CCTTxFailedError when the receipt carries no contract address', async () => { diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts index adeb849c..78a8b23f 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts @@ -63,7 +63,10 @@ export class DeployToken extends EVMOperation { if (!receipt.contractAddress) throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { context: { txHash: response.hash }, + // override the default CCT_TX_FAILED hint to point tx has mined but receipt carried no address + recovery: + 'Deployment mined but the receipt carried no contract address; re-fetch it by tx hash or retry against a different RPC.', }) - return { hash: response.hash, address: receipt.contractAddress } + return { hash: response.hash, contractAddress: receipt.contractAddress } } } diff --git a/ccip-sdk/src/cct/operation.ts b/ccip-sdk/src/cct/operation.ts index a54ea9bd..bbc6fd2f 100644 --- a/ccip-sdk/src/cct/operation.ts +++ b/ccip-sdk/src/cct/operation.ts @@ -10,8 +10,12 @@ import type { ChainTransaction } from '../types.ts' /** Result of a successful CCT write: the confirmed on-chain tx hash. */ export type TransactionResult = Pick -/** Result of a successful contract-deployment write: the tx hash plus the deployed address. */ -export type DeployResult = TransactionResult & { address: string } +/** + * Result of a successful deployment write: the tx hash plus the deployed contract address (token, pool, etc.) + * Note: No block-explorer verification handle yet; it's recoverable from the init-code, + * so it can be added later without a breaking change. + */ +export type DeployResult = TransactionResult & { contractAddress: string } /** * Abstract CCT write operation: build unsigned tx(s) with {@link generate}, or From 8e50efc62588b35f252fadc910f7431c13b42f4c Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Thu, 16 Jul 2026 11:33:25 +0100 Subject: [PATCH 08/22] Address PR comments by fixing chain-specific types --- ccip-cli/src/index.ts | 2 +- ccip-sdk/src/api/index.ts | 2 +- ccip-sdk/src/cct/evm/index.ts | 14 +++++++------- ccip-sdk/src/cct/evm/operation.ts | 14 ++++++++++++-- ccip-sdk/src/cct/evm/token/bytecode.ts | 3 ++- .../src/cct/evm/token/operations/deploy-token.ts | 5 ++--- ccip-sdk/src/cct/operation.ts | 11 +++++------ 7 files changed, 30 insertions(+), 21 deletions(-) diff --git a/ccip-cli/src/index.ts b/ccip-cli/src/index.ts index 1d870e54..bfde8466 100755 --- a/ccip-cli/src/index.ts +++ b/ccip-cli/src/index.ts @@ -28,7 +28,7 @@ Error.stackTraceLimit = 50 // show more stack frames for better debugging // generate:nofail // `const VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -const VERSION = '1.10.2-e2f4337' +const VERSION = '1.10.2-ca537a7' // generate:end const require = createRequire(import.meta.url) diff --git a/ccip-sdk/src/api/index.ts b/ccip-sdk/src/api/index.ts index c0439c5c..1a9af743 100644 --- a/ccip-sdk/src/api/index.ts +++ b/ccip-sdk/src/api/index.ts @@ -62,7 +62,7 @@ export const DEFAULT_TIMEOUT_MS = 30000 /** SDK version string for telemetry header */ // generate:nofail // `export const SDK_VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -export const SDK_VERSION = '1.10.2-e2f4337' +export const SDK_VERSION = '1.10.2-ca537a7' // generate:end /** SDK telemetry header name */ diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 9fe89a9f..0c96ef8c 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -12,8 +12,9 @@ import type { ChainContext } from '../../chain.ts' import { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' import type { ChainFamily } from '../../networks.ts' -import type { DeployResult, TransactionResult } from '../operation.ts' +import type { TransactionResult } from '../operation.ts' import { TokenManager } from '../token-manager.ts' +import type { DeployResult, EVMExecuteParams } from './operation.ts' import { type DeployTokenParams, DeployToken } from './token/operations/deploy-token.ts' import { type SetPoolParams, SetPool } from './token-admin-registry/operations/set-pool.ts' import { @@ -93,7 +94,7 @@ export class EVMTokenManager extends TokenManager { * }) * ``` */ - setPool(opts: SetPoolParams & { wallet: unknown }): Promise { + setPool(opts: EVMExecuteParams): Promise { return this.#setPool.execute(this.chain, opts) } @@ -115,9 +116,7 @@ export class EVMTokenManager extends TokenManager { * @throws {@link CCTContractVersionUnsupportedError} if the pool version is unsupported * @throws {@link CCTTxFailedError} if the tx reverts or fails */ - transferOwnership( - opts: TransferOwnershipParams & { wallet: unknown }, - ): Promise { + transferOwnership(opts: EVMExecuteParams): Promise { return this.#transferOwnership.execute(this.chain, opts) } @@ -159,7 +158,7 @@ export class EVMTokenManager extends TokenManager { * }) * ``` */ - deployToken(opts: DeployTokenParams & { wallet: unknown }): Promise { + deployToken(opts: EVMExecuteParams): Promise { return this.#deployToken.execute(this.chain, opts) } } @@ -167,4 +166,5 @@ export class EVMTokenManager extends TokenManager { export * from '../errors.ts' export type { SetPoolParams } from './token-admin-registry/operations/set-pool.ts' export type { DeployTokenParams } from './token/operations/deploy-token.ts' -export type { DeployResult, TransactionResult } from '../operation.ts' +export type { TransactionResult } from '../operation.ts' +export type { DeployResult, EVMExecuteParams } from './operation.ts' diff --git a/ccip-sdk/src/cct/evm/operation.ts b/ccip-sdk/src/cct/evm/operation.ts index d70cc75d..09feb956 100644 --- a/ccip-sdk/src/cct/evm/operation.ts +++ b/ccip-sdk/src/cct/evm/operation.ts @@ -9,9 +9,19 @@ import type { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' -import { type TransactionResult, Operation } from '../operation.ts' +import { type ExecuteParams, type TransactionResult, Operation } from '../operation.ts' import { submit } from './submit.ts' +/** EVM {@link ExecuteParams} — EVM ops need nothing beyond the signing `wallet`. */ +export type EVMExecuteParams

= ExecuteParams

+ +/** + * Result of a successful EVM deployment write: the tx hash plus the deployed + * contract address (token, pool, etc.). No block-explorer verification handle + * yet; it's recoverable from the init-code, so adding one later is non-breaking. + */ +export type DeployResult = TransactionResult & { contractAddress: string } + /** * EVM CCT write base. Subclasses supply {@link validate} and {@link buildUnsigned}; * {@link execute} signs and submits, returning the confirmed tx hash. Ops that @@ -38,7 +48,7 @@ export abstract class EVMOperation

extends Operat } /** {@link generate}, then sign and submit; returns the confirmed tx hash. */ - async execute(chain: EVMChain, params: P & { wallet: unknown }): Promise { + async execute(chain: EVMChain, params: EVMExecuteParams

): Promise { const { response } = await submit( chain, params.wallet, diff --git a/ccip-sdk/src/cct/evm/token/bytecode.ts b/ccip-sdk/src/cct/evm/token/bytecode.ts index 026b8472..57192207 100644 --- a/ccip-sdk/src/cct/evm/token/bytecode.ts +++ b/ccip-sdk/src/cct/evm/token/bytecode.ts @@ -9,6 +9,7 @@ // generate: // fetch('https://github.com/smartcontractkit/ccip/raw/release/contracts-ccip-1.5.1/core/gethwrappers/generated/burn_mint_erc677/burn_mint_erc677.go') // .then((res) => res.text()) -// .then((body) => body.match(/^\s*Bin: "(0x[0-9a-fA-F]+)",$/m)?.[1]) +// .then((body) => `export const BURN_MINT_ERC677_BYTECODE = '${body.match(/^\s*Bin: "(0x[0-9a-fA-F]+)",$/m)?.[1]}' as const`) export const BURN_MINT_ERC677_BYTECODE = '0x60c06040523480156200001157600080fd5b50604051620022dd380380620022dd833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611e4c6200049160003960008181610447015281816108c301526108ed015260006102710152611e4c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd6231461046b578063dd62ed3e1461047e578063f2fde38b146104c4578063f81094f3146104d757600080fd5b8063c2e3273d1461040c578063c630948d1461041f578063c64d0ebc14610432578063d5abeb011461044557600080fd5b80639dc29fac116100de5780639dc29fac146103c0578063a457c2d7146103d3578063a9059cbb146103e6578063aa271e1a146103f957600080fd5b806379cc67901461037557806386fe8b43146103885780638da5cb5b1461039057806395d89b41146103b857600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036d57600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046119b9565b6104ea565b60405190151581526020015b60405180910390f35b61022561061b565b6040516102149190611a5f565b610208610240366004611a9b565b6106ad565b6002545b604051908152602001610214565b610208610265366004611ac5565b6106c5565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611a9b565b6106e9565b6102086102bc366004611b30565b610735565b6102d46102cf366004611a9b565b610858565b005b6102d46102e4366004611c19565b61097f565b6102086102f7366004611c32565b6109cc565b6102d461030a366004611c32565b6109d9565b61020861031d366004611a9b565b610a35565b61032a610a48565b6040516102149190611c4d565b610249610345366004611c32565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102d4610a59565b6102d4610383366004611a9b565b610b5a565b61032a610ba9565b60055460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b610225610bb5565b6102d46103ce366004611a9b565b610bc4565b6102086103e1366004611a9b565b610bce565b6102086103f4366004611a9b565b610c9f565b610208610407366004611c32565b610cad565b6102d461041a366004611c32565b610cba565b6102d461042d366004611c32565b610d16565b6102d4610440366004611c32565b610d24565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d4610479366004611a9b565b610d80565b61024961048c366004611ca7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6102d46104d2366004611c32565b610d8a565b6102d46104e5366004611c32565b610d9b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f36372b0700000000000000000000000000000000000000000000000000000000148061057d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4000aea000000000000000000000000000000000000000000000000000000000145b806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fe6599b4d00000000000000000000000000000000000000000000000000000000145b8061061557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60606003805461062a90611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461065690611cda565b80156106a35780601f10610678576101008083540402835291602001916106a3565b820191906000526020600020905b81548152906001019060200180831161068657829003601f168201915b5050505050905090565b6000336106bb818585610df7565b5060019392505050565b6000336106d3858285610e2b565b6106de858585610efc565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906106bb9082908690610730908790611d5c565b610df7565b60006107418484610c9f565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1685856040516107a1929190611d6f565b60405180910390a373ffffffffffffffffffffffffffffffffffffffff84163b156106bb576040517fa4c0ed3600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063a4c0ed369061081c90339087908790600401611d90565b600060405180830381600087803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b505050505060019392505050565b61086133610cad565b61089e576040517fe2c8c9d50000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b813073ffffffffffffffffffffffffffffffffffffffff8216036108c157600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061092257507f00000000000000000000000000000000000000000000000000000000000000008261091660025490565b6109209190611d5c565b115b15610970578161093160025490565b61093b9190611d5c565b6040517fcbbf111300000000000000000000000000000000000000000000000000000000815260040161089591815260200190565b61097a8383610f2a565b505050565b610988336109cc565b6109c0576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b6109c98161101d565b50565b6000610615600983611027565b6109e1611056565b6109ec6009826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b6000610a418383610bce565b9392505050565b6060610a5460076110fb565b905090565b60065473ffffffffffffffffffffffffffffffffffffffff163314610ada576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610895565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560068054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610b63336109cc565b610b9b576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b610ba58282611108565b5050565b6060610a5460096110fb565b60606004805461062a90611cda565b610ba58282610b5a565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610895565b6106de8286868403610df7565b6000336106bb818585610efc565b6000610615600783611027565b610cc2611056565b610ccd60078261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610d1f81610cba565b6109c9815b610d2c611056565b610d3760098261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b61097a82826106e9565b610d92611056565b6109c98161113f565b610da3611056565b610dae6007826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b813073ffffffffffffffffffffffffffffffffffffffff821603610e1a57600080fd5b610e25848484611235565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610e255781811015610eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610895565b610e258484848403610df7565b813073ffffffffffffffffffffffffffffffffffffffff821603610f1f57600080fd5b610e258484846113e8565b73ffffffffffffffffffffffffffffffffffffffff8216610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610895565b8060026000828254610fb99190611d5c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6109c93382611657565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610a41565b60055473ffffffffffffffffffffffffffffffffffffffff1633146110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610895565b565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661181b565b60606000610a418361190e565b611113823383610e2b565b610ba58282611657565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661196a565b3373ffffffffffffffffffffffffffffffffffffffff8216036111be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610895565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b73ffffffffffffffffffffffffffffffffffffffff83166112d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661137a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661148b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661152e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054818110156115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610e25565b73ffffffffffffffffffffffffffffffffffffffff82166116fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156117b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561190457600061183f600183611dce565b855490915060009061185390600190611dce565b90508181146118b857600086600001828154811061187357611873611de1565b906000526020600020015490508087600001848154811061189657611896611de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118c9576118c9611e10565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610615565b6000915050610615565b60608160000180548060200260200160405190810160405280929190818152602001828054801561195e57602002820191906000526020600020905b81548152602001906001019080831161194a575b50505050509050919050565b60008181526001830160205260408120546119b157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610615565b506000610615565b6000602082840312156119cb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a4157600080fd5b6000815180845260005b81811015611a2157602081850181015186830182015201611a05565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610a4160208301846119fb565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a9657600080fd5b919050565b60008060408385031215611aae57600080fd5b611ab783611a72565b946020939093013593505050565b600080600060608486031215611ada57600080fd5b611ae384611a72565b9250611af160208501611a72565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080600060608486031215611b4557600080fd5b611b4e84611a72565b925060208401359150604084013567ffffffffffffffff80821115611b7257600080fd5b818601915086601f830112611b8657600080fd5b813581811115611b9857611b98611b01565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611bde57611bde611b01565b81604052828152896020848701011115611bf757600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b600060208284031215611c2b57600080fd5b5035919050565b600060208284031215611c4457600080fd5b610a4182611a72565b6020808252825182820181905260009190848201906040850190845b81811015611c9b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611c69565b50909695505050505050565b60008060408385031215611cba57600080fd5b611cc383611a72565b9150611cd160208401611a72565b90509250929050565b600181811c90821680611cee57607f821691505b602082108103611d27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561061557610615611d2d565b828152604060208201526000611d8860408301846119fb565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611dc560608301846119fb565b95945050505050565b8181038181111561061557610615611d2d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a' as const +// generate:end diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts index 78a8b23f..9c872235 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts @@ -10,8 +10,7 @@ import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' import { ChainFamily } from '../../../../networks.ts' import { CCTTxFailedError } from '../../../errors.ts' -import type { DeployResult } from '../../../operation.ts' -import { EVMOperation } from '../../operation.ts' +import { type DeployResult, type EVMExecuteParams, EVMOperation } from '../../operation.ts' import { submit } from '../../submit.ts' import { validateNonEmptyString, validateUint256, validateUint8 } from '../../validate.ts' import { BURN_MINT_ERC677_BYTECODE } from '../bytecode.ts' @@ -52,7 +51,7 @@ export class DeployToken extends EVMOperation { */ override async execute( chain: EVMChain, - params: DeployTokenParams & { wallet: unknown }, + params: EVMExecuteParams, ): Promise { const { response, receipt } = await submit( chain, diff --git a/ccip-sdk/src/cct/operation.ts b/ccip-sdk/src/cct/operation.ts index bbc6fd2f..215b53ea 100644 --- a/ccip-sdk/src/cct/operation.ts +++ b/ccip-sdk/src/cct/operation.ts @@ -11,17 +11,16 @@ import type { ChainTransaction } from '../types.ts' export type TransactionResult = Pick /** - * Result of a successful deployment write: the tx hash plus the deployed contract address (token, pool, etc.) - * Note: No block-explorer verification handle yet; it's recoverable from the init-code, - * so it can be added later without a breaking change. + * Execute params for a CCT write: an op's own params plus the signing `wallet`. + * Families extend with submit-time extras (e.g. Solana's `computeUnits`). */ -export type DeployResult = TransactionResult & { contractAddress: string } +export type ExecuteParams

= P & { wallet: unknown } /** * Abstract CCT write operation: build unsigned tx(s) with {@link generate}, or * sign and submit with {@link execute}. */ -export abstract class Operation { +export abstract class Operation { /** camelCase id; matches the token-manager facade method and error context. */ abstract readonly name: string /** Reject invalid params before any chain RPC. */ @@ -29,5 +28,5 @@ export abstract class Operation { /** Build unsigned transaction(s); no wallet required. */ abstract generate(chain: Chain, params: Params): Promise /** Sign and submit via `params.wallet`; returns once confirmed. */ - abstract execute(chain: Chain, params: Params & { wallet: unknown }): Promise + abstract execute(chain: Chain, params: ExecuteParams): Promise } From d5badf996875ea443c86938a98a51942095e8b34 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa <14206093+apedrob@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:53:47 +0100 Subject: [PATCH 09/22] feat(cct-sdk): Source chainlink/contracts-ccip artifacts (#303) * feat(cct-sdk): Source token + pool abi/bytecode from contracts-ccip * Remove outdated bytecodes --- .../V1_5_0/burn-mint-token-pool-and-proxy.ts | 1055 +++++++ .../lock-release-token-pool-and-proxy.ts | 1141 +++++++ .../abi/V1_5_1/burn-mint-token-pool.ts | 1171 ++++++++ .../abi/V1_5_1/factory-burn-mint-erc20.ts | 483 +++ .../abi/V1_5_1/lock-release-token-pool.ts | 1276 ++++++++ .../abi/V1_6_1/burn-mint-token-pool.ts | 1171 ++++++++ .../abi/V1_6_1/lock-release-token-pool.ts | 1286 ++++++++ .../abi/V1_6_2/factory-burn-mint-erc20.ts | 490 ++++ .../abi/V2_0_0/burn-from-mint-token-pool.ts | 1665 +++++++++++ .../abi/V2_0_0/burn-mint-token-pool.ts | 1665 +++++++++++ .../V2_0_0/burn-with-from-mint-token-pool.ts | 1665 +++++++++++ .../artifacts/abi/V2_0_0/cross-chain-token.ts | 661 +++++ .../abi/V2_0_0/lock-release-token-pool.ts | 1673 +++++++++++ .../V2_0_0/burn-from-mint-token-pool.ts | 4 + .../bytecode/V2_0_0/burn-mint-token-pool.ts | 4 + .../V2_0_0/burn-with-from-mint-token-pool.ts | 4 + .../bytecode/V2_0_0/cross-chain-token.ts | 4 + .../V2_0_0/lock-release-token-pool.ts | 4 + package-lock.json | 2609 +++++++++++++++-- package.json | 1 + 20 files changed, 17741 insertions(+), 291 deletions(-) create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/burn-mint-token-pool-and-proxy.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/lock-release-token-pool-and-proxy.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/burn-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/factory-burn-mint-erc20.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/lock-release-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/burn-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/lock-release-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V1_6_2/factory-burn-mint-erc20.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-from-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-with-from-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/cross-chain-token.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/lock-release-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/cross-chain-token.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/lock-release-token-pool.ts diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/burn-mint-token-pool-and-proxy.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/burn-mint-token-pool-and-proxy.ts new file mode 100644 index 00000000..e04b953f --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/burn-mint-token-pool-and-proxy.ts @@ -0,0 +1,1055 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_5_0/burn_mint_token_pool_and_proxy.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + inputs: [ + { + internalType: 'contract IBurnMintERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'address[]', + name: 'allowlist', + type: 'address[]', + }, + { internalType: 'address', name: 'rmnProxy', type: 'address' }, + { internalType: 'address', name: 'router', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { internalType: 'uint256', name: 'capacity', type: 'uint256' }, + { internalType: 'uint256', name: 'requested', type: 'uint256' }, + ], + name: 'AggregateValueMaxCapacityExceeded', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'minWaitInSeconds', + type: 'uint256', + }, + { internalType: 'uint256', name: 'available', type: 'uint256' }, + ], + name: 'AggregateValueRateLimitReached', + type: 'error', + }, + { inputs: [], name: 'AllowListNotEnabled', type: 'error' }, + { inputs: [], name: 'BucketOverfilled', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'caller', type: 'address' }], + name: 'CallerIsNotARampOnRouter', + type: 'error', + }, + { + inputs: [{ internalType: 'uint64', name: 'chainSelector', type: 'uint64' }], + name: 'ChainAlreadyExists', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'ChainNotAllowed', + type: 'error', + }, + { inputs: [], name: 'CursedByRMN', type: 'error' }, + { + inputs: [ + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'config', + type: 'tuple', + }, + ], + name: 'DisabledNonZeroRateLimit', + type: 'error', + }, + { + inputs: [ + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'rateLimiterConfig', + type: 'tuple', + }, + ], + name: 'InvalidRateLimitRate', + type: 'error', + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'sourcePoolAddress', + type: 'bytes', + }, + ], + name: 'InvalidSourcePoolAddress', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'InvalidToken', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'NonExistentChain', + type: 'error', + }, + { inputs: [], name: 'RateLimitMustBeDisabled', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], + name: 'SenderNotAllowed', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint256', name: 'capacity', type: 'uint256' }, + { internalType: 'uint256', name: 'requested', type: 'uint256' }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + name: 'TokenMaxCapacityExceeded', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'minWaitInSeconds', + type: 'uint256', + }, + { internalType: 'uint256', name: 'available', type: 'uint256' }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + name: 'TokenRateLimitReached', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'caller', type: 'address' }], + name: 'Unauthorized', + type: 'error', + }, + { inputs: [], name: 'ZeroAddressNotAllowed', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'AllowListAdd', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'AllowListRemove', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Burned', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + indexed: false, + internalType: 'bytes', + name: 'remoteToken', + type: 'bytes', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'outboundRateLimiterConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'inboundRateLimiterConfig', + type: 'tuple', + }, + ], + name: 'ChainAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'outboundRateLimiterConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'inboundRateLimiterConfig', + type: 'tuple', + }, + ], + name: 'ChainConfigured', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'ChainRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'config', + type: 'tuple', + }, + ], + name: 'ConfigChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IPoolPriorTo1_5', + name: 'oldPool', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IPoolPriorTo1_5', + name: 'newPool', + type: 'address', + }, + ], + name: 'LegacyPoolChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Locked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Minted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'OwnershipTransferRequested', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Released', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + indexed: false, + internalType: 'bytes', + name: 'previousPoolAddress', + type: 'bytes', + }, + { + indexed: false, + internalType: 'bytes', + name: 'remotePoolAddress', + type: 'bytes', + }, + ], + name: 'RemotePoolSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldRouter', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newRouter', + type: 'address', + }, + ], + name: 'RouterUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'tokens', + type: 'uint256', + }, + ], + name: 'TokensConsumed', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'removes', type: 'address[]' }, + { internalType: 'address[]', name: 'adds', type: 'address[]' }, + ], + name: 'applyAllowListUpdates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { internalType: 'bool', name: 'allowed', type: 'bool' }, + { + internalType: 'bytes', + name: 'remotePoolAddress', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'remoteTokenAddress', + type: 'bytes', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'rate', + type: 'uint128', + }, + ], + internalType: 'struct RateLimiter.Config', + name: 'outboundRateLimiterConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'rate', + type: 'uint128', + }, + ], + internalType: 'struct RateLimiter.Config', + name: 'inboundRateLimiterConfig', + type: 'tuple', + }, + ], + internalType: 'struct TokenPool.ChainUpdate[]', + name: 'chains', + type: 'tuple[]', + }, + ], + name: 'applyChainUpdates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'getAllowList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllowListEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getCurrentInboundRateLimiterState', + outputs: [ + { + components: [ + { internalType: 'uint128', name: 'tokens', type: 'uint128' }, + { + internalType: 'uint32', + name: 'lastUpdated', + type: 'uint32', + }, + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.TokenBucket', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getCurrentOutboundRateLimiterState', + outputs: [ + { + components: [ + { internalType: 'uint128', name: 'tokens', type: 'uint128' }, + { + internalType: 'uint32', + name: 'lastUpdated', + type: 'uint32', + }, + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.TokenBucket', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint64', name: '', type: 'uint64' }], + name: 'getOnRamp', + outputs: [ + { + internalType: 'address', + name: 'onRampAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPreviousPool', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRateLimitAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getRemotePool', + outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getRemoteToken', + outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRmnProxy', + outputs: [{ internalType: 'address', name: 'rmnProxy', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRouter', + outputs: [{ internalType: 'address', name: 'router', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getSupportedChains', + outputs: [{ internalType: 'uint64[]', name: '', type: 'uint64[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getToken', + outputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'sourceChainSelector', + type: 'uint64', + }, + { internalType: 'address', name: 'offRamp', type: 'address' }, + ], + name: 'isOffRamp', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'isSupportedChain', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'isSupportedToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { internalType: 'bytes', name: 'receiver', type: 'bytes' }, + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + internalType: 'address', + name: 'originalSender', + type: 'address', + }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { + internalType: 'address', + name: 'localToken', + type: 'address', + }, + ], + internalType: 'struct Pool.LockOrBurnInV1', + name: 'lockOrBurnIn', + type: 'tuple', + }, + ], + name: 'lockOrBurn', + outputs: [ + { + components: [ + { + internalType: 'bytes', + name: 'destTokenAddress', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'destPoolData', + type: 'bytes', + }, + ], + internalType: 'struct Pool.LockOrBurnOutV1', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'bytes', + name: 'originalSender', + type: 'bytes', + }, + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { + internalType: 'address', + name: 'localToken', + type: 'address', + }, + { + internalType: 'bytes', + name: 'sourcePoolAddress', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'sourcePoolData', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'offchainTokenData', + type: 'bytes', + }, + ], + internalType: 'struct Pool.ReleaseOrMintInV1', + name: 'releaseOrMintIn', + type: 'tuple', + }, + ], + name: 'releaseOrMint', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'destinationAmount', + type: 'uint256', + }, + ], + internalType: 'struct Pool.ReleaseOrMintOutV1', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'outboundConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'inboundConfig', + type: 'tuple', + }, + ], + name: 'setChainRateLimiterConfig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPoolPriorTo1_5', + name: 'prevPool', + type: 'address', + }, + ], + name: 'setPreviousPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'rateLimitAdmin', + type: 'address', + }, + ], + name: 'setRateLimitAdmin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + internalType: 'bytes', + name: 'remotePoolAddress', + type: 'bytes', + }, + ], + name: 'setRemotePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newRouter', type: 'address' }], + name: 'setRouter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'typeAndVersion', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/lock-release-token-pool-and-proxy.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/lock-release-token-pool-and-proxy.ts new file mode 100644 index 00000000..4400c01b --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_0/lock-release-token-pool-and-proxy.ts @@ -0,0 +1,1141 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_5_0/lock_release_token_pool_and_proxy.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'address[]', + name: 'allowlist', + type: 'address[]', + }, + { internalType: 'address', name: 'rmnProxy', type: 'address' }, + { internalType: 'bool', name: 'acceptLiquidity', type: 'bool' }, + { internalType: 'address', name: 'router', type: 'address' }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { internalType: 'uint256', name: 'capacity', type: 'uint256' }, + { internalType: 'uint256', name: 'requested', type: 'uint256' }, + ], + name: 'AggregateValueMaxCapacityExceeded', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'minWaitInSeconds', + type: 'uint256', + }, + { internalType: 'uint256', name: 'available', type: 'uint256' }, + ], + name: 'AggregateValueRateLimitReached', + type: 'error', + }, + { inputs: [], name: 'AllowListNotEnabled', type: 'error' }, + { inputs: [], name: 'BucketOverfilled', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'caller', type: 'address' }], + name: 'CallerIsNotARampOnRouter', + type: 'error', + }, + { + inputs: [{ internalType: 'uint64', name: 'chainSelector', type: 'uint64' }], + name: 'ChainAlreadyExists', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'ChainNotAllowed', + type: 'error', + }, + { inputs: [], name: 'CursedByRMN', type: 'error' }, + { + inputs: [ + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'config', + type: 'tuple', + }, + ], + name: 'DisabledNonZeroRateLimit', + type: 'error', + }, + { inputs: [], name: 'InsufficientLiquidity', type: 'error' }, + { + inputs: [ + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'rateLimiterConfig', + type: 'tuple', + }, + ], + name: 'InvalidRateLimitRate', + type: 'error', + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'sourcePoolAddress', + type: 'bytes', + }, + ], + name: 'InvalidSourcePoolAddress', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'InvalidToken', + type: 'error', + }, + { inputs: [], name: 'LiquidityNotAccepted', type: 'error' }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'NonExistentChain', + type: 'error', + }, + { inputs: [], name: 'RateLimitMustBeDisabled', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'sender', type: 'address' }], + name: 'SenderNotAllowed', + type: 'error', + }, + { + inputs: [ + { internalType: 'uint256', name: 'capacity', type: 'uint256' }, + { internalType: 'uint256', name: 'requested', type: 'uint256' }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + name: 'TokenMaxCapacityExceeded', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'minWaitInSeconds', + type: 'uint256', + }, + { internalType: 'uint256', name: 'available', type: 'uint256' }, + { + internalType: 'address', + name: 'tokenAddress', + type: 'address', + }, + ], + name: 'TokenRateLimitReached', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'caller', type: 'address' }], + name: 'Unauthorized', + type: 'error', + }, + { inputs: [], name: 'ZeroAddressNotAllowed', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'AllowListAdd', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'AllowListRemove', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Burned', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + indexed: false, + internalType: 'bytes', + name: 'remoteToken', + type: 'bytes', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'outboundRateLimiterConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'inboundRateLimiterConfig', + type: 'tuple', + }, + ], + name: 'ChainAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'outboundRateLimiterConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'inboundRateLimiterConfig', + type: 'tuple', + }, + ], + name: 'ChainConfigured', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'ChainRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + indexed: false, + internalType: 'struct RateLimiter.Config', + name: 'config', + type: 'tuple', + }, + ], + name: 'ConfigChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'contract IPoolPriorTo1_5', + name: 'oldPool', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IPoolPriorTo1_5', + name: 'newPool', + type: 'address', + }, + ], + name: 'LegacyPoolChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'LiquidityAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'provider', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'LiquidityRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Locked', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Minted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'OwnershipTransferRequested', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'Released', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + indexed: false, + internalType: 'bytes', + name: 'previousPoolAddress', + type: 'bytes', + }, + { + indexed: false, + internalType: 'bytes', + name: 'remotePoolAddress', + type: 'bytes', + }, + ], + name: 'RemotePoolSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'oldRouter', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newRouter', + type: 'address', + }, + ], + name: 'RouterUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'tokens', + type: 'uint256', + }, + ], + name: 'TokensConsumed', + type: 'event', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address[]', name: 'removes', type: 'address[]' }, + { internalType: 'address[]', name: 'adds', type: 'address[]' }, + ], + name: 'applyAllowListUpdates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { internalType: 'bool', name: 'allowed', type: 'bool' }, + { + internalType: 'bytes', + name: 'remotePoolAddress', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'remoteTokenAddress', + type: 'bytes', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'rate', + type: 'uint128', + }, + ], + internalType: 'struct RateLimiter.Config', + name: 'outboundRateLimiterConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { + internalType: 'uint128', + name: 'rate', + type: 'uint128', + }, + ], + internalType: 'struct RateLimiter.Config', + name: 'inboundRateLimiterConfig', + type: 'tuple', + }, + ], + internalType: 'struct TokenPool.ChainUpdate[]', + name: 'chains', + type: 'tuple[]', + }, + ], + name: 'applyChainUpdates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'canAcceptLiquidity', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllowList', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAllowListEnabled', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getCurrentInboundRateLimiterState', + outputs: [ + { + components: [ + { internalType: 'uint128', name: 'tokens', type: 'uint128' }, + { + internalType: 'uint32', + name: 'lastUpdated', + type: 'uint32', + }, + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.TokenBucket', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getCurrentOutboundRateLimiterState', + outputs: [ + { + components: [ + { internalType: 'uint128', name: 'tokens', type: 'uint128' }, + { + internalType: 'uint32', + name: 'lastUpdated', + type: 'uint32', + }, + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.TokenBucket', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint64', name: '', type: 'uint64' }], + name: 'getOnRamp', + outputs: [ + { + internalType: 'address', + name: 'onRampAddress', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPreviousPool', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRateLimitAdmin', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRebalancer', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getRemotePool', + outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'getRemoteToken', + outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRmnProxy', + outputs: [{ internalType: 'address', name: 'rmnProxy', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getRouter', + outputs: [{ internalType: 'address', name: 'router', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getSupportedChains', + outputs: [{ internalType: 'uint64[]', name: '', type: 'uint64[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getToken', + outputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'sourceChainSelector', + type: 'uint64', + }, + { internalType: 'address', name: 'offRamp', type: 'address' }, + ], + name: 'isOffRamp', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + ], + name: 'isSupportedChain', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'isSupportedToken', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { internalType: 'bytes', name: 'receiver', type: 'bytes' }, + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + internalType: 'address', + name: 'originalSender', + type: 'address', + }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { + internalType: 'address', + name: 'localToken', + type: 'address', + }, + ], + internalType: 'struct Pool.LockOrBurnInV1', + name: 'lockOrBurnIn', + type: 'tuple', + }, + ], + name: 'lockOrBurn', + outputs: [ + { + components: [ + { + internalType: 'bytes', + name: 'destTokenAddress', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'destPoolData', + type: 'bytes', + }, + ], + internalType: 'struct Pool.LockOrBurnOutV1', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'provideLiquidity', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'bytes', + name: 'originalSender', + type: 'bytes', + }, + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { + internalType: 'address', + name: 'localToken', + type: 'address', + }, + { + internalType: 'bytes', + name: 'sourcePoolAddress', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'sourcePoolData', + type: 'bytes', + }, + { + internalType: 'bytes', + name: 'offchainTokenData', + type: 'bytes', + }, + ], + internalType: 'struct Pool.ReleaseOrMintInV1', + name: 'releaseOrMintIn', + type: 'tuple', + }, + ], + name: 'releaseOrMint', + outputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'destinationAmount', + type: 'uint256', + }, + ], + internalType: 'struct Pool.ReleaseOrMintOutV1', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'outboundConfig', + type: 'tuple', + }, + { + components: [ + { internalType: 'bool', name: 'isEnabled', type: 'bool' }, + { + internalType: 'uint128', + name: 'capacity', + type: 'uint128', + }, + { internalType: 'uint128', name: 'rate', type: 'uint128' }, + ], + internalType: 'struct RateLimiter.Config', + name: 'inboundConfig', + type: 'tuple', + }, + ], + name: 'setChainRateLimiterConfig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IPoolPriorTo1_5', + name: 'prevPool', + type: 'address', + }, + ], + name: 'setPreviousPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'rateLimitAdmin', + type: 'address', + }, + ], + name: 'setRateLimitAdmin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'rebalancer', type: 'address' }], + name: 'setRebalancer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint64', + name: 'remoteChainSelector', + type: 'uint64', + }, + { + internalType: 'bytes', + name: 'remotePoolAddress', + type: 'bytes', + }, + ], + name: 'setRemotePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newRouter', type: 'address' }], + name: 'setRouter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'from', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + ], + name: 'transferLiquidity', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'to', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'typeAndVersion', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'withdrawLiquidity', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/burn-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/burn-mint-token-pool.ts new file mode 100644 index 00000000..f9be69bb --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/burn-mint-token-pool.ts @@ -0,0 +1,1171 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_5_1/burn_mint_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IBurnMintERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'allowlist', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'router', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyAllowListUpdates', + inputs: [ + { name: 'removes', type: 'address[]', internalType: 'address[]' }, + { name: 'adds', type: 'address[]', internalType: 'address[]' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAllowList', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowListEnabled', + inputs: [], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentInboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentOutboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRateLimitAdmin', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRouter', + inputs: [], + outputs: [{ name: 'router', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfig', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'outboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfigs', + inputs: [ + { + name: 'remoteChainSelectors', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'outboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitAdmin', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRouter', + inputs: [{ name: 'newRouter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'event', + name: 'AllowListAdd', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'AllowListRemove', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Burned', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ConfigChanged', + inputs: [ + { + name: 'config', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Locked', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Minted', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitAdminSet', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Released', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RouterUpdated', + inputs: [ + { + name: 'oldRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'newRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokensConsumed', + inputs: [ + { + name: 'tokens', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'AggregateValueMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'AggregateValueRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + ], + }, + { type: 'error', name: 'AllowListNotEnabled', inputs: [] }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'MismatchedArrayLengths', inputs: [] }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { type: 'error', name: 'RateLimitMustBeDisabled', inputs: [] }, + { + type: 'error', + name: 'SenderNotAllowed', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/factory-burn-mint-erc20.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/factory-burn-mint-erc20.ts new file mode 100644 index 00000000..0dbf68f7 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/factory-burn-mint-erc20.ts @@ -0,0 +1,483 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_5_1/factory_burn_mint_erc20.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { name: 'name', type: 'string', internalType: 'string' }, + { name: 'symbol', type: 'string', internalType: 'string' }, + { name: 'decimals_', type: 'uint8', internalType: 'uint8' }, + { name: 'maxSupply_', type: 'uint256', internalType: 'uint256' }, + { name: 'preMint', type: 'uint256', internalType: 'uint256' }, + { name: 'newOwner', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'allowance', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'spender', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'approve', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'balanceOf', + inputs: [{ name: 'account', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'burn', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'burn', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'burnFrom', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'decreaseAllowance', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { + name: 'subtractedValue', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'decreaseApproval', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { + name: 'subtractedValue', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [{ name: 'success', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getBurners', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCCIPAdmin', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getMinters', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'grantBurnRole', + inputs: [{ name: 'burner', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'grantMintAndBurnRoles', + inputs: [ + { + name: 'burnAndMinter', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'grantMintRole', + inputs: [{ name: 'minter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'increaseAllowance', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'addedValue', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'increaseApproval', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'addedValue', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'isBurner', + inputs: [{ name: 'burner', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isMinter', + inputs: [{ name: 'minter', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'maxSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'mint', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'revokeBurnRole', + inputs: [{ name: 'burner', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'revokeMintRole', + inputs: [{ name: 'minter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setCCIPAdmin', + inputs: [{ name: 'newAdmin', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transfer', + inputs: [ + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferFrom', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'Approval', + inputs: [ + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'BurnAccessGranted', + inputs: [ + { + name: 'burner', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'BurnAccessRevoked', + inputs: [ + { + name: 'burner', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'CCIPAdminTransferred', + inputs: [ + { + name: 'previousAdmin', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newAdmin', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'MintAccessGranted', + inputs: [ + { + name: 'minter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'MintAccessRevoked', + inputs: [ + { + name: 'minter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'MaxSupplyExceeded', + inputs: [ + { + name: 'supplyAfterMint', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'SenderNotBurner', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'SenderNotMinter', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/lock-release-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/lock-release-token-pool.ts new file mode 100644 index 00000000..9b072f87 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_5_1/lock-release-token-pool.ts @@ -0,0 +1,1276 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_5_1/lock_release_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'allowlist', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'acceptLiquidity', type: 'bool', internalType: 'bool' }, + { name: 'router', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyAllowListUpdates', + inputs: [ + { name: 'removes', type: 'address[]', internalType: 'address[]' }, + { name: 'adds', type: 'address[]', internalType: 'address[]' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'canAcceptLiquidity', + inputs: [], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowList', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowListEnabled', + inputs: [], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentInboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentOutboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRateLimitAdmin', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRebalancer', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRouter', + inputs: [], + outputs: [{ name: 'router', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'provideLiquidity', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfig', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'outboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfigs', + inputs: [ + { + name: 'remoteChainSelectors', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'outboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitAdmin', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRebalancer', + inputs: [{ name: 'rebalancer', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRouter', + inputs: [{ name: 'newRouter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'transferLiquidity', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'withdrawLiquidity', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'AllowListAdd', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'AllowListRemove', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Burned', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ConfigChanged', + inputs: [ + { + name: 'config', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LiquidityAdded', + inputs: [ + { + name: 'provider', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: true, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LiquidityRemoved', + inputs: [ + { + name: 'provider', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: true, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LiquidityTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Locked', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Minted', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitAdminSet', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Released', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RouterUpdated', + inputs: [ + { + name: 'oldRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'newRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokensConsumed', + inputs: [ + { + name: 'tokens', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'AggregateValueMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'AggregateValueRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + ], + }, + { type: 'error', name: 'AllowListNotEnabled', inputs: [] }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { type: 'error', name: 'InsufficientLiquidity', inputs: [] }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'LiquidityNotAccepted', inputs: [] }, + { type: 'error', name: 'MismatchedArrayLengths', inputs: [] }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { type: 'error', name: 'RateLimitMustBeDisabled', inputs: [] }, + { + type: 'error', + name: 'SenderNotAllowed', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/burn-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/burn-mint-token-pool.ts new file mode 100644 index 00000000..a9243ee8 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/burn-mint-token-pool.ts @@ -0,0 +1,1171 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_6_1/burn_mint_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IBurnMintERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'allowlist', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'router', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyAllowListUpdates', + inputs: [ + { name: 'removes', type: 'address[]', internalType: 'address[]' }, + { name: 'adds', type: 'address[]', internalType: 'address[]' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAllowList', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowListEnabled', + inputs: [], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentInboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentOutboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRateLimitAdmin', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRouter', + inputs: [], + outputs: [{ name: 'router', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfig', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'outboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfigs', + inputs: [ + { + name: 'remoteChainSelectors', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'outboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitAdmin', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRouter', + inputs: [{ name: 'newRouter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'event', + name: 'AllowListAdd', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'AllowListRemove', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ConfigChanged', + inputs: [ + { + name: 'config', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LockedOrBurned', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitAdminSet', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ReleasedOrMinted', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RouterUpdated', + inputs: [ + { + name: 'oldRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'newRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { type: 'error', name: 'AllowListNotEnabled', inputs: [] }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'MismatchedArrayLengths', inputs: [] }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'SenderNotAllowed', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/lock-release-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/lock-release-token-pool.ts new file mode 100644 index 00000000..8863f833 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_1/lock-release-token-pool.ts @@ -0,0 +1,1286 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_6_1/lock_release_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'allowlist', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'router', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyAllowListUpdates', + inputs: [ + { name: 'removes', type: 'address[]', internalType: 'address[]' }, + { name: 'adds', type: 'address[]', internalType: 'address[]' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAllowList', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowListEnabled', + inputs: [], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentInboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentOutboundRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRateLimitAdmin', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRebalancer', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRouter', + inputs: [], + outputs: [{ name: 'router', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'provideLiquidity', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfig', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'outboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setChainRateLimiterConfigs', + inputs: [ + { + name: 'remoteChainSelectors', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'outboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundConfigs', + type: 'tuple[]', + internalType: 'struct RateLimiter.Config[]', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitAdmin', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRebalancer', + inputs: [{ name: 'rebalancer', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRouter', + inputs: [{ name: 'newRouter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'transferLiquidity', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'withdrawLiquidity', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'AllowListAdd', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'AllowListRemove', + inputs: [ + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ConfigChanged', + inputs: [ + { + name: 'config', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LiquidityAdded', + inputs: [ + { + name: 'provider', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: true, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LiquidityRemoved', + inputs: [ + { + name: 'provider', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: true, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LiquidityTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LockedOrBurned', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitAdminSet', + inputs: [ + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RebalancerSet', + inputs: [ + { + name: 'oldRebalancer', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'newRebalancer', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ReleasedOrMinted', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RouterUpdated', + inputs: [ + { + name: 'oldRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'newRouter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { type: 'error', name: 'AllowListNotEnabled', inputs: [] }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { type: 'error', name: 'InsufficientLiquidity', inputs: [] }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'MismatchedArrayLengths', inputs: [] }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'SenderNotAllowed', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_2/factory-burn-mint-erc20.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_2/factory-burn-mint-erc20.ts new file mode 100644 index 00000000..5df804e9 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V1_6_2/factory-burn-mint-erc20.ts @@ -0,0 +1,490 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v1_6_2/factory_burn_mint_erc20.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { name: 'name', type: 'string', internalType: 'string' }, + { name: 'symbol', type: 'string', internalType: 'string' }, + { name: 'decimals_', type: 'uint8', internalType: 'uint8' }, + { name: 'maxSupply_', type: 'uint256', internalType: 'uint256' }, + { name: 'preMint', type: 'uint256', internalType: 'uint256' }, + { name: 'newOwner', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'allowance', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'spender', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'approve', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'balanceOf', + inputs: [{ name: 'account', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'burn', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'burn', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'burnFrom', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'decreaseAllowance', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { + name: 'subtractedValue', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'decreaseApproval', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { + name: 'subtractedValue', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [{ name: 'success', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getBurners', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCCIPAdmin', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getMinters', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'grantBurnRole', + inputs: [{ name: 'burner', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'grantMintAndBurnRoles', + inputs: [ + { + name: 'burnAndMinter', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'grantMintRole', + inputs: [{ name: 'minter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'increaseAllowance', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'addedValue', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'increaseApproval', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'addedValue', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'isBurner', + inputs: [{ name: 'burner', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isMinter', + inputs: [{ name: 'minter', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'maxSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'mint', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'revokeBurnRole', + inputs: [{ name: 'burner', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'revokeMintRole', + inputs: [{ name: 'minter', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setCCIPAdmin', + inputs: [{ name: 'newAdmin', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transfer', + inputs: [ + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferFrom', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'pure', + }, + { + type: 'event', + name: 'Approval', + inputs: [ + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'BurnAccessGranted', + inputs: [ + { + name: 'burner', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'BurnAccessRevoked', + inputs: [ + { + name: 'burner', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'CCIPAdminTransferred', + inputs: [ + { + name: 'previousAdmin', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newAdmin', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'MintAccessGranted', + inputs: [ + { + name: 'minter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'MintAccessRevoked', + inputs: [ + { + name: 'minter', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'MaxSupplyExceeded', + inputs: [ + { + name: 'supplyAfterMint', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'SenderNotBurner', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'SenderNotMinter', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-from-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-from-mint-token-pool.ts new file mode 100644 index 00000000..e945540d --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-from-mint-token-pool.ts @@ -0,0 +1,1665 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v2_0_0/burn_from_mint_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IBurnMintERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'advancedPoolHooks', + type: 'address', + internalType: 'address', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'router', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyTokenTransferFeeConfigUpdates', + inputs: [ + { + name: 'tokenTransferFeeConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.TokenTransferFeeConfigArgs[]', + components: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + }, + { + name: 'disableTokenTransferFeeConfigs', + type: 'uint64[]', + internalType: 'uint64[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAdvancedPoolHooks', + inputs: [], + outputs: [ + { + name: 'advancedPoolHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowedFinalityConfig', + inputs: [], + outputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + ], + outputs: [ + { + name: 'outboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getDynamicConfig', + inputs: [], + outputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getFee', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'uint256', internalType: 'uint256' }, + { name: '', type: 'address', internalType: 'address' }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { name: 'feeUSDCents', type: 'uint256', internalType: 'uint256' }, + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'tokenFeeBps', type: 'uint16', internalType: 'uint16' }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRequiredCCVs', + inputs: [ + { name: 'localToken', type: 'address', internalType: 'address' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'extraData', type: 'bytes', internalType: 'bytes' }, + { + name: 'direction', + type: 'uint8', + internalType: 'enum IPoolV2.MessageDirection', + }, + ], + outputs: [ + { + name: 'requiredCCVs', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenTransferFeeConfig', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'bytes4', internalType: 'bytes4' }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: 'feeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: 'lockOrBurnOutV1', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'tokenArgs', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'destTokenAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setAllowedFinalityConfig', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setDynamicConfig', + inputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitConfig', + inputs: [ + { + name: 'rateLimitConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.RateLimitConfigArgs[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'updateAdvancedPoolHooks', + inputs: [ + { + name: 'newHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'withdrawFeeTokens', + inputs: [ + { + name: 'feeTokens', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'recipient', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'AdvancedPoolHooksUpdated', + inputs: [ + { + name: 'oldHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + { + name: 'newHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DynamicConfigSet', + inputs: [ + { + name: 'router', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'feeAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityInboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityOutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FeeTokenWithdrawn', + inputs: [ + { + name: 'receiver', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'feeToken', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FinalityConfigSet', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + indexed: false, + internalType: 'bytes4', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LockedOrBurned', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'fastFinality', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ReleasedOrMinted', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigDeleted', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigUpdated', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + indexed: false, + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + anonymous: false, + }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'CallerIsNotOwnerOrFeeAdmin', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidRequestedFinality', + inputs: [ + { + name: 'requestedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'InvalidTokenTransferFeeConfig', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { + type: 'error', + name: 'InvalidTransferFeeBps', + inputs: [{ name: 'bps', type: 'uint256', internalType: 'uint256' }], + }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'RequestedFinalityCanOnlyHaveOneMode', + inputs: [ + { + name: 'encodedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'SafeERC20FailedOperation', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressInvalid', inputs: [] }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-mint-token-pool.ts new file mode 100644 index 00000000..ab3df104 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-mint-token-pool.ts @@ -0,0 +1,1665 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v2_0_0/burn_mint_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IBurnMintERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'advancedPoolHooks', + type: 'address', + internalType: 'address', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'router', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyTokenTransferFeeConfigUpdates', + inputs: [ + { + name: 'tokenTransferFeeConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.TokenTransferFeeConfigArgs[]', + components: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + }, + { + name: 'disableTokenTransferFeeConfigs', + type: 'uint64[]', + internalType: 'uint64[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAdvancedPoolHooks', + inputs: [], + outputs: [ + { + name: 'advancedPoolHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowedFinalityConfig', + inputs: [], + outputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + ], + outputs: [ + { + name: 'outboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getDynamicConfig', + inputs: [], + outputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getFee', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'uint256', internalType: 'uint256' }, + { name: '', type: 'address', internalType: 'address' }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { name: 'feeUSDCents', type: 'uint256', internalType: 'uint256' }, + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'tokenFeeBps', type: 'uint16', internalType: 'uint16' }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRequiredCCVs', + inputs: [ + { name: 'localToken', type: 'address', internalType: 'address' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'extraData', type: 'bytes', internalType: 'bytes' }, + { + name: 'direction', + type: 'uint8', + internalType: 'enum IPoolV2.MessageDirection', + }, + ], + outputs: [ + { + name: 'requiredCCVs', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenTransferFeeConfig', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'bytes4', internalType: 'bytes4' }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: 'feeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: 'lockOrBurnOutV1', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'tokenArgs', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'destTokenAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setAllowedFinalityConfig', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setDynamicConfig', + inputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitConfig', + inputs: [ + { + name: 'rateLimitConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.RateLimitConfigArgs[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'updateAdvancedPoolHooks', + inputs: [ + { + name: 'newHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'withdrawFeeTokens', + inputs: [ + { + name: 'feeTokens', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'recipient', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'AdvancedPoolHooksUpdated', + inputs: [ + { + name: 'oldHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + { + name: 'newHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DynamicConfigSet', + inputs: [ + { + name: 'router', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'feeAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityInboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityOutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FeeTokenWithdrawn', + inputs: [ + { + name: 'receiver', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'feeToken', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FinalityConfigSet', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + indexed: false, + internalType: 'bytes4', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LockedOrBurned', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'fastFinality', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ReleasedOrMinted', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigDeleted', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigUpdated', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + indexed: false, + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + anonymous: false, + }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'CallerIsNotOwnerOrFeeAdmin', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidRequestedFinality', + inputs: [ + { + name: 'requestedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'InvalidTokenTransferFeeConfig', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { + type: 'error', + name: 'InvalidTransferFeeBps', + inputs: [{ name: 'bps', type: 'uint256', internalType: 'uint256' }], + }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'RequestedFinalityCanOnlyHaveOneMode', + inputs: [ + { + name: 'encodedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'SafeERC20FailedOperation', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressInvalid', inputs: [] }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-with-from-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-with-from-mint-token-pool.ts new file mode 100644 index 00000000..b5cfe27d --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/burn-with-from-mint-token-pool.ts @@ -0,0 +1,1665 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v2_0_0/burn_with_from_mint_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IBurnMintERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'advancedPoolHooks', + type: 'address', + internalType: 'address', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'router', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyTokenTransferFeeConfigUpdates', + inputs: [ + { + name: 'tokenTransferFeeConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.TokenTransferFeeConfigArgs[]', + components: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + }, + { + name: 'disableTokenTransferFeeConfigs', + type: 'uint64[]', + internalType: 'uint64[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAdvancedPoolHooks', + inputs: [], + outputs: [ + { + name: 'advancedPoolHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowedFinalityConfig', + inputs: [], + outputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + ], + outputs: [ + { + name: 'outboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getDynamicConfig', + inputs: [], + outputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getFee', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'uint256', internalType: 'uint256' }, + { name: '', type: 'address', internalType: 'address' }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { name: 'feeUSDCents', type: 'uint256', internalType: 'uint256' }, + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'tokenFeeBps', type: 'uint16', internalType: 'uint16' }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRequiredCCVs', + inputs: [ + { name: 'localToken', type: 'address', internalType: 'address' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'extraData', type: 'bytes', internalType: 'bytes' }, + { + name: 'direction', + type: 'uint8', + internalType: 'enum IPoolV2.MessageDirection', + }, + ], + outputs: [ + { + name: 'requiredCCVs', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenTransferFeeConfig', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'bytes4', internalType: 'bytes4' }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: 'feeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: 'lockOrBurnOutV1', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'tokenArgs', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'destTokenAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setAllowedFinalityConfig', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setDynamicConfig', + inputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitConfig', + inputs: [ + { + name: 'rateLimitConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.RateLimitConfigArgs[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'updateAdvancedPoolHooks', + inputs: [ + { + name: 'newHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'withdrawFeeTokens', + inputs: [ + { + name: 'feeTokens', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'recipient', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'AdvancedPoolHooksUpdated', + inputs: [ + { + name: 'oldHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + { + name: 'newHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DynamicConfigSet', + inputs: [ + { + name: 'router', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'feeAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityInboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityOutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FeeTokenWithdrawn', + inputs: [ + { + name: 'receiver', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'feeToken', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FinalityConfigSet', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + indexed: false, + internalType: 'bytes4', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LockedOrBurned', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'fastFinality', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ReleasedOrMinted', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigDeleted', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigUpdated', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + indexed: false, + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + anonymous: false, + }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'CallerIsNotOwnerOrFeeAdmin', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidRequestedFinality', + inputs: [ + { + name: 'requestedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'InvalidTokenTransferFeeConfig', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { + type: 'error', + name: 'InvalidTransferFeeBps', + inputs: [{ name: 'bps', type: 'uint256', internalType: 'uint256' }], + }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'RequestedFinalityCanOnlyHaveOneMode', + inputs: [ + { + name: 'encodedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'SafeERC20FailedOperation', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressInvalid', inputs: [] }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/cross-chain-token.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/cross-chain-token.ts new file mode 100644 index 00000000..e967eebf --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/cross-chain-token.ts @@ -0,0 +1,661 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v2_0_0/cross_chain_token.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'args', + type: 'tuple', + internalType: 'struct BaseERC20.ConstructorParams', + components: [ + { name: 'name', type: 'string', internalType: 'string' }, + { name: 'symbol', type: 'string', internalType: 'string' }, + { + name: 'maxSupply', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'preMint', type: 'uint256', internalType: 'uint256' }, + { + name: 'preMintRecipient', + type: 'address', + internalType: 'address', + }, + { name: 'decimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'ccipAdmin', + type: 'address', + internalType: 'address', + }, + ], + }, + { + name: 'burnMintRoleAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'owner', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'BURNER_ROLE', + inputs: [], + outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'BURN_MINT_ADMIN_ROLE', + inputs: [], + outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'DEFAULT_ADMIN_ROLE', + inputs: [], + outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'MINTER_ROLE', + inputs: [], + outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'acceptDefaultAdminTransfer', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'allowance', + inputs: [ + { name: 'owner', type: 'address', internalType: 'address' }, + { name: 'spender', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'approve', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'balanceOf', + inputs: [{ name: 'account', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'beginDefaultAdminTransfer', + inputs: [{ name: 'newAdmin', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'burn', + inputs: [{ name: 'amount', type: 'uint256', internalType: 'uint256' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'burn', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'burnFrom', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'cancelDefaultAdminTransfer', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'changeDefaultAdminDelay', + inputs: [{ name: 'newDelay', type: 'uint48', internalType: 'uint48' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'decimals', + inputs: [], + outputs: [{ name: '_decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'defaultAdmin', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'defaultAdminDelay', + inputs: [], + outputs: [{ name: '', type: 'uint48', internalType: 'uint48' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'defaultAdminDelayIncreaseWait', + inputs: [], + outputs: [{ name: '', type: 'uint48', internalType: 'uint48' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCCIPAdmin', + inputs: [], + outputs: [{ name: 'ccipAdmin', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRoleAdmin', + inputs: [{ name: 'role', type: 'bytes32', internalType: 'bytes32' }], + outputs: [{ name: '', type: 'bytes32', internalType: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'grantMintAndBurnRoles', + inputs: [ + { + name: 'burnAndMinter', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'grantRole', + inputs: [ + { name: 'role', type: 'bytes32', internalType: 'bytes32' }, + { name: 'account', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'hasRole', + inputs: [ + { name: 'role', type: 'bytes32', internalType: 'bytes32' }, + { name: 'account', type: 'address', internalType: 'address' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'maxSupply', + inputs: [], + outputs: [{ name: '_maxSupply', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'mint', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'name', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'pendingDefaultAdmin', + inputs: [], + outputs: [ + { name: 'newAdmin', type: 'address', internalType: 'address' }, + { name: 'schedule', type: 'uint48', internalType: 'uint48' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'pendingDefaultAdminDelay', + inputs: [], + outputs: [ + { name: 'newDelay', type: 'uint48', internalType: 'uint48' }, + { name: 'schedule', type: 'uint48', internalType: 'uint48' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'renounceRole', + inputs: [ + { name: 'role', type: 'bytes32', internalType: 'bytes32' }, + { name: 'account', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'revokeRole', + inputs: [ + { name: 'role', type: 'bytes32', internalType: 'bytes32' }, + { name: 'account', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'rollbackDefaultAdminDelay', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setCCIPAdmin', + inputs: [{ name: 'newAdmin', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'symbol', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'totalSupply', + inputs: [], + outputs: [{ name: '', type: 'uint256', internalType: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transfer', + inputs: [ + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'transferFrom', + inputs: [ + { name: 'from', type: 'address', internalType: 'address' }, + { name: 'to', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'pure', + }, + { + type: 'event', + name: 'Approval', + inputs: [ + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'spender', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'CCIPAdminTransferred', + inputs: [ + { + name: 'previousAdmin', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newAdmin', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultAdminDelayChangeCanceled', + inputs: [], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultAdminDelayChangeScheduled', + inputs: [ + { + name: 'newDelay', + type: 'uint48', + indexed: false, + internalType: 'uint48', + }, + { + name: 'effectSchedule', + type: 'uint48', + indexed: false, + internalType: 'uint48', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultAdminTransferCanceled', + inputs: [], + anonymous: false, + }, + { + type: 'event', + name: 'DefaultAdminTransferScheduled', + inputs: [ + { + name: 'newAdmin', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'acceptSchedule', + type: 'uint48', + indexed: false, + internalType: 'uint48', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RoleAdminChanged', + inputs: [ + { + name: 'role', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + { + name: 'previousAdminRole', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + { + name: 'newAdminRole', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RoleGranted', + inputs: [ + { + name: 'role', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + { + name: 'account', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RoleRevoked', + inputs: [ + { + name: 'role', + type: 'bytes32', + indexed: true, + internalType: 'bytes32', + }, + { + name: 'account', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { type: 'error', name: 'AccessControlBadConfirmation', inputs: [] }, + { + type: 'error', + name: 'AccessControlEnforcedDefaultAdminDelay', + inputs: [{ name: 'schedule', type: 'uint48', internalType: 'uint48' }], + }, + { + type: 'error', + name: 'AccessControlEnforcedDefaultAdminRules', + inputs: [], + }, + { + type: 'error', + name: 'AccessControlInvalidDefaultAdmin', + inputs: [ + { + name: 'defaultAdmin', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'AccessControlUnauthorizedAccount', + inputs: [ + { name: 'account', type: 'address', internalType: 'address' }, + { name: 'neededRole', type: 'bytes32', internalType: 'bytes32' }, + ], + }, + { type: 'error', name: 'CannotRenounceCCIPAdmin', inputs: [] }, + { + type: 'error', + name: 'ERC20InsufficientAllowance', + inputs: [ + { name: 'spender', type: 'address', internalType: 'address' }, + { name: 'allowance', type: 'uint256', internalType: 'uint256' }, + { name: 'needed', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'ERC20InsufficientBalance', + inputs: [ + { name: 'sender', type: 'address', internalType: 'address' }, + { name: 'balance', type: 'uint256', internalType: 'uint256' }, + { name: 'needed', type: 'uint256', internalType: 'uint256' }, + ], + }, + { + type: 'error', + name: 'ERC20InvalidApprover', + inputs: [{ name: 'approver', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC20InvalidReceiver', + inputs: [{ name: 'receiver', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC20InvalidSender', + inputs: [{ name: 'sender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'ERC20InvalidSpender', + inputs: [{ name: 'spender', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'MaxSupplyExceeded', + inputs: [ + { + name: 'supplyAfterMint', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'maxSupply', type: 'uint256', internalType: 'uint256' }, + ], + }, + { type: 'error', name: 'OnlyCCIPAdmin', inputs: [] }, + { type: 'error', name: 'PreMintAddressNotSet', inputs: [] }, + { + type: 'error', + name: 'PreMintRecipientSetWithZeroPreMint', + inputs: [ + { + name: 'preMintRecipient', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'SafeCastOverflowedUintDowncast', + inputs: [ + { name: 'bits', type: 'uint8', internalType: 'uint8' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + ], + }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/lock-release-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/lock-release-token-pool.ts new file mode 100644 index 00000000..1b888ccd --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/lock-release-token-pool.ts @@ -0,0 +1,1673 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v2_0_0/lock_release_token_pool.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + { + name: 'localTokenDecimals', + type: 'uint8', + internalType: 'uint8', + }, + { + name: 'advancedPoolHooks', + type: 'address', + internalType: 'address', + }, + { name: 'rmnProxy', type: 'address', internalType: 'address' }, + { name: 'router', type: 'address', internalType: 'address' }, + { name: 'lockBox', type: 'address', internalType: 'address' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyChainUpdates', + inputs: [ + { + name: 'remoteChainSelectorsToRemove', + type: 'uint64[]', + internalType: 'uint64[]', + }, + { + name: 'chainsToAdd', + type: 'tuple[]', + internalType: 'struct TokenPool.ChainUpdate[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddresses', + type: 'bytes[]', + internalType: 'bytes[]', + }, + { + name: 'remoteTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyTokenTransferFeeConfigUpdates', + inputs: [ + { + name: 'tokenTransferFeeConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.TokenTransferFeeConfigArgs[]', + components: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + }, + { + name: 'disableTokenTransferFeeConfigs', + type: 'uint64[]', + internalType: 'uint64[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAdvancedPoolHooks', + inputs: [], + outputs: [ + { + name: 'advancedPoolHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllowedFinalityConfig', + inputs: [], + outputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getCurrentRateLimiterState', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + ], + outputs: [ + { + name: 'outboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterState', + type: 'tuple', + internalType: 'struct RateLimiter.TokenBucket', + components: [ + { name: 'tokens', type: 'uint128', internalType: 'uint128' }, + { + name: 'lastUpdated', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getDynamicConfig', + inputs: [], + outputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getFee', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'uint256', internalType: 'uint256' }, + { name: '', type: 'address', internalType: 'address' }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { name: 'feeUSDCents', type: 'uint256', internalType: 'uint256' }, + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { name: 'tokenFeeBps', type: 'uint16', internalType: 'uint16' }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getLockBox', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemotePools', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRemoteToken', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRequiredCCVs', + inputs: [ + { name: 'localToken', type: 'address', internalType: 'address' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'extraData', type: 'bytes', internalType: 'bytes' }, + { + name: 'direction', + type: 'uint8', + internalType: 'enum IPoolV2.MessageDirection', + }, + ], + outputs: [ + { + name: 'requiredCCVs', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getRmnProxy', + inputs: [], + outputs: [{ name: 'rmnProxy', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSupportedChains', + inputs: [], + outputs: [{ name: '', type: 'uint64[]', internalType: 'uint64[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [ + { + name: 'token', + type: 'address', + internalType: 'contract IERC20', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenDecimals', + inputs: [], + outputs: [{ name: 'decimals', type: 'uint8', internalType: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getTokenTransferFeeConfig', + inputs: [ + { name: '', type: 'address', internalType: 'address' }, + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: '', type: 'bytes4', internalType: 'bytes4' }, + { name: '', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: 'feeConfig', + type: 'tuple', + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isSupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + outputs: [ + { + name: 'lockOrBurnOutV1', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'lockOrBurn', + inputs: [ + { + name: 'lockOrBurnIn', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnInV1', + components: [ + { name: 'receiver', type: 'bytes', internalType: 'bytes' }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'originalSender', + type: 'address', + internalType: 'address', + }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + { name: 'tokenArgs', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.LockOrBurnOutV1', + components: [ + { + name: 'destTokenAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'destPoolData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'destTokenAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'requestedFinalityConfig', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'releaseOrMint', + inputs: [ + { + name: 'releaseOrMintIn', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintInV1', + components: [ + { + name: 'originalSender', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'receiver', + type: 'address', + internalType: 'address', + }, + { + name: 'sourceDenominatedAmount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'localToken', + type: 'address', + internalType: 'address', + }, + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'sourcePoolData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'offchainTokenData', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Pool.ReleaseOrMintOutV1', + components: [ + { + name: 'destinationAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeRemotePool', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setAllowedFinalityConfig', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setDynamicConfig', + inputs: [ + { name: 'router', type: 'address', internalType: 'address' }, + { + name: 'rateLimitAdmin', + type: 'address', + internalType: 'address', + }, + { name: 'feeAdmin', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setRateLimitConfig', + inputs: [ + { + name: 'rateLimitConfigArgs', + type: 'tuple[]', + internalType: 'struct TokenPool.RateLimitConfigArgs[]', + components: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { name: 'fastFinality', type: 'bool', internalType: 'bool' }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { + name: 'rate', + type: 'uint128', + internalType: 'uint128', + }, + ], + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [{ name: 'interfaceId', type: 'bytes4', internalType: 'bytes4' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'updateAdvancedPoolHooks', + inputs: [ + { + name: 'newHook', + type: 'address', + internalType: 'contract IAdvancedPoolHooks', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'withdrawFeeTokens', + inputs: [ + { + name: 'feeTokens', + type: 'address[]', + internalType: 'address[]', + }, + { name: 'recipient', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'AdvancedPoolHooksUpdated', + inputs: [ + { + name: 'oldHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + { + name: 'newHook', + type: 'address', + indexed: false, + internalType: 'contract IAdvancedPoolHooks', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'remoteToken', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ChainRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'DynamicConfigSet', + inputs: [ + { + name: 'router', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'rateLimitAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'feeAdmin', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityInboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FastFinalityOutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FeeTokenWithdrawn', + inputs: [ + { + name: 'receiver', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'feeToken', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FinalityConfigSet', + inputs: [ + { + name: 'allowedFinality', + type: 'bytes4', + indexed: false, + internalType: 'bytes4', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'LockedOrBurned', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OutboundRateLimitConsumed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RateLimitConfigured', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'fastFinality', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + { + name: 'outboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + { + name: 'inboundRateLimiterConfig', + type: 'tuple', + indexed: false, + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ReleasedOrMinted', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'token', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'sender', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'RemotePoolRemoved', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigDeleted', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'TokenTransferFeeConfigUpdated', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + indexed: true, + internalType: 'uint64', + }, + { + name: 'tokenTransferFeeConfig', + type: 'tuple', + indexed: false, + internalType: 'struct IPoolV2.TokenTransferFeeConfig', + components: [ + { + name: 'destGasOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'destBytesOverhead', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'fastFinalityFeeUSDCents', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'finalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { + name: 'fastFinalityTransferFeeBps', + type: 'uint16', + internalType: 'uint16', + }, + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + ], + }, + ], + anonymous: false, + }, + { type: 'error', name: 'BucketOverfilled', inputs: [] }, + { + type: 'error', + name: 'CallerIsNotARampOnRouter', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'CallerIsNotOwnerOrFeeAdmin', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'ChainAlreadyExists', + inputs: [{ name: 'chainSelector', type: 'uint64', internalType: 'uint64' }], + }, + { + type: 'error', + name: 'ChainNotAllowed', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'CursedByRMN', inputs: [] }, + { + type: 'error', + name: 'DisabledNonZeroRateLimit', + inputs: [ + { + name: 'config', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidDecimalArgs', + inputs: [ + { name: 'expected', type: 'uint8', internalType: 'uint8' }, + { name: 'actual', type: 'uint8', internalType: 'uint8' }, + ], + }, + { + type: 'error', + name: 'InvalidRateLimitRate', + inputs: [ + { + name: 'rateLimiterConfig', + type: 'tuple', + internalType: 'struct RateLimiter.Config', + components: [ + { name: 'isEnabled', type: 'bool', internalType: 'bool' }, + { + name: 'capacity', + type: 'uint128', + internalType: 'uint128', + }, + { name: 'rate', type: 'uint128', internalType: 'uint128' }, + ], + }, + ], + }, + { + type: 'error', + name: 'InvalidRemoteChainDecimals', + inputs: [{ name: 'sourcePoolData', type: 'bytes', internalType: 'bytes' }], + }, + { + type: 'error', + name: 'InvalidRemotePoolForChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidRequestedFinality', + inputs: [ + { + name: 'requestedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'allowedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'InvalidSourcePoolAddress', + inputs: [ + { + name: 'sourcePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'InvalidToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'InvalidTokenTransferFeeConfig', + inputs: [ + { + name: 'destChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { + type: 'error', + name: 'InvalidTransferFeeBps', + inputs: [{ name: 'bps', type: 'uint256', internalType: 'uint256' }], + }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { + type: 'error', + name: 'NonExistentChain', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + ], + }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { + type: 'error', + name: 'OverflowDetected', + inputs: [ + { name: 'remoteDecimals', type: 'uint8', internalType: 'uint8' }, + { name: 'localDecimals', type: 'uint8', internalType: 'uint8' }, + { + name: 'remoteAmount', + type: 'uint256', + internalType: 'uint256', + }, + ], + }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'PoolAlreadyAdded', + inputs: [ + { + name: 'remoteChainSelector', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'remotePoolAddress', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'RequestedFinalityCanOnlyHaveOneMode', + inputs: [ + { + name: 'encodedFinality', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'SafeERC20FailedOperation', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'TokenMaxCapacityExceeded', + inputs: [ + { name: 'capacity', type: 'uint256', internalType: 'uint256' }, + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TokenRateLimitReached', + inputs: [ + { + name: 'minWaitInSeconds', + type: 'uint256', + internalType: 'uint256', + }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + { + name: 'tokenAddress', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Unauthorized', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressInvalid', inputs: [] }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, + // generate:end +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts new file mode 100644 index 00000000..d45c9142 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts @@ -0,0 +1,4 @@ +export default // generate: +// `'${require('fs').readFileSync(require.resolve('@chainlink/contracts-ccip/bytecode/v2_0_0/burn_from_mint_token_pool.bin'), 'utf8').trim()}' as const` +'0x60e080604052346102aa5760a081615ee1803803809161001f82856102fb565b8339810103126102aa5780516001600160a01b03811691908290036102aa5761004a60208201610334565b61005660408301610342565b9061006f608061006860608601610342565b9401610342565b9233156102ea57600180546001600160a01b03191633179055841580156102d9575b80156102c8575b6102b7578460805260c052308403610220575b60a052600380546001600160a01b039283166001600160a01b0319918216179091556002805493909216921691909117905560405163095ea7b360e01b60208083019182523060248401526000196044808501919091528352906000906101136064856102fb565b83519082865af16000513d82610204575b5050156101bf575b604051615b2390816103be823960805181818161023e01528181610491015281816122700152818161244801528181612ab501528181612cb0015281816131a20152818161374f01526137a9015260a05181818161361501528181614928015281816149720152614ebc015260c0518181816102d9015281816113f50152818161230a01528181612b50015261323d0152f35b6101fd916101f860405163095ea7b360e01b602082015230602482015260006044820152604481526101f26064826102fb565b82610356565b610356565b388061012c565b9091506102185750813b15155b3880610124565b600114610211565b60405163313ce56760e01b8152602081600481885afa60009181610276575b5061024b575b506100ab565b60ff1660ff821681810361025f5750610245565b6332ad3e0760e11b60005260045260245260446000fd5b9091506020813d6020116102af575b81610292602093836102fb565b810103126102aa576102a390610334565b903861023f565b600080fd5b3d9150610285565b630a64406560e11b60005260046000fd5b506001600160a01b03811615610098565b506001600160a01b03841615610091565b639b15e16f60e01b60005260046000fd5b601f909101601f19168101906001600160401b0382119082101761031e57604052565b634e487b7160e01b600052604160045260246000fd5b519060ff821682036102aa57565b51906001600160a01b03821682036102aa57565b906000602091828151910182855af1156103b1576000513d6103a857506001600160a01b0381163b155b6103875750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415610380565b6040513d6000823e3d90fdfe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a7146139ca5750806306b859ef146138e5578063181f5a77146138845780631826b1e7146137cd57806321df0da71461377c578063240028e8146137185780632422ac451461363957806324f65ee7146135fb5780632cab0fb61461310757806337a3210d146130d35780633907753714612a0a5780634c5ef0ed146129c357806362ddd3c41461293c5780637437ff9f146128ee57806379ba5097146128275780638926f54f146127e15780638da5cb5b146127ad5780639a4575b9146121f7578063a42a7b8b14612090578063acfecf9114611f98578063ae39a25714611e0d578063b6cfa3b714611d52578063b794658014611d1a578063bfeffd3f14611c6e578063c4bffe2b14611b43578063c7230a601461189d578063dc04fa1f14611419578063dc0bd971146113c8578063dcbd41bc146111c4578063e8a1da1714610ae8578063ea6396db146109aa578063ec6ae7a714610967578063f2fde38b146108985763fbc801a71461019757600080fd5b346105db5760606003193601126105db576004359067ffffffffffffffff82116105db578160040160a060031984360301126105e9576101d5613afc565b9060443567ffffffffffffffff811161070f57906101fa610217923690600401613c27565b92906102046145e4565b5061020f8584615120565b933691613da1565b92608486019361022685614571565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361084e57602487019677ffffffffffffffff0000000000000000000000000000000061028c89614592565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156107c157889161081f575b506107f75767ffffffffffffffff61032089614592565b16610338816000526007602052604060002054151590565b156107cc57602073ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156107c1578890610770575b73ffffffffffffffffffffffffffffffffffffffff9150163303610744576064810135936103c78686613f88565b7fffffffff00000000000000000000000000000000000000000000000000000000851694851561072257610423907fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1690614a7c565b61043f816104308a614571565b6104398d614592565b90615408565b73ffffffffffffffffffffffffffffffffffffffff6003541693846105ed575b5050505050509061046f91613f88565b9161047984614592565b5073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b156105e9576040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018590529082908290604490829084905af180156105de576105c6575b6105bc8461058b61058688877ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff61054c61054685614592565b93614571565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252336020830152810188905292169180606081015b0390a2614592565b614755565b90610594614eb5565b604051926105a184613d0c565b83526020830152604051928392604084526040840190613e69565b9060208301520390f35b6105d1828092613d60565b6105db5780610504565b80fd5b6040513d84823e3d90fd5b5080fd5b843b1561071e578994928b9694928692604051988997889687957fa8027c0f00000000000000000000000000000000000000000000000000000000875260048701608090528061063c91615372565b6084880160a0905261012488019061065392613fb6565b9261065d90613c12565b67ffffffffffffffff1660a487015260440161067890613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660c48601528d8c60e48701526106a390613bc3565b73ffffffffffffffffffffffffffffffffffffffff1661010486015260248501528381036003190160448501526106d991613c55565b90606483015203925af18015610713579085916106fa575b8080808061045f565b8161070491613d60565b61070f5783386106f1565b8380fd5b6040513d87823e3d90fd5b8980fd5b5061073f816107308a614571565b6107398d614592565b906153c2565b61043f565b6024877f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b506020813d6020116107b9575b8161078a60209383613d60565b810103126107b5576107b073ffffffffffffffffffffffffffffffffffffffff91613f95565b610399565b8780fd5b3d915061077d565b6040513d8a823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008852600452602487fd5b6004877f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b610841915060203d602011610847575b6108398183613d60565b810190614be8565b38610309565b503d61082f565b60248673ffffffffffffffffffffffffffffffffffffffff61086f88614571565b7f961c9a4f00000000000000000000000000000000000000000000000000000000835216600452fd5b50346105db5760206003193601126105db5773ffffffffffffffffffffffffffffffffffffffff6108c7613b5a565b6108cf614c00565b1633811461093f57807fffffffffffffffffffffffff000000000000000000000000000000000000000083541617825573ffffffffffffffffffffffffffffffffffffffff600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12788380a380f35b6004827fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b50346105db57806003193601126105db5760207fffffffff0000000000000000000000000000000000000000000000000000000060025460401b16604051908152f35b50346105db5760806003193601126105db576109c4613b5a565b506109cd613be4565b6109d5613b2b565b5060643567ffffffffffffffff8111610ae4579167ffffffffffffffff604092610a0560e0953690600401613c27565b50508260c08551610a1581613d44565b82815282602082015282878201528260608201528260808201528260a08201520152168152600b6020522060405190610a4d82613d44565b5461ffff818163ffffffff82169485815263ffffffff60208201818560201c1681528160408401818760401c168152816060860193818960601c16855260ff60c060808901988a8c60801c168a528a60a082019c60901c168c52019b60a01c1615158b526040519b8c52511660208b0152511660408901525116606087015251166080850152511660a083015251151560c0820152f35b8280fd5b50346105db5760406003193601126105db5760043567ffffffffffffffff81116105e957610b1a903690600401613e93565b9060243567ffffffffffffffff811161070f5790610b3d84923690600401613e93565b939091610b48614c00565b83905b8282106110055750505081927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee182360301935b81811015611001578060051b83013585811215610ffd57830161012081360312610ffd5760405194610baf86613d28565b610bb882613c12565b8652602082013567ffffffffffffffff81116105e95782019436601f870112156105e957853595610be887613ef5565b96610bf66040519889613d60565b80885260208089019160051b83010190368211610ffd5760208301905b828210610fca575050505060208701958652604083013567ffffffffffffffff8111610ae457610c469036908501613e06565b9160408801928352610c70610c5e3660608701614801565b9460608a0195865260c0369101614801565b956080890196875283515115610fa257610c9467ffffffffffffffff8a51166157a5565b15610f6b5767ffffffffffffffff8951168252600860205260408220610cbb865182614ef0565b610cc9885160028301614ef0565b6004855191019080519067ffffffffffffffff8211610f3e57610cec8354614640565b601f8111610f03575b50602090601f8311600114610e6457610d439291869183610e59575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b90555b815b88518051821015610d7d5790610d77600192610d708367ffffffffffffffff8f5116926145fd565b5190614c4b565b01610d48565b5050977f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2939199975095610e4b67ffffffffffffffff6001979694985116925193519151610e17610de260405196879687526101006020880152610100870190613c55565b9360408601906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b60a08401906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b0390a1019392909193610b7e565b015190508e80610d11565b83865281862091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08416875b818110610eeb5750908460019594939210610eb4575b505050811b019055610d46565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558d8080610ea7565b92936020600181928786015181550195019301610e91565b610f2e9084875260208720601f850160051c81019160208610610f34575b601f0160051c019061489d565b8d610cf5565b9091508190610f21565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b60248267ffffffffffffffff8b51167f1d5ad3c5000000000000000000000000000000000000000000000000000000008252600452fd5b6004827f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b813567ffffffffffffffff8111610ff957602091610fee8392833691890101613e06565b815201910190610c13565b8680fd5b8480fd5b8380f35b9267ffffffffffffffff6110276110228486889a9699979a6147d4565b614592565b1691611032836154db565b1561119857828452600860205261104e60056040862001615478565b94845b865181101561108757600190858752600860205261108060056040892001611079838b6145fd565b5190615671565b5001611051565b50939692909450949094808752600860205260056040882088815588600182015588600282015588600382015588600482016110c38154614640565b80611157575b5050500180549088815581611139575b5050907f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599166020836001948a52600482528985604082208281550155808a52600582528985604082208281550155604051908152a101909194939294610b4b565b885260208820908101905b818110156110d957888155600101611144565b601f811160011461116d5750555b888a806110c9565b8183526020832061118891601f01861c81019060010161489d565b8082528160208120915555611165565b602484847f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b50346105db5760206003193601126105db5760043567ffffffffffffffff81116105e9576111f6903690600401613ec4565b73ffffffffffffffffffffffffffffffffffffffff600a5416331415806113a6575b61137a57825b818110611229578380f35b611234818385614777565b67ffffffffffffffff61124682614592565b169061125f826000526007602052604060002054151590565b1561134e57907f41f7c8f7cfdad9350aa495e6c54cbbf750a07ab38a9098aed1256e30dd1682bb60e08361130e6112e8602060019897018b6112a082614787565b156113155787905260046020526112c760408d206112c13660408801614801565b90614ef0565b868c5260056020526112e360408d206112c13660a08801614801565b614787565b9160405192151583526113016020840160408301614859565b60a0608084019101614859565ba20161121e565b60026040828a6112e3945260086020526113378282206112c136858c01614801565b8a8152600860205220016112c13660a08801614801565b602486837f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b6024837f8e4a23d600000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff60015416331415611218565b50346105db57806003193601126105db57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105db5760406003193601126105db5760043567ffffffffffffffff81116105e95761144b903690600401613ec4565b60243567ffffffffffffffff811161070f5761146b903690600401613e93565b919092611476614c00565b845b8281106114e257505050825b81811061148f578380f35b8067ffffffffffffffff6114a961102260019486886147d4565b16808652600b6020528560408120557f5479bbc0288b7eaeaf2ace0943b88016cc648964fcd42919a86fd93b15fdbee88680a201611484565b67ffffffffffffffff6114f9611022838686614777565b16611511816000526007602052604060002054151590565b1561187257611521828585614777565b602081019060e081019061153482614787565b156118465760a0810161271061ffff61154c83614794565b1610156118375760c082019161271061ffff61156785614794565b1610156117ff5763ffffffff61157c866147a3565b16156117d357858c52600b60205260408c20611597866147a3565b63ffffffff169080549060408401916115af836147a3565b60201b67ffffffff00000000169360608601946115cb866147a3565b60401b6bffffffff00000000000000001696608001966115ea886147a3565b60601b6fffffffff00000000000000000000000016916116098a614794565b60801b71ffff00000000000000000000000000000000169361162a8c614794565b60901b73ffff00000000000000000000000000000000000016957fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016177fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16177fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff16177fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff1617171781556116dd87614787565b81547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff0000000000000000000000000000000000000000161790556040519661172e906147b4565b63ffffffff16875261173f906147b4565b63ffffffff166020870152611753906147b4565b63ffffffff166040860152611767906147b4565b63ffffffff16606085015261177b906147c5565b61ffff16608084015261178d906147c5565b61ffff1660a083015261179f90613cb4565b151560c082015260e07ffae1e296719dac5269c3886fb5002bb29bf17ae403060c6eb063a55abaaa104191a2600101611478565b60248c877f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b60248c61ffff61180e86614794565b7f95f3517a00000000000000000000000000000000000000000000000000000000835216600452fd5b8a61ffff61180e602493614794565b60248a857f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b7f1e670e4b000000000000000000000000000000000000000000000000000000008752600452602486fd5b50346105db5760406003193601126105db5760043567ffffffffffffffff81116105e9576118cf903690600401613e93565b906118d8613ba0565b9173ffffffffffffffffffffffffffffffffffffffff6001541633141580611b21575b611af55773ffffffffffffffffffffffffffffffffffffffff8316908115611acd57845b81811061192a578580f35b73ffffffffffffffffffffffffffffffffffffffff61195261194d8385886147d4565b614571565b166040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152602081602481855afa9081156107c1578891611a9a575b50806119a7575b505060010161191f565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000602080830191825273ffffffffffffffffffffffffffffffffffffffff8a16602484015260448084018590528352918a9190611a08606482613d60565b519082865af115611a8f5787513d611a865750813b155b611a5a5790847f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e602060019594604051908152a3903861199d565b602488837f5274afe7000000000000000000000000000000000000000000000000000000008252600452fd5b60011415611a1f565b6040513d89823e3d90fd5b905060203d8111611ac6575b611ab08183613d60565b602082600092810103126105db57505138611996565b503d611aa6565b6004857f8579befe000000000000000000000000000000000000000000000000000000008152fd5b6024847fcb1afbd700000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff600c54163314156118fb565b50346105db57806003193601126105db57604051906006548083528260208101600684526020842092845b818110611c55575050611b8392500383613d60565b8151611ba7611b9182613ef5565b91611b9f6040519384613d60565b808352613ef5565b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0602083019301368437805b8451811015611c06578067ffffffffffffffff611bf3600193886145fd565b5116611bff82866145fd565b5201611bd4565b50925090604051928392602084019060208552518091526040840192915b818110611c32575050500390f35b825167ffffffffffffffff16845285945060209384019390920191600101611c24565b8454835260019485019487945060209093019201611b6e565b50346105db5760206003193601126105db5760043573ffffffffffffffffffffffffffffffffffffffff81168091036105e957611ca9614c00565b7fffffffffffffffffffffffff00000000000000000000000000000000000000006003547fbaff46844acf36d6ee996f489a1a288709c4542bd33cd557770afd267d5812096040805173ffffffffffffffffffffffffffffffffffffffff84168152856020820152a1161760035580f35b50346105db5760206003193601126105db57611d4e611d3a610586613bfb565b604051918291602083526020830190613c55565b0390f35b50346105db5760206003193601126105db577f307cf716eade81675bea3ccb6917b0f91baa2160056765d9a83d76f819caf06a6020611d8f613ac8565b611d97614c00565b6002547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff0000000000000000000000000000000000000000808460401c16169116176002557fffffffff0000000000000000000000000000000000000000000000000000000060405191168152a180f35b50346105db5760606003193601126105db57611e27613b5a565b90611e30613ba0565b6044359273ffffffffffffffffffffffffffffffffffffffff841680850361070f57611e5a614c00565b73ffffffffffffffffffffffffffffffffffffffff82168015611f705794611f6a917f3f1036e85d016a93254a0b1415844f79b85424959d90ae5ad51ce8f4533fe70195967fffffffffffffffffffffffff0000000000000000000000000000000000000000600254161760025573ffffffffffffffffffffffffffffffffffffffff85167fffffffffffffffffffffffff0000000000000000000000000000000000000000600a541617600a557fffffffffffffffffffffffff0000000000000000000000000000000000000000600c541617600c556040519384938491604091949373ffffffffffffffffffffffffffffffffffffffff809281606087019816865216602085015216910152565b0390a180f35b6004857f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b50346105db5767ffffffffffffffff611fb036613e24565b929091611fbb614c00565b1691611fd4836000526007602052604060002054151590565b1561119857828452600860205261200360056040862001611ff6368486613da1565b6020815191012090615671565b1561204857907f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7691612042604051928392602084526020840191613fb6565b0390a280f35b8261208c836040519384937f74f23c7c0000000000000000000000000000000000000000000000000000000085526004850152604060248501526044840191613fb6565b0390fd5b50346105db5760206003193601126105db5767ffffffffffffffff6120b3613bfb565b16815260086020526120ca60056040832001615478565b80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061210f6120f983613ef5565b926121076040519485613d60565b808452613ef5565b01835b8181106121e6575050825b82518110156121635780612133600192856145fd565b518552600960205261214760408620614693565b61215182856145fd565b5261215c81846145fd565b500161211d565b81846040519182916020830160208452825180915260408401602060408360051b870101940192905b82821061219b57505050500390f35b919360206121d6827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851613c55565b960192019201859493919261218c565b806060602080938601015201612112565b50346105db5760206003193601126105db5760043567ffffffffffffffff81116105e957806004019060a06003198236030112610ae4576122366145e4565b506040516020936122478583613d60565b808252608483019161225883614571565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361278c57602484019477ffffffffffffffff000000000000000000000000000000006122be87614592565b60801b16604051907f2cbc26bb0000000000000000000000000000000000000000000000000000000082526004820152878160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa90811561271157849161276f575b506127475767ffffffffffffffff61235187614592565b16612369816000526007602052604060002054151590565b1561271c578773ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156127115784906126c9575b73ffffffffffffffffffffffffffffffffffffffff915016330361269d57606485013594612403866123fa87614571565b6107398a614592565b73ffffffffffffffffffffffffffffffffffffffff600354169182612580575b5050505061243084614592565b5073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b156105e9576040517f79cc6790000000000000000000000000000000000000000000000000000000008152306004820152602481018590529082908290604490829084905af180156105de5761256b575b8561253b61058687877ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff8961057e6125046124fe87614592565b92614571565b6040805173ffffffffffffffffffffffffffffffffffffffff90921682523360208301528101959095529116929081906060820190565b90612544614eb5565b6040519261255184613d0c565b835281830152611d4e604051928284938452830190613e69565b612576828092613d60565b6105db57806124bb565b823b15610ffd57918791858094604051968795869485937fa8027c0f0000000000000000000000000000000000000000000000000000000085526004850160809052806125cc91615372565b6084860160a090526101248601906125e392613fb6565b916125ed90613c12565b67ffffffffffffffff1660a485015260440161260890613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660c48401528b60e48401526126328b613bc3565b73ffffffffffffffffffffffffffffffffffffffff1661010484015283602484015282810360031901604484015261266991613c55565b8a606483015203925af180156105de57908291612688575b8080612423565b8161269291613d60565b6105db578038612681565b6024837f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b508781813d831161270a575b6126df8183613d60565b8101031261070f5761270573ffffffffffffffffffffffffffffffffffffffff91613f95565b6123c9565b503d6126d5565b6040513d86823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008452600452602483fd5b6004837f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b6127869150883d8a11610847576108398183613d60565b3861233a565b5073ffffffffffffffffffffffffffffffffffffffff61086f602493614571565b50346105db57806003193601126105db57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b50346105db5760206003193601126105db57602061281d67ffffffffffffffff612809613bfb565b166000526007602052604060002054151590565b6040519015158152f35b50346105db57806003193601126105db57805473ffffffffffffffffffffffffffffffffffffffff811633036128c6577fffffffffffffffffffffffff000000000000000000000000000000000000000060015491338284161760015516825573ffffffffffffffffffffffffffffffffffffffff3391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b6004827f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b50346105db57806003193601126105db57600254600a54600c546040805173ffffffffffffffffffffffffffffffffffffffff94851681529284166020840152921691810191909152606090f35b50346105db5761294b36613e24565b61295793929193614c00565b67ffffffffffffffff8216612979816000526007602052604060002054151590565b156129985750612995929361298f913691613da1565b90614c4b565b80f35b7f1e670e4b000000000000000000000000000000000000000000000000000000008452600452602483fd5b50346105db5760406003193601126105db576129dd613bfb565b906024359067ffffffffffffffff82116105db57602061281d84612a043660048701613e06565b906145a7565b50346105db5760206003193601126105db576004359067ffffffffffffffff82116105db57816004019061010060031984360301126105db5780604051612a5081613cc1565b5280604051612a5e81613cc1565b52606483013560c4840193612a8e612a88612a83612a7c8888614520565b3691613da1565b6148b4565b8361496f565b936084820195612a9d87614571565b73ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116036130b257602483019377ffffffffffffffff00000000000000000000000000000000612b0386614592565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115611a8f578791613093575b5061306b5767ffffffffffffffff612b9786614592565b16612baf816000526007602052604060002054151590565b1561304057602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa908115611a8f578791613021575b5015612ff557612c2685614592565b92612c3c60a4860194612a04612a7c8785614520565b15612fae57612c5d88612c4e8b614571565b612c5789614592565b90615289565b73ffffffffffffffffffffffffffffffffffffffff600354169283612de0575b505050505060440191612c8f83614571565b612c9883614592565b5073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690813b15610ae4576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152602481018690529082908290604490829084905af180156105de57612dcb575b5050608067ffffffffffffffff60209573ffffffffffffffffffffffffffffffffffffffff612d97612d916105467ffc5e3a5bddc11d92c2dc20fae6f7d5eb989f056be35239f7de7e86150609abc097614592565b96614571565b816040519716875233898801521660408601528560608601521692a260405190612dc082613cc1565b815260405190518152f35b612dd6828092613d60565b6105db5780612d3c565b833b156107b557878795938195938c93604051988997889687957f6371157400000000000000000000000000000000000000000000000000000000875260048701606090528d612e308780615372565b60648a0161010090526101648a0190612e4892613fb6565b94612e5290613c12565b67ffffffffffffffff166084890152604401612e6d90613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660a488015260c4870152612e9690613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660e4860152612ebb9084615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c86840301610104870152612ef09291613fb6565b90612efb9083615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c85840301610124860152612f309291613fb6565b9060e48a01612f3e91615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c84840301610144850152612f739291613fb6565b8b602483015282604483015203925af1801561271157908491612f99575b808080612c7d565b81612fa391613d60565b610ae4578238612f91565b83612fb891614520565b61208c6040519283927f24eb47e5000000000000000000000000000000000000000000000000000000008452602060048501526024840191613fb6565b6024867f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b61303a915060203d602011610847576108398183613d60565b38612c17565b7fa9902c7e000000000000000000000000000000000000000000000000000000008752600452602486fd5b6004867f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b6130ac915060203d602011610847576108398183613d60565b38612b80565b60248573ffffffffffffffffffffffffffffffffffffffff61086f8a614571565b50346105db57806003193601126105db57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b50346105db5760406003193601126105db576004359067ffffffffffffffff82116105db57816004019061010060031984360301126105db57613148613afc565b918160405161315681613cc1565b5260648401359360c481019361317b613175612a83612a7c8887614520565b8761496f565b94608483019661318a88614571565b73ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116036135da57602484019477ffffffffffffffff000000000000000000000000000000006131f087614592565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156107c15788916135bb575b506107f75767ffffffffffffffff61328487614592565b1661329c816000526007602052604060002054151590565b156107cc57602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa9081156107c157889161359c575b50156107445761331386614592565b9361332960a4870195612a04612a7c8886614520565b15613592577fffffffff000000000000000000000000000000000000000000000000000000001690811561357757613373896133648c614571565b61336d8a614592565b90615302565b73ffffffffffffffffffffffffffffffffffffffff6003541693846133a6575b50505050505060440191612c8f83614571565b843b1561357357868995938c959387938b6040519a8b998a9889977f6371157400000000000000000000000000000000000000000000000000000000895260048901606090526133f68780615372565b60648b0161010090526101648b019061340e92613fb6565b9461341890613c12565b67ffffffffffffffff1660848a015260440161343390613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660a489015260c488015261345c90613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660e48701526134819084615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c878403016101048801526134b69291613fb6565b906134c19083615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c868403016101248701526134f69291613fb6565b9060e48b0161350491615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c858403016101448601526135399291613fb6565b908c6024840152604483015203925af180156127115761355e575b8080808080613393565b9261356c8160449395613d60565b9290613554565b8880fd5b61358d896135848c614571565b612c578a614592565b613373565b612fb88583614520565b6135b5915060203d602011610847576108398183613d60565b38613304565b6135d4915060203d602011610847576108398183613d60565b3861326d565b60248673ffffffffffffffffffffffffffffffffffffffff61086f8b614571565b50346105db57806003193601126105db57602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105db5760406003193601126105db57613653613bfb565b6024359182151583036105db57610140613716613670858561449d565b6136c660409392935180946fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565b60a08301906fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565bf35b50346105db5760206003193601126105db57602090613735613b5a565b905073ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116146040519015158152f35b50346105db57806003193601126105db57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105db5760c06003193601126105db576137e7613b5a565b506137f0613be4565b6137f8613b7d565b50608435917fffffffff00000000000000000000000000000000000000000000000000000000831683036105db5760a4359067ffffffffffffffff82116105db5760a063ffffffff8061ffff61385d88886138563660048b01613c27565b50506142ed565b95926040979194975197885216602087015216604085015216606083015215156080820152f35b50346105db57806003193601126105db5750611d4e6040516138a7604082613d60565b601b81527f4275726e46726f6d4d696e74546f6b656e506f6f6c20322e302e3000000000006020820152604051918291602083526020830190613c55565b50346105db5760c06003193601126105db576138ff613b5a565b613907613be4565b906064357fffffffff000000000000000000000000000000000000000000000000000000008116810361070f5760843567ffffffffffffffff8111610ffd57613954903690600401613c27565b9160a435936002851015610ff95761396f9560443591613ff5565b90604051918291602083016020845282518091526020604085019301915b81811061399b575050500390f35b825173ffffffffffffffffffffffffffffffffffffffff1684528594506020938401939092019160010161398d565b9050346105e95760206003193601126105e9576020907fffffffff00000000000000000000000000000000000000000000000000000000613a09613ac8565b167faff2afbf000000000000000000000000000000000000000000000000000000008114908115613a9e575b8115613a74575b8115613a4a575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483613a43565b7f0e64dd290000000000000000000000000000000000000000000000000000000081149150613a3c565b7f940a15420000000000000000000000000000000000000000000000000000000081149150613a35565b600435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613af757565b600080fd5b602435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613af757565b604435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613af757565b6004359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b6064359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b6024359067ffffffffffffffff82168203613af757565b6004359067ffffffffffffffff82168203613af757565b359067ffffffffffffffff82168203613af757565b9181601f84011215613af75782359167ffffffffffffffff8311613af75760208381860195010111613af757565b919082519283825260005b848110613c9f5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b80602080928401015182828601015201613c60565b35908115158203613af757565b6020810190811067ffffffffffffffff821117613cdd57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff821117613cdd57604052565b60a0810190811067ffffffffffffffff821117613cdd57604052565b60e0810190811067ffffffffffffffff821117613cdd57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117613cdd57604052565b92919267ffffffffffffffff8211613cdd5760405191613de9601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184613d60565b829481845281830111613af7578281602093846000960137010152565b9080601f83011215613af757816020613e2193359101613da1565b90565b906040600319830112613af75760043567ffffffffffffffff81168103613af757916024359067ffffffffffffffff8211613af757613e6591600401613c27565b9091565b613e21916020613e828351604084526040840190613c55565b920151906020818403910152613c55565b9181601f84011215613af75782359167ffffffffffffffff8311613af7576020808501948460051b010111613af757565b9181601f84011215613af75782359167ffffffffffffffff8311613af7576020808501948460081b010111613af757565b67ffffffffffffffff8111613cdd5760051b60200190565b81810292918115918404141715613f2057565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8115613f59570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b91908203918211613f2057565b519073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b92959390919473ffffffffffffffffffffffffffffffffffffffff600354169586156142cb578097600287101561429c5773ffffffffffffffffffffffffffffffffffffffff98614156957fffffffff0000000000000000000000000000000000000000000000000000000093896142725767ffffffffffffffff8216600052600b6020526040600020906040519161408d83613d44565b549163ffffffff8316815263ffffffff8360201c16602082015263ffffffff8360401c16604082015263ffffffff8360601c16606082015260c061ffff8460801c169182608082015260ff60a082019561ffff8160901c16875260a01c161515918291015261421e575b50505067ffffffffffffffff905b6040519b8c997f06b859ef000000000000000000000000000000000000000000000000000000008b521660048a0152166024880152604487015216606485015260c0608485015260c4840191613fb6565b928180600095869560a483015203915afa91821561421157819261417957505090565b9091503d8083833e61418b8183613d60565b810190602081830312610ae45780519067ffffffffffffffff821161070f570181601f82011215610ae4578051906141c282613ef5565b936141d06040519586613d60565b82855260208086019360051b8301019384116105db5750602001905b8282106141f95750505090565b6020809161420684613f95565b8152019101906141ec565b50604051903d90823e3d90fd5b92935067ffffffffffffffff928587161561425a575061271061424961ffff61425094511683613f0d565b0490613f88565b915b9038806140f7565b61426c92506142496127109183613f0d565b91614252565b67ffffffffffffffff91925061429690614290612a8336898b613da1565b9061496f565b91614105565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b50505050505050506040516142e1602082613d60565b60008152600036813790565b67ffffffffffffffff9092919261432b7fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1685614a7c565b16600052600b60205260406000206040519061434682613d44565b549163ffffffff83169384835263ffffffff8460201c169384602085015263ffffffff8160401c169182604086015263ffffffff8260601c169081606087015261ffff8360801c169586608082015260ff61ffff8560901c16948560a084015260a01c16159060c082159101526143f3577fffffffff00000000000000000000000000000000000000000000000000000000166143e857505093929190600190565b959493509160019150565b5050505092505050600090600090600090600090600090565b6040519061441982613d28565b60006080838281528260208201528260408201528260608201520152565b9060405161444481613d28565b60806001829460ff81546fffffffffffffffffffffffffffffffff8116865263ffffffff81861c16602087015260a01c161515604085015201546fffffffffffffffffffffffffffffffff81166060840152811c910152565b67ffffffffffffffff916144af61440c565b506144b861440c565b506144ec57166000526008602052604060002090613e216144e060026144e56144e086614437565b614b63565b9401614437565b16908160005260046020526145076144e06040600020614437565b916000526005602052613e216144e06040600020614437565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215613af7570180359067ffffffffffffffff8211613af757602001918136038313613af757565b3573ffffffffffffffffffffffffffffffffffffffff81168103613af75790565b3567ffffffffffffffff81168103613af75790565b9067ffffffffffffffff613e2192166000526008602052600560406000200190602081519101209060019160005201602052604060002054151590565b604051906145f182613d0c565b60606020838281520152565b80518210156146115760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600182811c92168015614689575b602083101461465a57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f169161464f565b90604051918260008254926146a784614640565b808452936001811690811561471557506001146146ce575b506146cc92500383613d60565b565b90506000929192526020600020906000915b8183106146f95750509060206146cc92820101386146bf565b60209193508060019154838589010152019101909184926146e0565b602093506146cc9592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b820101386146bf565b67ffffffffffffffff166000526008602052613e216004604060002001614693565b91908110156146115760081b0190565b358015158103613af75790565b3561ffff81168103613af75790565b3563ffffffff81168103613af75790565b359063ffffffff82168203613af757565b359061ffff82168203613af757565b91908110156146115760051b0190565b35906fffffffffffffffffffffffffffffffff82168203613af757565b9190826060910312613af7576040516060810181811067ffffffffffffffff821117613cdd57604052604061485481839561483b81613cb4565b8552614849602082016147e4565b6020860152016147e4565b910152565b6fffffffffffffffffffffffffffffffff6148976040809361487a81613cb4565b151586528361488b602083016147e4565b166020870152016147e4565b16910152565b8181106148a8575050565b6000815560010161489d565b80518015614924576020036148e6578051602082810191830183900312613af757519060ff82116148e6575060ff1690565b61208c906040519182917f953576f7000000000000000000000000000000000000000000000000000000008352602060048401526024830190613c55565b50507f000000000000000000000000000000000000000000000000000000000000000090565b9060ff8091169116039060ff8211613f2057565b60ff16604d8111613f2057600a0a90565b907f00000000000000000000000000000000000000000000000000000000000000009060ff82169060ff811692828414614a7557828411614a4b57906149b49161494a565b91604d60ff8416118015614a12575b6149dc575050906149d6613e219261495e565b90613f0d565b9091507fa9cb113d0000000000000000000000000000000000000000000000000000000060005260045260245260445260646000fd5b50614a1c8361495e565b8015613f59577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0484116149c3565b614a549161494a565b91604d60ff8416116149dc57505090614a6f613e219261495e565b90613f4f565b5050505090565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115614b5e57614aaf816151ae565b7dffff00000000000000000000000000000000000000000000000000000000601082811c9085901c1616614b5e5761ffff8360e01c168015918215614b4d575b5050614af9575050565b7fffffffff0000000000000000000000000000000000000000000000000000000092507fdf63778f000000000000000000000000000000000000000000000000000000006000526004521660245260446000fd5b60e01c61ffff161090503880614aef565b505050565b614b6b61440c565b506fffffffffffffffffffffffffffffffff6060820151166fffffffffffffffffffffffffffffffff8083511691614bc86020850193614bc2614bb563ffffffff87511642613f88565b8560808901511690613f0d565b906151a1565b80821015614be157505b16825263ffffffff4216905290565b9050614bd2565b90816020910312613af757518015158103613af75790565b73ffffffffffffffffffffffffffffffffffffffff600154163303614c2157565b7f2b5c74de0000000000000000000000000000000000000000000000000000000060005260046000fd5b90805115614e8b5767ffffffffffffffff81516020830120921691826000526008602052614c80816005604060002001615805565b15614e475760005260096020526040600020815167ffffffffffffffff8111613cdd57614cad8254614640565b601f8111614e15575b506020601f8211600114614d4f5791614d29827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea9593614d3f95600091614d44575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9055604051918291602083526020830190613c55565b0390a2565b905084015138614cf8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082169083600052806000209160005b818110614dfd575092614d3f9492600192827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea989610614dc6575b5050811b019055611d3a565b8501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690553880614dba565b9192602060018192868a015181550194019201614d7f565b614e4190836000526020600020601f840160051c81019160208510610f3457601f0160051c019061489d565b38614cb6565b509061208c6040519283927f393b8ad20000000000000000000000000000000000000000000000000000000084526004840152604060248401526044830190613c55565b7f14c880ca0000000000000000000000000000000000000000000000000000000060005260046000fd5b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260208152613e21604082613d60565b815191929115615072576fffffffffffffffffffffffffffffffff6040840151166fffffffffffffffffffffffffffffffff6020850151161061500f576146cc91925b805182547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff0000000000000000000000000000000000000000161782556020810151825460409290920151608090811b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691821760018501557fffffffffffffffffffffffff0000000000000000000000000000000000000000909216174290911b73ffffffff0000000000000000000000000000000016179055565b606483615070604051917f8020d12400000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565bfd5b6fffffffffffffffffffffffffffffffff60408401511615801590615101575b6150a0576146cc9192614f33565b606483615070604051917fd68af9cc00000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b506fffffffffffffffffffffffffffffffff6020840151161515615092565b906127109167ffffffffffffffff61513a60208301614592565b166000908152600b60205260409020917fffffffff00000000000000000000000000000000000000000000000000000000161561518b57606061ffff615187935460901c16910135613f0d565b0490565b606061ffff615187935460801c16910135613f0d565b91908201809211613f2057565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115615285577dffff0000000000000000000000000000000000000000000000000000000081161561527c5760ff60015b169060f01c80615246575b506001036152195750565b7fc512f96c0000000000000000000000000000000000000000000000000000000060005260045260246000fd5b60005b60108110615257575061520e565b6001811b821661526a575b600101615249565b9160018101809111613f205791615262565b60ff6000615203565b5050565b9167ffffffffffffffff7f50f6fbee3ceedce6b7fd7eaef18244487867e6718aec7208187efb6b7908c14c9216928360005260086020526152d28183600260406000200161585a565b6040805173ffffffffffffffffffffffffffffffffffffffff909216825260208201929092529081908101614d3f565b91909167ffffffffffffffff83169283600052600560205260ff60406000205460a01c16156153675750907fc6735cd4fa2bbe7b203b1682936e6ee61bc1702464bbbd12abb6630229d9a5f9918360005260056020526152d28183604060002061585a565b906146cc9350615289565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811215613af757016020813591019167ffffffffffffffff8211613af7578136038313613af757565b9167ffffffffffffffff7fff0133389f9bb82d5b9385826160eaf2328039f6fa950eeb8cf0836da81789449216928360005260086020526152d28183604060002061585a565b91909167ffffffffffffffff83169283600052600460205260ff60406000205460a01c161561546d5750907f28d6c52e2b0b7587b0d195539fbe6af984b28791aca4d2cc0844244e38bce29e918360005260046020526152d28183604060002061585a565b906146cc93506153c2565b906040519182815491828252602082019060005260206000209260005b8181106154aa5750506146cc92500383613d60565b8454835260019485019487945060209093019201615495565b80548210156146115760005260206000200190600090565b600081815260076020526040902054801561566a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613f2057600654907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613f20578181036155fb575b50505060065480156155cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016155898160066154c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b19169055600655600052600760205260006040812055600190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b61565261560c61561d9360066154c3565b90549060031b1c92839260066154c3565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b90556000526007602052604060002055388080615550565b5050600090565b906001820191816000528260205260406000205480151560001461579c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613f20578254907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613f2057818103615765575b505050805480156155cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061572682826154c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b191690555560005260205260006040812055600190565b61578561577561561d93866154c3565b90549060031b1c928392866154c3565b9055600052836020526040600020553880806156ee565b50505050600090565b806000526007602052604060002054156000146157ff5760065468010000000000000000811015613cdd576157e661561d82600185940160065560066154c3565b9055600654906000526007602052604060002055600190565b50600090565b600082815260018201602052604090205461566a5780549068010000000000000000821015613cdd578261584361561d8460018096018555846154c3565b905580549260005201602052604060002055600190565b9182549060ff8260a01c16158015615b0e575b615b08576fffffffffffffffffffffffffffffffff821691600185019081546158b263ffffffff6fffffffffffffffffffffffffffffffff83169360801c1642613f88565b9081615a6a575b5050848110615a1e57508383106159135750506158e86fffffffffffffffffffffffffffffffff928392613f88565b16167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055565b9190915460801c9283156159b2578161592b91613f88565b927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190808211613f205761597961597e9273ffffffffffffffffffffffffffffffffffffffff966151a1565b613f4f565b7fd0c8d23a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b73ffffffffffffffffffffffffffffffffffffffff83837fd0c8d23a000000000000000000000000000000000000000000000000000000006000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6004526024521660445260646000fd5b828573ffffffffffffffffffffffffffffffffffffffff927f1a76572a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b828692939611615ade57615a8592614bc29160801c90613f0d565b80841015615ad95750825b85547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff164260801b73ffffffff00000000000000000000000000000000161786559238806158b9565b615a90565b7f9725942a0000000000000000000000000000000000000000000000000000000060005260046000fd5b50505050565b50821561586d56fea164736f6c634300081a000a' as const +// generate:end diff --git a/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts new file mode 100644 index 00000000..a00f5f88 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts @@ -0,0 +1,4 @@ +export default // generate: +// `'${require('fs').readFileSync(require.resolve('@chainlink/contracts-ccip/bytecode/v2_0_0/burn_mint_token_pool.bin'), 'utf8').trim()}' as const` +'0x60e080604052346101f65760a081615db2803803809161001f8285610247565b8339810103126101f65780516001600160a01b038116908190036101f65761004960208301610280565b6100556040840161028e565b9161006e60806100676060870161028e565b950161028e565b93331561023657600180546001600160a01b0319163317905581158015610225575b8015610214575b610203578160805260c052308103610170575b5060a052600380546001600160a01b039283166001600160a01b03199182161790915560028054939092169216919091179055604051615b0f90816102a3823960805181818161023e01528181610491015281816122660152818161243e01528181612aa101528181612c9c0152818161318e0152818161373b0152613795015260a051818181613601015281816149140152818161495e0152614ea8015260c0518181816102d9015281816113eb0152818161230001528181612b3c01526132290152f35b60206004916040519283809263313ce56760e01b82525afa600091816101c2575b50156100aa5760ff1660ff82168181036101ab57506100aa565b6332ad3e0760e11b60005260045260245260446000fd5b9091506020813d6020116101fb575b816101de60209383610247565b810103126101f6576101ef90610280565b9038610191565b600080fd5b3d91506101d1565b630a64406560e11b60005260046000fd5b506001600160a01b03811615610097565b506001600160a01b03851615610090565b639b15e16f60e01b60005260046000fd5b601f909101601f19168101906001600160401b0382119082101761026a57604052565b634e487b7160e01b600052604160045260246000fd5b519060ff821682036101f657565b51906001600160a01b03821682036101f65756fe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a7146139b65750806306b859ef146138d1578063181f5a77146138705780631826b1e7146137b957806321df0da714613768578063240028e8146137045780632422ac451461362557806324f65ee7146135e75780632cab0fb6146130f357806337a3210d146130bf57806339077537146129f65780634c5ef0ed146129af57806362ddd3c4146129285780637437ff9f146128da57806379ba5097146128135780638926f54f146127cd5780638da5cb5b146127995780639a4575b9146121ed578063a42a7b8b14612086578063acfecf9114611f8e578063ae39a25714611e03578063b6cfa3b714611d48578063b794658014611d10578063bfeffd3f14611c64578063c4bffe2b14611b39578063c7230a6014611893578063dc04fa1f1461140f578063dc0bd971146113be578063dcbd41bc146111ba578063e8a1da1714610ade578063ea6396db146109a0578063ec6ae7a71461095d578063f2fde38b1461088e5763fbc801a71461019757600080fd5b346105d15760606003193601126105d1576004359067ffffffffffffffff82116105d1578160040160a060031984360301126105df576101d5613ae8565b9060443567ffffffffffffffff811161070557906101fa610217923690600401613c13565b92906102046145d0565b5061020f858461510c565b933691613d8d565b9260848601936102268561455d565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361084457602487019677ffffffffffffffff0000000000000000000000000000000061028c8961457e565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156107b7578891610815575b506107ed5767ffffffffffffffff6103208961457e565b16610338816000526007602052604060002054151590565b156107c257602073ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156107b7578890610766575b73ffffffffffffffffffffffffffffffffffffffff915016330361073a576064810135936103c78686613f74565b7fffffffff00000000000000000000000000000000000000000000000000000000851694851561071857610423907fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1690614a68565b61043f816104308a61455d565b6104398d61457e565b906153f4565b73ffffffffffffffffffffffffffffffffffffffff6003541693846105e3575b5050505050509061046f91613f74565b916104798461457e565b5073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b156105df578180916024604051809481937f42966c680000000000000000000000000000000000000000000000000000000083528960048401525af180156105d4576105bc575b6105b28461058161057c88877ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff61054261053c8561457e565b9361455d565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252336020830152810188905292169180606081015b0390a261457e565b614741565b9061058a614ea1565b6040519261059784613cf8565b83526020830152604051928392604084526040840190613e55565b9060208301520390f35b6105c7828092613d4c565b6105d157806104fa565b80fd5b6040513d84823e3d90fd5b5080fd5b843b15610714578994928b9694928692604051988997889687957fa8027c0f0000000000000000000000000000000000000000000000000000000087526004870160809052806106329161535e565b6084880160a0905261012488019061064992613fa2565b9261065390613bfe565b67ffffffffffffffff1660a487015260440161066e90613baf565b73ffffffffffffffffffffffffffffffffffffffff1660c48601528d8c60e487015261069990613baf565b73ffffffffffffffffffffffffffffffffffffffff1661010486015260248501528381036003190160448501526106cf91613c41565b90606483015203925af18015610709579085916106f0575b8080808061045f565b816106fa91613d4c565b6107055783386106e7565b8380fd5b6040513d87823e3d90fd5b8980fd5b50610735816107268a61455d565b61072f8d61457e565b906153ae565b61043f565b6024877f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b506020813d6020116107af575b8161078060209383613d4c565b810103126107ab576107a673ffffffffffffffffffffffffffffffffffffffff91613f81565b610399565b8780fd5b3d9150610773565b6040513d8a823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008852600452602487fd5b6004877f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b610837915060203d60201161083d575b61082f8183613d4c565b810190614bd4565b38610309565b503d610825565b60248673ffffffffffffffffffffffffffffffffffffffff6108658861455d565b7f961c9a4f00000000000000000000000000000000000000000000000000000000835216600452fd5b50346105d15760206003193601126105d15773ffffffffffffffffffffffffffffffffffffffff6108bd613b46565b6108c5614bec565b1633811461093557807fffffffffffffffffffffffff000000000000000000000000000000000000000083541617825573ffffffffffffffffffffffffffffffffffffffff600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12788380a380f35b6004827fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b50346105d157806003193601126105d15760207fffffffff0000000000000000000000000000000000000000000000000000000060025460401b16604051908152f35b50346105d15760806003193601126105d1576109ba613b46565b506109c3613bd0565b6109cb613b17565b5060643567ffffffffffffffff8111610ada579167ffffffffffffffff6040926109fb60e0953690600401613c13565b50508260c08551610a0b81613d30565b82815282602082015282878201528260608201528260808201528260a08201520152168152600b6020522060405190610a4382613d30565b5461ffff818163ffffffff82169485815263ffffffff60208201818560201c1681528160408401818760401c168152816060860193818960601c16855260ff60c060808901988a8c60801c168a528a60a082019c60901c168c52019b60a01c1615158b526040519b8c52511660208b0152511660408901525116606087015251166080850152511660a083015251151560c0820152f35b8280fd5b50346105d15760406003193601126105d15760043567ffffffffffffffff81116105df57610b10903690600401613e7f565b9060243567ffffffffffffffff81116107055790610b3384923690600401613e7f565b939091610b3e614bec565b83905b828210610ffb5750505081927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee182360301935b81811015610ff7578060051b83013585811215610ff357830161012081360312610ff35760405194610ba586613d14565b610bae82613bfe565b8652602082013567ffffffffffffffff81116105df5782019436601f870112156105df57853595610bde87613ee1565b96610bec6040519889613d4c565b80885260208089019160051b83010190368211610ff35760208301905b828210610fc0575050505060208701958652604083013567ffffffffffffffff8111610ada57610c3c9036908501613df2565b9160408801928352610c66610c5436606087016147ed565b9460608a0195865260c03691016147ed565b956080890196875283515115610f9857610c8a67ffffffffffffffff8a5116615791565b15610f615767ffffffffffffffff8951168252600860205260408220610cb1865182614edc565b610cbf885160028301614edc565b6004855191019080519067ffffffffffffffff8211610f3457610ce2835461462c565b601f8111610ef9575b50602090601f8311600114610e5a57610d399291869183610e4f575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b90555b815b88518051821015610d735790610d6d600192610d668367ffffffffffffffff8f5116926145e9565b5190614c37565b01610d3e565b5050977f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2939199975095610e4167ffffffffffffffff6001979694985116925193519151610e0d610dd860405196879687526101006020880152610100870190613c41565b9360408601906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b60a08401906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b0390a1019392909193610b74565b015190508e80610d07565b83865281862091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08416875b818110610ee15750908460019594939210610eaa575b505050811b019055610d3c565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558d8080610e9d565b92936020600181928786015181550195019301610e87565b610f249084875260208720601f850160051c81019160208610610f2a575b601f0160051c0190614889565b8d610ceb565b9091508190610f17565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b60248267ffffffffffffffff8b51167f1d5ad3c5000000000000000000000000000000000000000000000000000000008252600452fd5b6004827f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b813567ffffffffffffffff8111610fef57602091610fe48392833691890101613df2565b815201910190610c09565b8680fd5b8480fd5b8380f35b9267ffffffffffffffff61101d6110188486889a9699979a6147c0565b61457e565b1691611028836154c7565b1561118e57828452600860205261104460056040862001615464565b94845b865181101561107d5760019085875260086020526110766005604089200161106f838b6145e9565b519061565d565b5001611047565b50939692909450949094808752600860205260056040882088815588600182015588600282015588600382015588600482016110b9815461462c565b8061114d575b505050018054908881558161112f575b5050907f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599166020836001948a52600482528985604082208281550155808a52600582528985604082208281550155604051908152a101909194939294610b41565b885260208820908101905b818110156110cf5788815560010161113a565b601f81116001146111635750555b888a806110bf565b8183526020832061117e91601f01861c810190600101614889565b808252816020812091555561115b565b602484847f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b50346105d15760206003193601126105d15760043567ffffffffffffffff81116105df576111ec903690600401613eb0565b73ffffffffffffffffffffffffffffffffffffffff600a54163314158061139c575b61137057825b81811061121f578380f35b61122a818385614763565b67ffffffffffffffff61123c8261457e565b1690611255826000526007602052604060002054151590565b1561134457907f41f7c8f7cfdad9350aa495e6c54cbbf750a07ab38a9098aed1256e30dd1682bb60e0836113046112de602060019897018b61129682614773565b1561130b5787905260046020526112bd60408d206112b736604088016147ed565b90614edc565b868c5260056020526112d960408d206112b73660a088016147ed565b614773565b9160405192151583526112f76020840160408301614845565b60a0608084019101614845565ba201611214565b60026040828a6112d99452600860205261132d8282206112b736858c016147ed565b8a8152600860205220016112b73660a088016147ed565b602486837f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b6024837f8e4a23d600000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff6001541633141561120e565b50346105d157806003193601126105d157602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105d15760406003193601126105d15760043567ffffffffffffffff81116105df57611441903690600401613eb0565b60243567ffffffffffffffff811161070557611461903690600401613e7f565b91909261146c614bec565b845b8281106114d857505050825b818110611485578380f35b8067ffffffffffffffff61149f61101860019486886147c0565b16808652600b6020528560408120557f5479bbc0288b7eaeaf2ace0943b88016cc648964fcd42919a86fd93b15fdbee88680a20161147a565b67ffffffffffffffff6114ef611018838686614763565b16611507816000526007602052604060002054151590565b1561186857611517828585614763565b602081019060e081019061152a82614773565b1561183c5760a0810161271061ffff61154283614780565b16101561182d5760c082019161271061ffff61155d85614780565b1610156117f55763ffffffff6115728661478f565b16156117c957858c52600b60205260408c2061158d8661478f565b63ffffffff169080549060408401916115a58361478f565b60201b67ffffffff00000000169360608601946115c18661478f565b60401b6bffffffff00000000000000001696608001966115e08861478f565b60601b6fffffffff00000000000000000000000016916115ff8a614780565b60801b71ffff0000000000000000000000000000000016936116208c614780565b60901b73ffff00000000000000000000000000000000000016957fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016177fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16177fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff16177fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff1617171781556116d387614773565b81547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff00000000000000000000000000000000000000001617905560405196611724906147a0565b63ffffffff168752611735906147a0565b63ffffffff166020870152611749906147a0565b63ffffffff16604086015261175d906147a0565b63ffffffff166060850152611771906147b1565b61ffff166080840152611783906147b1565b61ffff1660a083015261179590613ca0565b151560c082015260e07ffae1e296719dac5269c3886fb5002bb29bf17ae403060c6eb063a55abaaa104191a260010161146e565b60248c877f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b60248c61ffff61180486614780565b7f95f3517a00000000000000000000000000000000000000000000000000000000835216600452fd5b8a61ffff611804602493614780565b60248a857f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b7f1e670e4b000000000000000000000000000000000000000000000000000000008752600452602486fd5b50346105d15760406003193601126105d15760043567ffffffffffffffff81116105df576118c5903690600401613e7f565b906118ce613b8c565b9173ffffffffffffffffffffffffffffffffffffffff6001541633141580611b17575b611aeb5773ffffffffffffffffffffffffffffffffffffffff8316908115611ac357845b818110611920578580f35b73ffffffffffffffffffffffffffffffffffffffff6119486119438385886147c0565b61455d565b166040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152602081602481855afa9081156107b7578891611a90575b508061199d575b5050600101611915565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000602080830191825273ffffffffffffffffffffffffffffffffffffffff8a16602484015260448084018590528352918a91906119fe606482613d4c565b519082865af115611a855787513d611a7c5750813b155b611a505790847f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e602060019594604051908152a39038611993565b602488837f5274afe7000000000000000000000000000000000000000000000000000000008252600452fd5b60011415611a15565b6040513d89823e3d90fd5b905060203d8111611abc575b611aa68183613d4c565b602082600092810103126105d15750513861198c565b503d611a9c565b6004857f8579befe000000000000000000000000000000000000000000000000000000008152fd5b6024847fcb1afbd700000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff600c54163314156118f1565b50346105d157806003193601126105d157604051906006548083528260208101600684526020842092845b818110611c4b575050611b7992500383613d4c565b8151611b9d611b8782613ee1565b91611b956040519384613d4c565b808352613ee1565b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0602083019301368437805b8451811015611bfc578067ffffffffffffffff611be9600193886145e9565b5116611bf582866145e9565b5201611bca565b50925090604051928392602084019060208552518091526040840192915b818110611c28575050500390f35b825167ffffffffffffffff16845285945060209384019390920191600101611c1a565b8454835260019485019487945060209093019201611b64565b50346105d15760206003193601126105d15760043573ffffffffffffffffffffffffffffffffffffffff81168091036105df57611c9f614bec565b7fffffffffffffffffffffffff00000000000000000000000000000000000000006003547fbaff46844acf36d6ee996f489a1a288709c4542bd33cd557770afd267d5812096040805173ffffffffffffffffffffffffffffffffffffffff84168152856020820152a1161760035580f35b50346105d15760206003193601126105d157611d44611d3061057c613be7565b604051918291602083526020830190613c41565b0390f35b50346105d15760206003193601126105d1577f307cf716eade81675bea3ccb6917b0f91baa2160056765d9a83d76f819caf06a6020611d85613ab4565b611d8d614bec565b6002547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff0000000000000000000000000000000000000000808460401c16169116176002557fffffffff0000000000000000000000000000000000000000000000000000000060405191168152a180f35b50346105d15760606003193601126105d157611e1d613b46565b90611e26613b8c565b6044359273ffffffffffffffffffffffffffffffffffffffff841680850361070557611e50614bec565b73ffffffffffffffffffffffffffffffffffffffff82168015611f665794611f60917f3f1036e85d016a93254a0b1415844f79b85424959d90ae5ad51ce8f4533fe70195967fffffffffffffffffffffffff0000000000000000000000000000000000000000600254161760025573ffffffffffffffffffffffffffffffffffffffff85167fffffffffffffffffffffffff0000000000000000000000000000000000000000600a541617600a557fffffffffffffffffffffffff0000000000000000000000000000000000000000600c541617600c556040519384938491604091949373ffffffffffffffffffffffffffffffffffffffff809281606087019816865216602085015216910152565b0390a180f35b6004857f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b50346105d15767ffffffffffffffff611fa636613e10565b929091611fb1614bec565b1691611fca836000526007602052604060002054151590565b1561118e578284526008602052611ff960056040862001611fec368486613d8d565b602081519101209061565d565b1561203e57907f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7691612038604051928392602084526020840191613fa2565b0390a280f35b82612082836040519384937f74f23c7c0000000000000000000000000000000000000000000000000000000085526004850152604060248501526044840191613fa2565b0390fd5b50346105d15760206003193601126105d15767ffffffffffffffff6120a9613be7565b16815260086020526120c060056040832001615464565b80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06121056120ef83613ee1565b926120fd6040519485613d4c565b808452613ee1565b01835b8181106121dc575050825b82518110156121595780612129600192856145e9565b518552600960205261213d6040862061467f565b61214782856145e9565b5261215281846145e9565b5001612113565b81846040519182916020830160208452825180915260408401602060408360051b870101940192905b82821061219157505050500390f35b919360206121cc827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851613c41565b9601920192018594939192612182565b806060602080938601015201612108565b50346105d15760206003193601126105d15760043567ffffffffffffffff81116105df57806004019060a06003198236030112610ada5761222c6145d0565b5060405160209361223d8583613d4c565b808252608483019161224e8361455d565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361277857602484019477ffffffffffffffff000000000000000000000000000000006122b48761457e565b60801b16604051907f2cbc26bb0000000000000000000000000000000000000000000000000000000082526004820152878160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156126fd57849161275b575b506127335767ffffffffffffffff6123478761457e565b1661235f816000526007602052604060002054151590565b15612708578773ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156126fd5784906126b5575b73ffffffffffffffffffffffffffffffffffffffff9150163303612689576064850135946123f9866123f08761455d565b61072f8a61457e565b73ffffffffffffffffffffffffffffffffffffffff60035416918261256c575b505050506124268461457e565b5073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b156105df578180916024604051809481937f42966c680000000000000000000000000000000000000000000000000000000083528960048401525af180156105d457612557575b8561252761057c87877ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff896105746124f06124ea8761457e565b9261455d565b6040805173ffffffffffffffffffffffffffffffffffffffff90921682523360208301528101959095529116929081906060820190565b90612530614ea1565b6040519261253d84613cf8565b835281830152611d44604051928284938452830190613e55565b612562828092613d4c565b6105d157806124a7565b823b15610ff357918791858094604051968795869485937fa8027c0f0000000000000000000000000000000000000000000000000000000085526004850160809052806125b89161535e565b6084860160a090526101248601906125cf92613fa2565b916125d990613bfe565b67ffffffffffffffff1660a48501526044016125f490613baf565b73ffffffffffffffffffffffffffffffffffffffff1660c48401528b60e484015261261e8b613baf565b73ffffffffffffffffffffffffffffffffffffffff1661010484015283602484015282810360031901604484015261265591613c41565b8a606483015203925af180156105d457908291612674575b8080612419565b8161267e91613d4c565b6105d157803861266d565b6024837f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b508781813d83116126f6575b6126cb8183613d4c565b81010312610705576126f173ffffffffffffffffffffffffffffffffffffffff91613f81565b6123bf565b503d6126c1565b6040513d86823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008452600452602483fd5b6004837f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b6127729150883d8a1161083d5761082f8183613d4c565b38612330565b5073ffffffffffffffffffffffffffffffffffffffff61086560249361455d565b50346105d157806003193601126105d157602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b50346105d15760206003193601126105d157602061280967ffffffffffffffff6127f5613be7565b166000526007602052604060002054151590565b6040519015158152f35b50346105d157806003193601126105d157805473ffffffffffffffffffffffffffffffffffffffff811633036128b2577fffffffffffffffffffffffff000000000000000000000000000000000000000060015491338284161760015516825573ffffffffffffffffffffffffffffffffffffffff3391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b6004827f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b50346105d157806003193601126105d157600254600a54600c546040805173ffffffffffffffffffffffffffffffffffffffff94851681529284166020840152921691810191909152606090f35b50346105d15761293736613e10565b61294393929193614bec565b67ffffffffffffffff8216612965816000526007602052604060002054151590565b156129845750612981929361297b913691613d8d565b90614c37565b80f35b7f1e670e4b000000000000000000000000000000000000000000000000000000008452600452602483fd5b50346105d15760406003193601126105d1576129c9613be7565b906024359067ffffffffffffffff82116105d1576020612809846129f03660048701613df2565b90614593565b50346105d15760206003193601126105d1576004359067ffffffffffffffff82116105d157816004019061010060031984360301126105d15780604051612a3c81613cad565b5280604051612a4a81613cad565b52606483013560c4840193612a7a612a74612a6f612a68888861450c565b3691613d8d565b6148a0565b8361495b565b936084820195612a898761455d565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361309e57602483019377ffffffffffffffff00000000000000000000000000000000612aef8661457e565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115611a8557879161307f575b506130575767ffffffffffffffff612b838661457e565b16612b9b816000526007602052604060002054151590565b1561302c57602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa908115611a8557879161300d575b5015612fe157612c128561457e565b92612c2860a48601946129f0612a68878561450c565b15612f9a57612c4988612c3a8b61455d565b612c438961457e565b90615275565b73ffffffffffffffffffffffffffffffffffffffff600354169283612dcc575b505050505060440191612c7b8361455d565b612c848361457e565b5073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690813b15610ada576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152602481018690529082908290604490829084905af180156105d457612db7575b5050608067ffffffffffffffff60209573ffffffffffffffffffffffffffffffffffffffff612d83612d7d61053c7ffc5e3a5bddc11d92c2dc20fae6f7d5eb989f056be35239f7de7e86150609abc09761457e565b9661455d565b816040519716875233898801521660408601528560608601521692a260405190612dac82613cad565b815260405190518152f35b612dc2828092613d4c565b6105d15780612d28565b833b156107ab57878795938195938c93604051988997889687957f6371157400000000000000000000000000000000000000000000000000000000875260048701606090528d612e1c878061535e565b60648a0161010090526101648a0190612e3492613fa2565b94612e3e90613bfe565b67ffffffffffffffff166084890152604401612e5990613baf565b73ffffffffffffffffffffffffffffffffffffffff1660a488015260c4870152612e8290613baf565b73ffffffffffffffffffffffffffffffffffffffff1660e4860152612ea7908461535e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c86840301610104870152612edc9291613fa2565b90612ee7908361535e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c85840301610124860152612f1c9291613fa2565b9060e48a01612f2a9161535e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c84840301610144850152612f5f9291613fa2565b8b602483015282604483015203925af180156126fd57908491612f85575b808080612c69565b81612f8f91613d4c565b610ada578238612f7d565b83612fa49161450c565b6120826040519283927f24eb47e5000000000000000000000000000000000000000000000000000000008452602060048501526024840191613fa2565b6024867f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b613026915060203d60201161083d5761082f8183613d4c565b38612c03565b7fa9902c7e000000000000000000000000000000000000000000000000000000008752600452602486fd5b6004867f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b613098915060203d60201161083d5761082f8183613d4c565b38612b6c565b60248573ffffffffffffffffffffffffffffffffffffffff6108658a61455d565b50346105d157806003193601126105d157602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b50346105d15760406003193601126105d1576004359067ffffffffffffffff82116105d157816004019061010060031984360301126105d157613134613ae8565b918160405161314281613cad565b5260648401359360c4810193613167613161612a6f612a68888761450c565b8761495b565b9460848301966131768861455d565b73ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116036135c657602484019477ffffffffffffffff000000000000000000000000000000006131dc8761457e565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156107b75788916135a7575b506107ed5767ffffffffffffffff6132708761457e565b16613288816000526007602052604060002054151590565b156107c257602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa9081156107b7578891613588575b501561073a576132ff8661457e565b9361331560a48701956129f0612a68888661450c565b1561357e577fffffffff00000000000000000000000000000000000000000000000000000000169081156135635761335f896133508c61455d565b6133598a61457e565b906152ee565b73ffffffffffffffffffffffffffffffffffffffff600354169384613392575b50505050505060440191612c7b8361455d565b843b1561355f57868995938c959387938b6040519a8b998a9889977f6371157400000000000000000000000000000000000000000000000000000000895260048901606090526133e2878061535e565b60648b0161010090526101648b01906133fa92613fa2565b9461340490613bfe565b67ffffffffffffffff1660848a015260440161341f90613baf565b73ffffffffffffffffffffffffffffffffffffffff1660a489015260c488015261344890613baf565b73ffffffffffffffffffffffffffffffffffffffff1660e487015261346d908461535e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c878403016101048801526134a29291613fa2565b906134ad908361535e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c868403016101248701526134e29291613fa2565b9060e48b016134f09161535e565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c858403016101448601526135259291613fa2565b908c6024840152604483015203925af180156126fd5761354a575b808080808061337f565b926135588160449395613d4c565b9290613540565b8880fd5b613579896135708c61455d565b612c438a61457e565b61335f565b612fa4858361450c565b6135a1915060203d60201161083d5761082f8183613d4c565b386132f0565b6135c0915060203d60201161083d5761082f8183613d4c565b38613259565b60248673ffffffffffffffffffffffffffffffffffffffff6108658b61455d565b50346105d157806003193601126105d157602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105d15760406003193601126105d15761363f613be7565b6024359182151583036105d15761014061370261365c8585614489565b6136b260409392935180946fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565b60a08301906fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565bf35b50346105d15760206003193601126105d157602090613721613b46565b905073ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116146040519015158152f35b50346105d157806003193601126105d157602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105d15760c06003193601126105d1576137d3613b46565b506137dc613bd0565b6137e4613b69565b50608435917fffffffff00000000000000000000000000000000000000000000000000000000831683036105d15760a4359067ffffffffffffffff82116105d15760a063ffffffff8061ffff61384988886138423660048b01613c13565b50506142d9565b95926040979194975197885216602087015216604085015216606083015215156080820152f35b50346105d157806003193601126105d15750611d44604051613893604082613d4c565b601781527f4275726e4d696e74546f6b656e506f6f6c20322e302e300000000000000000006020820152604051918291602083526020830190613c41565b50346105d15760c06003193601126105d1576138eb613b46565b6138f3613bd0565b906064357fffffffff00000000000000000000000000000000000000000000000000000000811681036107055760843567ffffffffffffffff8111610ff357613940903690600401613c13565b9160a435936002851015610fef5761395b9560443591613fe1565b90604051918291602083016020845282518091526020604085019301915b818110613987575050500390f35b825173ffffffffffffffffffffffffffffffffffffffff16845285945060209384019390920191600101613979565b9050346105df5760206003193601126105df576020907fffffffff000000000000000000000000000000000000000000000000000000006139f5613ab4565b167faff2afbf000000000000000000000000000000000000000000000000000000008114908115613a8a575b8115613a60575b8115613a36575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483613a2f565b7f0e64dd290000000000000000000000000000000000000000000000000000000081149150613a28565b7f940a15420000000000000000000000000000000000000000000000000000000081149150613a21565b600435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613ae357565b600080fd5b602435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613ae357565b604435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613ae357565b6004359073ffffffffffffffffffffffffffffffffffffffff82168203613ae357565b6064359073ffffffffffffffffffffffffffffffffffffffff82168203613ae357565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203613ae357565b359073ffffffffffffffffffffffffffffffffffffffff82168203613ae357565b6024359067ffffffffffffffff82168203613ae357565b6004359067ffffffffffffffff82168203613ae357565b359067ffffffffffffffff82168203613ae357565b9181601f84011215613ae35782359167ffffffffffffffff8311613ae35760208381860195010111613ae357565b919082519283825260005b848110613c8b5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b80602080928401015182828601015201613c4c565b35908115158203613ae357565b6020810190811067ffffffffffffffff821117613cc957604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff821117613cc957604052565b60a0810190811067ffffffffffffffff821117613cc957604052565b60e0810190811067ffffffffffffffff821117613cc957604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117613cc957604052565b92919267ffffffffffffffff8211613cc95760405191613dd5601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184613d4c565b829481845281830111613ae3578281602093846000960137010152565b9080601f83011215613ae357816020613e0d93359101613d8d565b90565b906040600319830112613ae35760043567ffffffffffffffff81168103613ae357916024359067ffffffffffffffff8211613ae357613e5191600401613c13565b9091565b613e0d916020613e6e8351604084526040840190613c41565b920151906020818403910152613c41565b9181601f84011215613ae35782359167ffffffffffffffff8311613ae3576020808501948460051b010111613ae357565b9181601f84011215613ae35782359167ffffffffffffffff8311613ae3576020808501948460081b010111613ae357565b67ffffffffffffffff8111613cc95760051b60200190565b81810292918115918404141715613f0c57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8115613f45570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b91908203918211613f0c57565b519073ffffffffffffffffffffffffffffffffffffffff82168203613ae357565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b92959390919473ffffffffffffffffffffffffffffffffffffffff600354169586156142b757809760028710156142885773ffffffffffffffffffffffffffffffffffffffff98614142957fffffffff00000000000000000000000000000000000000000000000000000000938961425e5767ffffffffffffffff8216600052600b6020526040600020906040519161407983613d30565b549163ffffffff8316815263ffffffff8360201c16602082015263ffffffff8360401c16604082015263ffffffff8360601c16606082015260c061ffff8460801c169182608082015260ff60a082019561ffff8160901c16875260a01c161515918291015261420a575b50505067ffffffffffffffff905b6040519b8c997f06b859ef000000000000000000000000000000000000000000000000000000008b521660048a0152166024880152604487015216606485015260c0608485015260c4840191613fa2565b928180600095869560a483015203915afa9182156141fd57819261416557505090565b9091503d8083833e6141778183613d4c565b810190602081830312610ada5780519067ffffffffffffffff8211610705570181601f82011215610ada578051906141ae82613ee1565b936141bc6040519586613d4c565b82855260208086019360051b8301019384116105d15750602001905b8282106141e55750505090565b602080916141f284613f81565b8152019101906141d8565b50604051903d90823e3d90fd5b92935067ffffffffffffffff9285871615614246575061271061423561ffff61423c94511683613ef9565b0490613f74565b915b9038806140e3565b61425892506142356127109183613ef9565b9161423e565b67ffffffffffffffff9192506142829061427c612a6f36898b613d8d565b9061495b565b916140f1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b50505050505050506040516142cd602082613d4c565b60008152600036813790565b67ffffffffffffffff909291926143177fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1685614a68565b16600052600b60205260406000206040519061433282613d30565b549163ffffffff83169384835263ffffffff8460201c169384602085015263ffffffff8160401c169182604086015263ffffffff8260601c169081606087015261ffff8360801c169586608082015260ff61ffff8560901c16948560a084015260a01c16159060c082159101526143df577fffffffff00000000000000000000000000000000000000000000000000000000166143d457505093929190600190565b959493509160019150565b5050505092505050600090600090600090600090600090565b6040519061440582613d14565b60006080838281528260208201528260408201528260608201520152565b9060405161443081613d14565b60806001829460ff81546fffffffffffffffffffffffffffffffff8116865263ffffffff81861c16602087015260a01c161515604085015201546fffffffffffffffffffffffffffffffff81166060840152811c910152565b67ffffffffffffffff9161449b6143f8565b506144a46143f8565b506144d857166000526008602052604060002090613e0d6144cc60026144d16144cc86614423565b614b4f565b9401614423565b16908160005260046020526144f36144cc6040600020614423565b916000526005602052613e0d6144cc6040600020614423565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215613ae3570180359067ffffffffffffffff8211613ae357602001918136038313613ae357565b3573ffffffffffffffffffffffffffffffffffffffff81168103613ae35790565b3567ffffffffffffffff81168103613ae35790565b9067ffffffffffffffff613e0d92166000526008602052600560406000200190602081519101209060019160005201602052604060002054151590565b604051906145dd82613cf8565b60606020838281520152565b80518210156145fd5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600182811c92168015614675575b602083101461464657565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f169161463b565b90604051918260008254926146938461462c565b808452936001811690811561470157506001146146ba575b506146b892500383613d4c565b565b90506000929192526020600020906000915b8183106146e55750509060206146b892820101386146ab565b60209193508060019154838589010152019101909184926146cc565b602093506146b89592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b820101386146ab565b67ffffffffffffffff166000526008602052613e0d600460406000200161467f565b91908110156145fd5760081b0190565b358015158103613ae35790565b3561ffff81168103613ae35790565b3563ffffffff81168103613ae35790565b359063ffffffff82168203613ae357565b359061ffff82168203613ae357565b91908110156145fd5760051b0190565b35906fffffffffffffffffffffffffffffffff82168203613ae357565b9190826060910312613ae3576040516060810181811067ffffffffffffffff821117613cc957604052604061484081839561482781613ca0565b8552614835602082016147d0565b6020860152016147d0565b910152565b6fffffffffffffffffffffffffffffffff6148836040809361486681613ca0565b1515865283614877602083016147d0565b166020870152016147d0565b16910152565b818110614894575050565b60008155600101614889565b80518015614910576020036148d2578051602082810191830183900312613ae357519060ff82116148d2575060ff1690565b612082906040519182917f953576f7000000000000000000000000000000000000000000000000000000008352602060048401526024830190613c41565b50507f000000000000000000000000000000000000000000000000000000000000000090565b9060ff8091169116039060ff8211613f0c57565b60ff16604d8111613f0c57600a0a90565b907f00000000000000000000000000000000000000000000000000000000000000009060ff82169060ff811692828414614a6157828411614a3757906149a091614936565b91604d60ff84161180156149fe575b6149c8575050906149c2613e0d9261494a565b90613ef9565b9091507fa9cb113d0000000000000000000000000000000000000000000000000000000060005260045260245260445260646000fd5b50614a088361494a565b8015613f45577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0484116149af565b614a4091614936565b91604d60ff8416116149c857505090614a5b613e0d9261494a565b90613f3b565b5050505090565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115614b4a57614a9b8161519a565b7dffff00000000000000000000000000000000000000000000000000000000601082811c9085901c1616614b4a5761ffff8360e01c168015918215614b39575b5050614ae5575050565b7fffffffff0000000000000000000000000000000000000000000000000000000092507fdf63778f000000000000000000000000000000000000000000000000000000006000526004521660245260446000fd5b60e01c61ffff161090503880614adb565b505050565b614b576143f8565b506fffffffffffffffffffffffffffffffff6060820151166fffffffffffffffffffffffffffffffff8083511691614bb46020850193614bae614ba163ffffffff87511642613f74565b8560808901511690613ef9565b9061518d565b80821015614bcd57505b16825263ffffffff4216905290565b9050614bbe565b90816020910312613ae357518015158103613ae35790565b73ffffffffffffffffffffffffffffffffffffffff600154163303614c0d57565b7f2b5c74de0000000000000000000000000000000000000000000000000000000060005260046000fd5b90805115614e775767ffffffffffffffff81516020830120921691826000526008602052614c6c8160056040600020016157f1565b15614e335760005260096020526040600020815167ffffffffffffffff8111613cc957614c99825461462c565b601f8111614e01575b506020601f8211600114614d3b5791614d15827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea9593614d2b95600091614d30575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9055604051918291602083526020830190613c41565b0390a2565b905084015138614ce4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082169083600052806000209160005b818110614de9575092614d2b9492600192827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea989610614db2575b5050811b019055611d30565b8501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690553880614da6565b9192602060018192868a015181550194019201614d6b565b614e2d90836000526020600020601f840160051c81019160208510610f2a57601f0160051c0190614889565b38614ca2565b50906120826040519283927f393b8ad20000000000000000000000000000000000000000000000000000000084526004840152604060248401526044830190613c41565b7f14c880ca0000000000000000000000000000000000000000000000000000000060005260046000fd5b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260208152613e0d604082613d4c565b81519192911561505e576fffffffffffffffffffffffffffffffff6040840151166fffffffffffffffffffffffffffffffff60208501511610614ffb576146b891925b805182547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff0000000000000000000000000000000000000000161782556020810151825460409290920151608090811b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691821760018501557fffffffffffffffffffffffff0000000000000000000000000000000000000000909216174290911b73ffffffff0000000000000000000000000000000016179055565b60648361505c604051917f8020d12400000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565bfd5b6fffffffffffffffffffffffffffffffff604084015116158015906150ed575b61508c576146b89192614f1f565b60648361505c604051917fd68af9cc00000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b506fffffffffffffffffffffffffffffffff602084015116151561507e565b906127109167ffffffffffffffff6151266020830161457e565b166000908152600b60205260409020917fffffffff00000000000000000000000000000000000000000000000000000000161561517757606061ffff615173935460901c16910135613ef9565b0490565b606061ffff615173935460801c16910135613ef9565b91908201809211613f0c57565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115615271577dffff000000000000000000000000000000000000000000000000000000008116156152685760ff60015b169060f01c80615232575b506001036152055750565b7fc512f96c0000000000000000000000000000000000000000000000000000000060005260045260246000fd5b60005b6010811061524357506151fa565b6001811b8216615256575b600101615235565b9160018101809111613f0c579161524e565b60ff60006151ef565b5050565b9167ffffffffffffffff7f50f6fbee3ceedce6b7fd7eaef18244487867e6718aec7208187efb6b7908c14c9216928360005260086020526152be81836002604060002001615846565b6040805173ffffffffffffffffffffffffffffffffffffffff909216825260208201929092529081908101614d2b565b91909167ffffffffffffffff83169283600052600560205260ff60406000205460a01c16156153535750907fc6735cd4fa2bbe7b203b1682936e6ee61bc1702464bbbd12abb6630229d9a5f9918360005260056020526152be81836040600020615846565b906146b89350615275565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811215613ae357016020813591019167ffffffffffffffff8211613ae3578136038313613ae357565b9167ffffffffffffffff7fff0133389f9bb82d5b9385826160eaf2328039f6fa950eeb8cf0836da81789449216928360005260086020526152be81836040600020615846565b91909167ffffffffffffffff83169283600052600460205260ff60406000205460a01c16156154595750907f28d6c52e2b0b7587b0d195539fbe6af984b28791aca4d2cc0844244e38bce29e918360005260046020526152be81836040600020615846565b906146b893506153ae565b906040519182815491828252602082019060005260206000209260005b8181106154965750506146b892500383613d4c565b8454835260019485019487945060209093019201615481565b80548210156145fd5760005260206000200190600090565b6000818152600760205260409020548015615656577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613f0c57600654907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613f0c578181036155e7575b50505060065480156155b8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016155758160066154af565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b19169055600655600052600760205260006040812055600190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b61563e6155f86156099360066154af565b90549060031b1c92839260066154af565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b9055600052600760205260406000205538808061553c565b5050600090565b9060018201918160005282602052604060002054801515600014615788577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613f0c578254907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613f0c57818103615751575b505050805480156155b8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061571282826154af565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b191690555560005260205260006040812055600190565b61577161576161560993866154af565b90549060031b1c928392866154af565b9055600052836020526040600020553880806156da565b50505050600090565b806000526007602052604060002054156000146157eb5760065468010000000000000000811015613cc9576157d261560982600185940160065560066154af565b9055600654906000526007602052604060002055600190565b50600090565b60008281526001820160205260409020546156565780549068010000000000000000821015613cc9578261582f6156098460018096018555846154af565b905580549260005201602052604060002055600190565b9182549060ff8260a01c16158015615afa575b615af4576fffffffffffffffffffffffffffffffff8216916001850190815461589e63ffffffff6fffffffffffffffffffffffffffffffff83169360801c1642613f74565b9081615a56575b5050848110615a0a57508383106158ff5750506158d46fffffffffffffffffffffffffffffffff928392613f74565b16167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055565b9190915460801c92831561599e578161591791613f74565b927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190808211613f0c5761596561596a9273ffffffffffffffffffffffffffffffffffffffff9661518d565b613f3b565b7fd0c8d23a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b73ffffffffffffffffffffffffffffffffffffffff83837fd0c8d23a000000000000000000000000000000000000000000000000000000006000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6004526024521660445260646000fd5b828573ffffffffffffffffffffffffffffffffffffffff927f1a76572a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b828692939611615aca57615a7192614bae9160801c90613ef9565b80841015615ac55750825b85547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff164260801b73ffffffff00000000000000000000000000000000161786559238806158a5565b615a7c565b7f9725942a0000000000000000000000000000000000000000000000000000000060005260046000fd5b50505050565b50821561585956fea164736f6c634300081a000a' as const +// generate:end diff --git a/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts new file mode 100644 index 00000000..b109a687 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts @@ -0,0 +1,4 @@ +export default // generate: +// `'${require('fs').readFileSync(require.resolve('@chainlink/contracts-ccip/bytecode/v2_0_0/burn_with_from_mint_token_pool.bin'), 'utf8').trim()}' as const` +'0x60e080604052346102aa5760a081615ee1803803809161001f82856102fb565b8339810103126102aa5780516001600160a01b03811691908290036102aa5761004a60208201610334565b61005660408301610342565b9061006f608061006860608601610342565b9401610342565b9233156102ea57600180546001600160a01b03191633179055841580156102d9575b80156102c8575b6102b7578460805260c052308403610220575b60a052600380546001600160a01b039283166001600160a01b0319918216179091556002805493909216921691909117905560405163095ea7b360e01b60208083019182523060248401526000196044808501919091528352906000906101136064856102fb565b83519082865af16000513d82610204575b5050156101bf575b604051615b2390816103be823960805181818161023e01528181610491015281816122700152818161244801528181612ab501528181612cb0015281816131a20152818161374f01526137a9015260a05181818161361501528181614928015281816149720152614ebc015260c0518181816102d9015281816113f50152818161230a01528181612b50015261323d0152f35b6101fd916101f860405163095ea7b360e01b602082015230602482015260006044820152604481526101f26064826102fb565b82610356565b610356565b388061012c565b9091506102185750813b15155b3880610124565b600114610211565b60405163313ce56760e01b8152602081600481885afa60009181610276575b5061024b575b506100ab565b60ff1660ff821681810361025f5750610245565b6332ad3e0760e11b60005260045260245260446000fd5b9091506020813d6020116102af575b81610292602093836102fb565b810103126102aa576102a390610334565b903861023f565b600080fd5b3d9150610285565b630a64406560e11b60005260046000fd5b506001600160a01b03811615610098565b506001600160a01b03841615610091565b639b15e16f60e01b60005260046000fd5b601f909101601f19168101906001600160401b0382119082101761031e57604052565b634e487b7160e01b600052604160045260246000fd5b519060ff821682036102aa57565b51906001600160a01b03821682036102aa57565b906000602091828151910182855af1156103b1576000513d6103a857506001600160a01b0381163b155b6103875750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415610380565b6040513d6000823e3d90fdfe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a7146139ca5750806306b859ef146138e5578063181f5a77146138845780631826b1e7146137cd57806321df0da71461377c578063240028e8146137185780632422ac451461363957806324f65ee7146135fb5780632cab0fb61461310757806337a3210d146130d35780633907753714612a0a5780634c5ef0ed146129c357806362ddd3c41461293c5780637437ff9f146128ee57806379ba5097146128275780638926f54f146127e15780638da5cb5b146127ad5780639a4575b9146121f7578063a42a7b8b14612090578063acfecf9114611f98578063ae39a25714611e0d578063b6cfa3b714611d52578063b794658014611d1a578063bfeffd3f14611c6e578063c4bffe2b14611b43578063c7230a601461189d578063dc04fa1f14611419578063dc0bd971146113c8578063dcbd41bc146111c4578063e8a1da1714610ae8578063ea6396db146109aa578063ec6ae7a714610967578063f2fde38b146108985763fbc801a71461019757600080fd5b346105db5760606003193601126105db576004359067ffffffffffffffff82116105db578160040160a060031984360301126105e9576101d5613afc565b9060443567ffffffffffffffff811161070f57906101fa610217923690600401613c27565b92906102046145e4565b5061020f8584615120565b933691613da1565b92608486019361022685614571565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361084e57602487019677ffffffffffffffff0000000000000000000000000000000061028c89614592565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156107c157889161081f575b506107f75767ffffffffffffffff61032089614592565b16610338816000526007602052604060002054151590565b156107cc57602073ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156107c1578890610770575b73ffffffffffffffffffffffffffffffffffffffff9150163303610744576064810135936103c78686613f88565b7fffffffff00000000000000000000000000000000000000000000000000000000851694851561072257610423907fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1690614a7c565b61043f816104308a614571565b6104398d614592565b90615408565b73ffffffffffffffffffffffffffffffffffffffff6003541693846105ed575b5050505050509061046f91613f88565b9161047984614592565b5073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b156105e9576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018590529082908290604490829084905af180156105de576105c6575b6105bc8461058b61058688877ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff61054c61054685614592565b93614571565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252336020830152810188905292169180606081015b0390a2614592565b614755565b90610594614eb5565b604051926105a184613d0c565b83526020830152604051928392604084526040840190613e69565b9060208301520390f35b6105d1828092613d60565b6105db5780610504565b80fd5b6040513d84823e3d90fd5b5080fd5b843b1561071e578994928b9694928692604051988997889687957fa8027c0f00000000000000000000000000000000000000000000000000000000875260048701608090528061063c91615372565b6084880160a0905261012488019061065392613fb6565b9261065d90613c12565b67ffffffffffffffff1660a487015260440161067890613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660c48601528d8c60e48701526106a390613bc3565b73ffffffffffffffffffffffffffffffffffffffff1661010486015260248501528381036003190160448501526106d991613c55565b90606483015203925af18015610713579085916106fa575b8080808061045f565b8161070491613d60565b61070f5783386106f1565b8380fd5b6040513d87823e3d90fd5b8980fd5b5061073f816107308a614571565b6107398d614592565b906153c2565b61043f565b6024877f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b506020813d6020116107b9575b8161078a60209383613d60565b810103126107b5576107b073ffffffffffffffffffffffffffffffffffffffff91613f95565b610399565b8780fd5b3d915061077d565b6040513d8a823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008852600452602487fd5b6004877f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b610841915060203d602011610847575b6108398183613d60565b810190614be8565b38610309565b503d61082f565b60248673ffffffffffffffffffffffffffffffffffffffff61086f88614571565b7f961c9a4f00000000000000000000000000000000000000000000000000000000835216600452fd5b50346105db5760206003193601126105db5773ffffffffffffffffffffffffffffffffffffffff6108c7613b5a565b6108cf614c00565b1633811461093f57807fffffffffffffffffffffffff000000000000000000000000000000000000000083541617825573ffffffffffffffffffffffffffffffffffffffff600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12788380a380f35b6004827fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b50346105db57806003193601126105db5760207fffffffff0000000000000000000000000000000000000000000000000000000060025460401b16604051908152f35b50346105db5760806003193601126105db576109c4613b5a565b506109cd613be4565b6109d5613b2b565b5060643567ffffffffffffffff8111610ae4579167ffffffffffffffff604092610a0560e0953690600401613c27565b50508260c08551610a1581613d44565b82815282602082015282878201528260608201528260808201528260a08201520152168152600b6020522060405190610a4d82613d44565b5461ffff818163ffffffff82169485815263ffffffff60208201818560201c1681528160408401818760401c168152816060860193818960601c16855260ff60c060808901988a8c60801c168a528a60a082019c60901c168c52019b60a01c1615158b526040519b8c52511660208b0152511660408901525116606087015251166080850152511660a083015251151560c0820152f35b8280fd5b50346105db5760406003193601126105db5760043567ffffffffffffffff81116105e957610b1a903690600401613e93565b9060243567ffffffffffffffff811161070f5790610b3d84923690600401613e93565b939091610b48614c00565b83905b8282106110055750505081927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee182360301935b81811015611001578060051b83013585811215610ffd57830161012081360312610ffd5760405194610baf86613d28565b610bb882613c12565b8652602082013567ffffffffffffffff81116105e95782019436601f870112156105e957853595610be887613ef5565b96610bf66040519889613d60565b80885260208089019160051b83010190368211610ffd5760208301905b828210610fca575050505060208701958652604083013567ffffffffffffffff8111610ae457610c469036908501613e06565b9160408801928352610c70610c5e3660608701614801565b9460608a0195865260c0369101614801565b956080890196875283515115610fa257610c9467ffffffffffffffff8a51166157a5565b15610f6b5767ffffffffffffffff8951168252600860205260408220610cbb865182614ef0565b610cc9885160028301614ef0565b6004855191019080519067ffffffffffffffff8211610f3e57610cec8354614640565b601f8111610f03575b50602090601f8311600114610e6457610d439291869183610e59575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b90555b815b88518051821015610d7d5790610d77600192610d708367ffffffffffffffff8f5116926145fd565b5190614c4b565b01610d48565b5050977f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2939199975095610e4b67ffffffffffffffff6001979694985116925193519151610e17610de260405196879687526101006020880152610100870190613c55565b9360408601906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b60a08401906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b0390a1019392909193610b7e565b015190508e80610d11565b83865281862091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08416875b818110610eeb5750908460019594939210610eb4575b505050811b019055610d46565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558d8080610ea7565b92936020600181928786015181550195019301610e91565b610f2e9084875260208720601f850160051c81019160208610610f34575b601f0160051c019061489d565b8d610cf5565b9091508190610f21565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b60248267ffffffffffffffff8b51167f1d5ad3c5000000000000000000000000000000000000000000000000000000008252600452fd5b6004827f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b813567ffffffffffffffff8111610ff957602091610fee8392833691890101613e06565b815201910190610c13565b8680fd5b8480fd5b8380f35b9267ffffffffffffffff6110276110228486889a9699979a6147d4565b614592565b1691611032836154db565b1561119857828452600860205261104e60056040862001615478565b94845b865181101561108757600190858752600860205261108060056040892001611079838b6145fd565b5190615671565b5001611051565b50939692909450949094808752600860205260056040882088815588600182015588600282015588600382015588600482016110c38154614640565b80611157575b5050500180549088815581611139575b5050907f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599166020836001948a52600482528985604082208281550155808a52600582528985604082208281550155604051908152a101909194939294610b4b565b885260208820908101905b818110156110d957888155600101611144565b601f811160011461116d5750555b888a806110c9565b8183526020832061118891601f01861c81019060010161489d565b8082528160208120915555611165565b602484847f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b50346105db5760206003193601126105db5760043567ffffffffffffffff81116105e9576111f6903690600401613ec4565b73ffffffffffffffffffffffffffffffffffffffff600a5416331415806113a6575b61137a57825b818110611229578380f35b611234818385614777565b67ffffffffffffffff61124682614592565b169061125f826000526007602052604060002054151590565b1561134e57907f41f7c8f7cfdad9350aa495e6c54cbbf750a07ab38a9098aed1256e30dd1682bb60e08361130e6112e8602060019897018b6112a082614787565b156113155787905260046020526112c760408d206112c13660408801614801565b90614ef0565b868c5260056020526112e360408d206112c13660a08801614801565b614787565b9160405192151583526113016020840160408301614859565b60a0608084019101614859565ba20161121e565b60026040828a6112e3945260086020526113378282206112c136858c01614801565b8a8152600860205220016112c13660a08801614801565b602486837f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b6024837f8e4a23d600000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff60015416331415611218565b50346105db57806003193601126105db57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105db5760406003193601126105db5760043567ffffffffffffffff81116105e95761144b903690600401613ec4565b60243567ffffffffffffffff811161070f5761146b903690600401613e93565b919092611476614c00565b845b8281106114e257505050825b81811061148f578380f35b8067ffffffffffffffff6114a961102260019486886147d4565b16808652600b6020528560408120557f5479bbc0288b7eaeaf2ace0943b88016cc648964fcd42919a86fd93b15fdbee88680a201611484565b67ffffffffffffffff6114f9611022838686614777565b16611511816000526007602052604060002054151590565b1561187257611521828585614777565b602081019060e081019061153482614787565b156118465760a0810161271061ffff61154c83614794565b1610156118375760c082019161271061ffff61156785614794565b1610156117ff5763ffffffff61157c866147a3565b16156117d357858c52600b60205260408c20611597866147a3565b63ffffffff169080549060408401916115af836147a3565b60201b67ffffffff00000000169360608601946115cb866147a3565b60401b6bffffffff00000000000000001696608001966115ea886147a3565b60601b6fffffffff00000000000000000000000016916116098a614794565b60801b71ffff00000000000000000000000000000000169361162a8c614794565b60901b73ffff00000000000000000000000000000000000016957fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016177fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16177fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff16177fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff1617171781556116dd87614787565b81547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff0000000000000000000000000000000000000000161790556040519661172e906147b4565b63ffffffff16875261173f906147b4565b63ffffffff166020870152611753906147b4565b63ffffffff166040860152611767906147b4565b63ffffffff16606085015261177b906147c5565b61ffff16608084015261178d906147c5565b61ffff1660a083015261179f90613cb4565b151560c082015260e07ffae1e296719dac5269c3886fb5002bb29bf17ae403060c6eb063a55abaaa104191a2600101611478565b60248c877f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b60248c61ffff61180e86614794565b7f95f3517a00000000000000000000000000000000000000000000000000000000835216600452fd5b8a61ffff61180e602493614794565b60248a857f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b7f1e670e4b000000000000000000000000000000000000000000000000000000008752600452602486fd5b50346105db5760406003193601126105db5760043567ffffffffffffffff81116105e9576118cf903690600401613e93565b906118d8613ba0565b9173ffffffffffffffffffffffffffffffffffffffff6001541633141580611b21575b611af55773ffffffffffffffffffffffffffffffffffffffff8316908115611acd57845b81811061192a578580f35b73ffffffffffffffffffffffffffffffffffffffff61195261194d8385886147d4565b614571565b166040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152602081602481855afa9081156107c1578891611a9a575b50806119a7575b505060010161191f565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000602080830191825273ffffffffffffffffffffffffffffffffffffffff8a16602484015260448084018590528352918a9190611a08606482613d60565b519082865af115611a8f5787513d611a865750813b155b611a5a5790847f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e602060019594604051908152a3903861199d565b602488837f5274afe7000000000000000000000000000000000000000000000000000000008252600452fd5b60011415611a1f565b6040513d89823e3d90fd5b905060203d8111611ac6575b611ab08183613d60565b602082600092810103126105db57505138611996565b503d611aa6565b6004857f8579befe000000000000000000000000000000000000000000000000000000008152fd5b6024847fcb1afbd700000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff600c54163314156118fb565b50346105db57806003193601126105db57604051906006548083528260208101600684526020842092845b818110611c55575050611b8392500383613d60565b8151611ba7611b9182613ef5565b91611b9f6040519384613d60565b808352613ef5565b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0602083019301368437805b8451811015611c06578067ffffffffffffffff611bf3600193886145fd565b5116611bff82866145fd565b5201611bd4565b50925090604051928392602084019060208552518091526040840192915b818110611c32575050500390f35b825167ffffffffffffffff16845285945060209384019390920191600101611c24565b8454835260019485019487945060209093019201611b6e565b50346105db5760206003193601126105db5760043573ffffffffffffffffffffffffffffffffffffffff81168091036105e957611ca9614c00565b7fffffffffffffffffffffffff00000000000000000000000000000000000000006003547fbaff46844acf36d6ee996f489a1a288709c4542bd33cd557770afd267d5812096040805173ffffffffffffffffffffffffffffffffffffffff84168152856020820152a1161760035580f35b50346105db5760206003193601126105db57611d4e611d3a610586613bfb565b604051918291602083526020830190613c55565b0390f35b50346105db5760206003193601126105db577f307cf716eade81675bea3ccb6917b0f91baa2160056765d9a83d76f819caf06a6020611d8f613ac8565b611d97614c00565b6002547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff0000000000000000000000000000000000000000808460401c16169116176002557fffffffff0000000000000000000000000000000000000000000000000000000060405191168152a180f35b50346105db5760606003193601126105db57611e27613b5a565b90611e30613ba0565b6044359273ffffffffffffffffffffffffffffffffffffffff841680850361070f57611e5a614c00565b73ffffffffffffffffffffffffffffffffffffffff82168015611f705794611f6a917f3f1036e85d016a93254a0b1415844f79b85424959d90ae5ad51ce8f4533fe70195967fffffffffffffffffffffffff0000000000000000000000000000000000000000600254161760025573ffffffffffffffffffffffffffffffffffffffff85167fffffffffffffffffffffffff0000000000000000000000000000000000000000600a541617600a557fffffffffffffffffffffffff0000000000000000000000000000000000000000600c541617600c556040519384938491604091949373ffffffffffffffffffffffffffffffffffffffff809281606087019816865216602085015216910152565b0390a180f35b6004857f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b50346105db5767ffffffffffffffff611fb036613e24565b929091611fbb614c00565b1691611fd4836000526007602052604060002054151590565b1561119857828452600860205261200360056040862001611ff6368486613da1565b6020815191012090615671565b1561204857907f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7691612042604051928392602084526020840191613fb6565b0390a280f35b8261208c836040519384937f74f23c7c0000000000000000000000000000000000000000000000000000000085526004850152604060248501526044840191613fb6565b0390fd5b50346105db5760206003193601126105db5767ffffffffffffffff6120b3613bfb565b16815260086020526120ca60056040832001615478565b80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061210f6120f983613ef5565b926121076040519485613d60565b808452613ef5565b01835b8181106121e6575050825b82518110156121635780612133600192856145fd565b518552600960205261214760408620614693565b61215182856145fd565b5261215c81846145fd565b500161211d565b81846040519182916020830160208452825180915260408401602060408360051b870101940192905b82821061219b57505050500390f35b919360206121d6827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851613c55565b960192019201859493919261218c565b806060602080938601015201612112565b50346105db5760206003193601126105db5760043567ffffffffffffffff81116105e957806004019060a06003198236030112610ae4576122366145e4565b506040516020936122478583613d60565b808252608483019161225883614571565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361278c57602484019477ffffffffffffffff000000000000000000000000000000006122be87614592565b60801b16604051907f2cbc26bb0000000000000000000000000000000000000000000000000000000082526004820152878160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa90811561271157849161276f575b506127475767ffffffffffffffff61235187614592565b16612369816000526007602052604060002054151590565b1561271c578773ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156127115784906126c9575b73ffffffffffffffffffffffffffffffffffffffff915016330361269d57606485013594612403866123fa87614571565b6107398a614592565b73ffffffffffffffffffffffffffffffffffffffff600354169182612580575b5050505061243084614592565b5073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b156105e9576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152306004820152602481018590529082908290604490829084905af180156105de5761256b575b8561253b61058687877ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff8961057e6125046124fe87614592565b92614571565b6040805173ffffffffffffffffffffffffffffffffffffffff90921682523360208301528101959095529116929081906060820190565b90612544614eb5565b6040519261255184613d0c565b835281830152611d4e604051928284938452830190613e69565b612576828092613d60565b6105db57806124bb565b823b15610ffd57918791858094604051968795869485937fa8027c0f0000000000000000000000000000000000000000000000000000000085526004850160809052806125cc91615372565b6084860160a090526101248601906125e392613fb6565b916125ed90613c12565b67ffffffffffffffff1660a485015260440161260890613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660c48401528b60e48401526126328b613bc3565b73ffffffffffffffffffffffffffffffffffffffff1661010484015283602484015282810360031901604484015261266991613c55565b8a606483015203925af180156105de57908291612688575b8080612423565b8161269291613d60565b6105db578038612681565b6024837f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b508781813d831161270a575b6126df8183613d60565b8101031261070f5761270573ffffffffffffffffffffffffffffffffffffffff91613f95565b6123c9565b503d6126d5565b6040513d86823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008452600452602483fd5b6004837f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b6127869150883d8a11610847576108398183613d60565b3861233a565b5073ffffffffffffffffffffffffffffffffffffffff61086f602493614571565b50346105db57806003193601126105db57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b50346105db5760206003193601126105db57602061281d67ffffffffffffffff612809613bfb565b166000526007602052604060002054151590565b6040519015158152f35b50346105db57806003193601126105db57805473ffffffffffffffffffffffffffffffffffffffff811633036128c6577fffffffffffffffffffffffff000000000000000000000000000000000000000060015491338284161760015516825573ffffffffffffffffffffffffffffffffffffffff3391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b6004827f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b50346105db57806003193601126105db57600254600a54600c546040805173ffffffffffffffffffffffffffffffffffffffff94851681529284166020840152921691810191909152606090f35b50346105db5761294b36613e24565b61295793929193614c00565b67ffffffffffffffff8216612979816000526007602052604060002054151590565b156129985750612995929361298f913691613da1565b90614c4b565b80f35b7f1e670e4b000000000000000000000000000000000000000000000000000000008452600452602483fd5b50346105db5760406003193601126105db576129dd613bfb565b906024359067ffffffffffffffff82116105db57602061281d84612a043660048701613e06565b906145a7565b50346105db5760206003193601126105db576004359067ffffffffffffffff82116105db57816004019061010060031984360301126105db5780604051612a5081613cc1565b5280604051612a5e81613cc1565b52606483013560c4840193612a8e612a88612a83612a7c8888614520565b3691613da1565b6148b4565b8361496f565b936084820195612a9d87614571565b73ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116036130b257602483019377ffffffffffffffff00000000000000000000000000000000612b0386614592565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115611a8f578791613093575b5061306b5767ffffffffffffffff612b9786614592565b16612baf816000526007602052604060002054151590565b1561304057602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa908115611a8f578791613021575b5015612ff557612c2685614592565b92612c3c60a4860194612a04612a7c8785614520565b15612fae57612c5d88612c4e8b614571565b612c5789614592565b90615289565b73ffffffffffffffffffffffffffffffffffffffff600354169283612de0575b505050505060440191612c8f83614571565b612c9883614592565b5073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690813b15610ae4576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152602481018690529082908290604490829084905af180156105de57612dcb575b5050608067ffffffffffffffff60209573ffffffffffffffffffffffffffffffffffffffff612d97612d916105467ffc5e3a5bddc11d92c2dc20fae6f7d5eb989f056be35239f7de7e86150609abc097614592565b96614571565b816040519716875233898801521660408601528560608601521692a260405190612dc082613cc1565b815260405190518152f35b612dd6828092613d60565b6105db5780612d3c565b833b156107b557878795938195938c93604051988997889687957f6371157400000000000000000000000000000000000000000000000000000000875260048701606090528d612e308780615372565b60648a0161010090526101648a0190612e4892613fb6565b94612e5290613c12565b67ffffffffffffffff166084890152604401612e6d90613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660a488015260c4870152612e9690613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660e4860152612ebb9084615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c86840301610104870152612ef09291613fb6565b90612efb9083615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c85840301610124860152612f309291613fb6565b9060e48a01612f3e91615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c84840301610144850152612f739291613fb6565b8b602483015282604483015203925af1801561271157908491612f99575b808080612c7d565b81612fa391613d60565b610ae4578238612f91565b83612fb891614520565b61208c6040519283927f24eb47e5000000000000000000000000000000000000000000000000000000008452602060048501526024840191613fb6565b6024867f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b61303a915060203d602011610847576108398183613d60565b38612c17565b7fa9902c7e000000000000000000000000000000000000000000000000000000008752600452602486fd5b6004867f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b6130ac915060203d602011610847576108398183613d60565b38612b80565b60248573ffffffffffffffffffffffffffffffffffffffff61086f8a614571565b50346105db57806003193601126105db57602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b50346105db5760406003193601126105db576004359067ffffffffffffffff82116105db57816004019061010060031984360301126105db57613148613afc565b918160405161315681613cc1565b5260648401359360c481019361317b613175612a83612a7c8887614520565b8761496f565b94608483019661318a88614571565b73ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116036135da57602484019477ffffffffffffffff000000000000000000000000000000006131f087614592565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156107c15788916135bb575b506107f75767ffffffffffffffff61328487614592565b1661329c816000526007602052604060002054151590565b156107cc57602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa9081156107c157889161359c575b50156107445761331386614592565b9361332960a4870195612a04612a7c8886614520565b15613592577fffffffff000000000000000000000000000000000000000000000000000000001690811561357757613373896133648c614571565b61336d8a614592565b90615302565b73ffffffffffffffffffffffffffffffffffffffff6003541693846133a6575b50505050505060440191612c8f83614571565b843b1561357357868995938c959387938b6040519a8b998a9889977f6371157400000000000000000000000000000000000000000000000000000000895260048901606090526133f68780615372565b60648b0161010090526101648b019061340e92613fb6565b9461341890613c12565b67ffffffffffffffff1660848a015260440161343390613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660a489015260c488015261345c90613bc3565b73ffffffffffffffffffffffffffffffffffffffff1660e48701526134819084615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c878403016101048801526134b69291613fb6565b906134c19083615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c868403016101248701526134f69291613fb6565b9060e48b0161350491615372565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c858403016101448601526135399291613fb6565b908c6024840152604483015203925af180156127115761355e575b8080808080613393565b9261356c8160449395613d60565b9290613554565b8880fd5b61358d896135848c614571565b612c578a614592565b613373565b612fb88583614520565b6135b5915060203d602011610847576108398183613d60565b38613304565b6135d4915060203d602011610847576108398183613d60565b3861326d565b60248673ffffffffffffffffffffffffffffffffffffffff61086f8b614571565b50346105db57806003193601126105db57602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105db5760406003193601126105db57613653613bfb565b6024359182151583036105db57610140613716613670858561449d565b6136c660409392935180946fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565b60a08301906fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565bf35b50346105db5760206003193601126105db57602090613735613b5a565b905073ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116146040519015158152f35b50346105db57806003193601126105db57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346105db5760c06003193601126105db576137e7613b5a565b506137f0613be4565b6137f8613b7d565b50608435917fffffffff00000000000000000000000000000000000000000000000000000000831683036105db5760a4359067ffffffffffffffff82116105db5760a063ffffffff8061ffff61385d88886138563660048b01613c27565b50506142ed565b95926040979194975197885216602087015216604085015216606083015215156080820152f35b50346105db57806003193601126105db5750611d4e6040516138a7604082613d60565b601f81527f4275726e5769746846726f6d4d696e74546f6b656e506f6f6c20322e302e30006020820152604051918291602083526020830190613c55565b50346105db5760c06003193601126105db576138ff613b5a565b613907613be4565b906064357fffffffff000000000000000000000000000000000000000000000000000000008116810361070f5760843567ffffffffffffffff8111610ffd57613954903690600401613c27565b9160a435936002851015610ff95761396f9560443591613ff5565b90604051918291602083016020845282518091526020604085019301915b81811061399b575050500390f35b825173ffffffffffffffffffffffffffffffffffffffff1684528594506020938401939092019160010161398d565b9050346105e95760206003193601126105e9576020907fffffffff00000000000000000000000000000000000000000000000000000000613a09613ac8565b167faff2afbf000000000000000000000000000000000000000000000000000000008114908115613a9e575b8115613a74575b8115613a4a575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483613a43565b7f0e64dd290000000000000000000000000000000000000000000000000000000081149150613a3c565b7f940a15420000000000000000000000000000000000000000000000000000000081149150613a35565b600435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613af757565b600080fd5b602435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613af757565b604435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613af757565b6004359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b6064359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b359073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b6024359067ffffffffffffffff82168203613af757565b6004359067ffffffffffffffff82168203613af757565b359067ffffffffffffffff82168203613af757565b9181601f84011215613af75782359167ffffffffffffffff8311613af75760208381860195010111613af757565b919082519283825260005b848110613c9f5750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b80602080928401015182828601015201613c60565b35908115158203613af757565b6020810190811067ffffffffffffffff821117613cdd57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff821117613cdd57604052565b60a0810190811067ffffffffffffffff821117613cdd57604052565b60e0810190811067ffffffffffffffff821117613cdd57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117613cdd57604052565b92919267ffffffffffffffff8211613cdd5760405191613de9601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184613d60565b829481845281830111613af7578281602093846000960137010152565b9080601f83011215613af757816020613e2193359101613da1565b90565b906040600319830112613af75760043567ffffffffffffffff81168103613af757916024359067ffffffffffffffff8211613af757613e6591600401613c27565b9091565b613e21916020613e828351604084526040840190613c55565b920151906020818403910152613c55565b9181601f84011215613af75782359167ffffffffffffffff8311613af7576020808501948460051b010111613af757565b9181601f84011215613af75782359167ffffffffffffffff8311613af7576020808501948460081b010111613af757565b67ffffffffffffffff8111613cdd5760051b60200190565b81810292918115918404141715613f2057565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8115613f59570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b91908203918211613f2057565b519073ffffffffffffffffffffffffffffffffffffffff82168203613af757565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b92959390919473ffffffffffffffffffffffffffffffffffffffff600354169586156142cb578097600287101561429c5773ffffffffffffffffffffffffffffffffffffffff98614156957fffffffff0000000000000000000000000000000000000000000000000000000093896142725767ffffffffffffffff8216600052600b6020526040600020906040519161408d83613d44565b549163ffffffff8316815263ffffffff8360201c16602082015263ffffffff8360401c16604082015263ffffffff8360601c16606082015260c061ffff8460801c169182608082015260ff60a082019561ffff8160901c16875260a01c161515918291015261421e575b50505067ffffffffffffffff905b6040519b8c997f06b859ef000000000000000000000000000000000000000000000000000000008b521660048a0152166024880152604487015216606485015260c0608485015260c4840191613fb6565b928180600095869560a483015203915afa91821561421157819261417957505090565b9091503d8083833e61418b8183613d60565b810190602081830312610ae45780519067ffffffffffffffff821161070f570181601f82011215610ae4578051906141c282613ef5565b936141d06040519586613d60565b82855260208086019360051b8301019384116105db5750602001905b8282106141f95750505090565b6020809161420684613f95565b8152019101906141ec565b50604051903d90823e3d90fd5b92935067ffffffffffffffff928587161561425a575061271061424961ffff61425094511683613f0d565b0490613f88565b915b9038806140f7565b61426c92506142496127109183613f0d565b91614252565b67ffffffffffffffff91925061429690614290612a8336898b613da1565b9061496f565b91614105565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b50505050505050506040516142e1602082613d60565b60008152600036813790565b67ffffffffffffffff9092919261432b7fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1685614a7c565b16600052600b60205260406000206040519061434682613d44565b549163ffffffff83169384835263ffffffff8460201c169384602085015263ffffffff8160401c169182604086015263ffffffff8260601c169081606087015261ffff8360801c169586608082015260ff61ffff8560901c16948560a084015260a01c16159060c082159101526143f3577fffffffff00000000000000000000000000000000000000000000000000000000166143e857505093929190600190565b959493509160019150565b5050505092505050600090600090600090600090600090565b6040519061441982613d28565b60006080838281528260208201528260408201528260608201520152565b9060405161444481613d28565b60806001829460ff81546fffffffffffffffffffffffffffffffff8116865263ffffffff81861c16602087015260a01c161515604085015201546fffffffffffffffffffffffffffffffff81166060840152811c910152565b67ffffffffffffffff916144af61440c565b506144b861440c565b506144ec57166000526008602052604060002090613e216144e060026144e56144e086614437565b614b63565b9401614437565b16908160005260046020526145076144e06040600020614437565b916000526005602052613e216144e06040600020614437565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215613af7570180359067ffffffffffffffff8211613af757602001918136038313613af757565b3573ffffffffffffffffffffffffffffffffffffffff81168103613af75790565b3567ffffffffffffffff81168103613af75790565b9067ffffffffffffffff613e2192166000526008602052600560406000200190602081519101209060019160005201602052604060002054151590565b604051906145f182613d0c565b60606020838281520152565b80518210156146115760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600182811c92168015614689575b602083101461465a57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f169161464f565b90604051918260008254926146a784614640565b808452936001811690811561471557506001146146ce575b506146cc92500383613d60565b565b90506000929192526020600020906000915b8183106146f95750509060206146cc92820101386146bf565b60209193508060019154838589010152019101909184926146e0565b602093506146cc9592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b820101386146bf565b67ffffffffffffffff166000526008602052613e216004604060002001614693565b91908110156146115760081b0190565b358015158103613af75790565b3561ffff81168103613af75790565b3563ffffffff81168103613af75790565b359063ffffffff82168203613af757565b359061ffff82168203613af757565b91908110156146115760051b0190565b35906fffffffffffffffffffffffffffffffff82168203613af757565b9190826060910312613af7576040516060810181811067ffffffffffffffff821117613cdd57604052604061485481839561483b81613cb4565b8552614849602082016147e4565b6020860152016147e4565b910152565b6fffffffffffffffffffffffffffffffff6148976040809361487a81613cb4565b151586528361488b602083016147e4565b166020870152016147e4565b16910152565b8181106148a8575050565b6000815560010161489d565b80518015614924576020036148e6578051602082810191830183900312613af757519060ff82116148e6575060ff1690565b61208c906040519182917f953576f7000000000000000000000000000000000000000000000000000000008352602060048401526024830190613c55565b50507f000000000000000000000000000000000000000000000000000000000000000090565b9060ff8091169116039060ff8211613f2057565b60ff16604d8111613f2057600a0a90565b907f00000000000000000000000000000000000000000000000000000000000000009060ff82169060ff811692828414614a7557828411614a4b57906149b49161494a565b91604d60ff8416118015614a12575b6149dc575050906149d6613e219261495e565b90613f0d565b9091507fa9cb113d0000000000000000000000000000000000000000000000000000000060005260045260245260445260646000fd5b50614a1c8361495e565b8015613f59577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0484116149c3565b614a549161494a565b91604d60ff8416116149dc57505090614a6f613e219261495e565b90613f4f565b5050505090565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115614b5e57614aaf816151ae565b7dffff00000000000000000000000000000000000000000000000000000000601082811c9085901c1616614b5e5761ffff8360e01c168015918215614b4d575b5050614af9575050565b7fffffffff0000000000000000000000000000000000000000000000000000000092507fdf63778f000000000000000000000000000000000000000000000000000000006000526004521660245260446000fd5b60e01c61ffff161090503880614aef565b505050565b614b6b61440c565b506fffffffffffffffffffffffffffffffff6060820151166fffffffffffffffffffffffffffffffff8083511691614bc86020850193614bc2614bb563ffffffff87511642613f88565b8560808901511690613f0d565b906151a1565b80821015614be157505b16825263ffffffff4216905290565b9050614bd2565b90816020910312613af757518015158103613af75790565b73ffffffffffffffffffffffffffffffffffffffff600154163303614c2157565b7f2b5c74de0000000000000000000000000000000000000000000000000000000060005260046000fd5b90805115614e8b5767ffffffffffffffff81516020830120921691826000526008602052614c80816005604060002001615805565b15614e475760005260096020526040600020815167ffffffffffffffff8111613cdd57614cad8254614640565b601f8111614e15575b506020601f8211600114614d4f5791614d29827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea9593614d3f95600091614d44575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9055604051918291602083526020830190613c55565b0390a2565b905084015138614cf8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082169083600052806000209160005b818110614dfd575092614d3f9492600192827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea989610614dc6575b5050811b019055611d3a565b8501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690553880614dba565b9192602060018192868a015181550194019201614d7f565b614e4190836000526020600020601f840160051c81019160208510610f3457601f0160051c019061489d565b38614cb6565b509061208c6040519283927f393b8ad20000000000000000000000000000000000000000000000000000000084526004840152604060248401526044830190613c55565b7f14c880ca0000000000000000000000000000000000000000000000000000000060005260046000fd5b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260208152613e21604082613d60565b815191929115615072576fffffffffffffffffffffffffffffffff6040840151166fffffffffffffffffffffffffffffffff6020850151161061500f576146cc91925b805182547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff0000000000000000000000000000000000000000161782556020810151825460409290920151608090811b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691821760018501557fffffffffffffffffffffffff0000000000000000000000000000000000000000909216174290911b73ffffffff0000000000000000000000000000000016179055565b606483615070604051917f8020d12400000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565bfd5b6fffffffffffffffffffffffffffffffff60408401511615801590615101575b6150a0576146cc9192614f33565b606483615070604051917fd68af9cc00000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b506fffffffffffffffffffffffffffffffff6020840151161515615092565b906127109167ffffffffffffffff61513a60208301614592565b166000908152600b60205260409020917fffffffff00000000000000000000000000000000000000000000000000000000161561518b57606061ffff615187935460901c16910135613f0d565b0490565b606061ffff615187935460801c16910135613f0d565b91908201809211613f2057565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115615285577dffff0000000000000000000000000000000000000000000000000000000081161561527c5760ff60015b169060f01c80615246575b506001036152195750565b7fc512f96c0000000000000000000000000000000000000000000000000000000060005260045260246000fd5b60005b60108110615257575061520e565b6001811b821661526a575b600101615249565b9160018101809111613f205791615262565b60ff6000615203565b5050565b9167ffffffffffffffff7f50f6fbee3ceedce6b7fd7eaef18244487867e6718aec7208187efb6b7908c14c9216928360005260086020526152d28183600260406000200161585a565b6040805173ffffffffffffffffffffffffffffffffffffffff909216825260208201929092529081908101614d3f565b91909167ffffffffffffffff83169283600052600560205260ff60406000205460a01c16156153675750907fc6735cd4fa2bbe7b203b1682936e6ee61bc1702464bbbd12abb6630229d9a5f9918360005260056020526152d28183604060002061585a565b906146cc9350615289565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811215613af757016020813591019167ffffffffffffffff8211613af7578136038313613af757565b9167ffffffffffffffff7fff0133389f9bb82d5b9385826160eaf2328039f6fa950eeb8cf0836da81789449216928360005260086020526152d28183604060002061585a565b91909167ffffffffffffffff83169283600052600460205260ff60406000205460a01c161561546d5750907f28d6c52e2b0b7587b0d195539fbe6af984b28791aca4d2cc0844244e38bce29e918360005260046020526152d28183604060002061585a565b906146cc93506153c2565b906040519182815491828252602082019060005260206000209260005b8181106154aa5750506146cc92500383613d60565b8454835260019485019487945060209093019201615495565b80548210156146115760005260206000200190600090565b600081815260076020526040902054801561566a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613f2057600654907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613f20578181036155fb575b50505060065480156155cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016155898160066154c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b19169055600655600052600760205260006040812055600190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b61565261560c61561d9360066154c3565b90549060031b1c92839260066154c3565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b90556000526007602052604060002055388080615550565b5050600090565b906001820191816000528260205260406000205480151560001461579c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613f20578254907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613f2057818103615765575b505050805480156155cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019061572682826154c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b191690555560005260205260006040812055600190565b61578561577561561d93866154c3565b90549060031b1c928392866154c3565b9055600052836020526040600020553880806156ee565b50505050600090565b806000526007602052604060002054156000146157ff5760065468010000000000000000811015613cdd576157e661561d82600185940160065560066154c3565b9055600654906000526007602052604060002055600190565b50600090565b600082815260018201602052604090205461566a5780549068010000000000000000821015613cdd578261584361561d8460018096018555846154c3565b905580549260005201602052604060002055600190565b9182549060ff8260a01c16158015615b0e575b615b08576fffffffffffffffffffffffffffffffff821691600185019081546158b263ffffffff6fffffffffffffffffffffffffffffffff83169360801c1642613f88565b9081615a6a575b5050848110615a1e57508383106159135750506158e86fffffffffffffffffffffffffffffffff928392613f88565b16167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055565b9190915460801c9283156159b2578161592b91613f88565b927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190808211613f205761597961597e9273ffffffffffffffffffffffffffffffffffffffff966151a1565b613f4f565b7fd0c8d23a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b73ffffffffffffffffffffffffffffffffffffffff83837fd0c8d23a000000000000000000000000000000000000000000000000000000006000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6004526024521660445260646000fd5b828573ffffffffffffffffffffffffffffffffffffffff927f1a76572a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b828692939611615ade57615a8592614bc29160801c90613f0d565b80841015615ad95750825b85547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff164260801b73ffffffff00000000000000000000000000000000161786559238806158b9565b615a90565b7f9725942a0000000000000000000000000000000000000000000000000000000060005260046000fd5b50505050565b50821561586d56fea164736f6c634300081a000a' as const +// generate:end diff --git a/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/cross-chain-token.ts b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/cross-chain-token.ts new file mode 100644 index 00000000..52ca7b62 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/cross-chain-token.ts @@ -0,0 +1,4 @@ +export default // generate: +// `'${require('fs').readFileSync(require.resolve('@chainlink/contracts-ccip/bytecode/v2_0_0/cross_chain_token.bin'), 'utf8').trim()}' as const` +'0x60c06040523461072757612e58803803806100198161072c565b92833981016060828203126107275781516001600160401b03811161072757820160e081830312610727576040519160e083016001600160401b0381118482101761061e5760405281516001600160401b038111610727578161007d918401610751565b83526020820151906001600160401b0382116107275761009e918301610751565b9081602084015260408101519060408401918252606081015191606085019283526100cb608083016107bc565b916080860192835260a08101519060ff821682036107275760c06100f69160a08901938452016107bc565b9460c08701958652610116604061010f60208b016107bc565b99016107bc565b6001600160a01b038116610721575033965b518051906001600160401b03821161061e5760035490600182811c92168015610717575b60208310146105fe5781601f8493116106a7575b50602090601f831160011461063f57600092610634575b50508160011b916000199060031b1c1916176003555b8051906001600160401b03821161061e57600454600181811c91168015610614575b60208210146105fe57601f8111610599575b50602090601f831160011461052d5760ff93929160009183610522575b50508160011b916000199060031b1c1916176004555b51166080525160a0528151156104f75780516001600160a01b0316156104e657519051906001600160a01b031680156104d0573081146104bc57600254918083018093116104a6576020926002557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600093849284845283825260408420818154019055604051908152a360a05180610480575b50505b516001600160a01b03168061047b5750335b600580546001600160a01b039283166001600160a01b0319821681179092559091167f9524c9e4b0b61eb018dd58a1cd856e3e74009528328ab4a613b434fa631d7242600080a36001600160a01b0381161561046557600780546001600160d01b0316905561030b906107d0565b506001600160a01b038116610455575b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6600081815260066020527f3195c024b2ddd6d9b8f6c836aa52f67fe69376c8903d009b80229b3ce4425f528054600080516020612e3883398151915291829055909290917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9080a47f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848600081815260066020527f42d20fd6db25ea5a8e33f43724ad72f2ebd9488257fa78c86176b8175fc383fb8054600080516020612e3883398151915291829055909290917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9080a460405161257990816108bf823960805181611417015260a051818181610330015261113a0152f35b61045e9061081b565b503861031b565b636116401160e11b600052600060045260246000fd5b61029d565b6002548181116104905750610288565b637502c12360e11b835260045260245260449150fd5b634e487b7160e01b600052601160045260246000fd5b63ec442f0560e01b60005260045260246000fd5b63ec442f0560e01b600052600060045260246000fd5b634dd371db60e11b60005260046000fd5b516001600160a01b031690508061050e575061028b565b63f5c8f5a160e01b60005260045260246000fd5b0151905038806101de565b90601f198316916004600052816000209260005b818110610581575091600193918560ff97969410610568575b505050811b016004556101f4565b015160001960f88460031b161c1916905538808061055a565b92936020600181928786015181550195019301610541565b60046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f840160051c810191602085106105f4575b601f0160051c01905b8181106105e857506101c1565b600081556001016105db565b90915081906105d2565b634e487b7160e01b600052602260045260246000fd5b90607f16906101af565b634e487b7160e01b600052604160045260246000fd5b015190503880610177565b600360009081528281209350601f198516905b81811061068f5750908460019594939210610676575b505050811b0160035561018d565b015160001960f88460031b161c19169055388080610668565b92936020600181928786015181550195019301610652565b60036000529091507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f840160051c8101916020851061070d575b90601f859493920160051c01905b8181106106fe5750610160565b600081558493506001016106f1565b90915081906106e3565b91607f169161014c565b96610128565b600080fd5b6040519190601f01601f191682016001600160401b0381118382101761061e57604052565b81601f82011215610727578051906001600160401b03821161061e57610780601f8301601f191660200161072c565b92828452602083830101116107275760005b8281106107a757505060206000918301015290565b80602080928401015182828701015201610792565b51906001600160a01b038216820361072757565b600854906001600160a01b03821661080a576001600160a01b03199091166001600160a01b0382161760085561080790600061082f565b90565b631fe1e13d60e11b60005260046000fd5b61080790600080516020612e388339815191525b60008181526006602090815260408083206001600160a01b038616845290915290205460ff166108b75760008181526006602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b505060009056fe608080604052600436101561001357600080fd5b60003560e01c90816301ffc9a7146119d457508063022d63fb1461199857806306fdde03146118bb578063095ea7b3146117795780630aa6220b1461169357806318160ddd14611657578063181f5a77146115a157806323b872dd1461154b578063248a9ca3146114f8578063282c51f31461149f5780632f2ff15d1461143b578063313ce567146113df57806336568abe1461125057806340c10f191461105157806342966c681461100e578063634e93da14610eb7578063649a5ec714610c8757806370a0823114610c2257806379cc67901461095657806384ef8ffc14610bd05780638da5cb5b14610bd05780638fd6a6ac14610b7e57806391d1485414610b0557806395d89b41146109ac5780639dc29fac14610956578063a1eda53c146108d1578063a217fddf14610897578063a8fa343c146107ec578063a9059cbb1461079d578063c630948d146106ac578063c91ddc2014610653578063cc8463c81461060a578063cefc1429146104cc578063cf6eefb714610441578063d5391393146103e8578063d547741f14610353578063d5abeb01146102fa578063d602b9fd146102615763dd62ed3e146101cc57600080fd5b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57610203611c1c565b73ffffffffffffffffffffffffffffffffffffffff610220611c3f565b9116600052600160205273ffffffffffffffffffffffffffffffffffffffff604060002091166000526020526020604060002054604051908152f35b600080fd5b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57610298611cdc565b600780547fffffffffffff0000000000000000000000000000000000000000000000000000811690915560a01c65ffffffffffff166102d357005b7f8886ebfc4259abdbc16601dd8fb5678e54878f47b3c34836cfc51154a9605109600080a1005b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760043561038d611c3f565b81156103be57816103b76103b26103bc94600052600660205260016040600020015490565b611dd3565b6122f9565b005b7f3fc3c27a0000000000000000000000000000000000000000000000000000000060005260046000fd5b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760206040517f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a68152f35b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57604065ffffffffffff6104a66007549065ffffffffffff73ffffffffffffffffffffffffffffffffffffffff83169260a01c1690565b73ffffffffffffffffffffffffffffffffffffffff849392935193168352166020820152f35b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760075473ffffffffffffffffffffffffffffffffffffffff1633036105dc5760075460a081901c65ffffffffffff169073ffffffffffffffffffffffffffffffffffffffff16811580156105d2575b6105a4576105799061057373ffffffffffffffffffffffffffffffffffffffff6008541661228b565b506121af565b50600780547fffffffffffff0000000000000000000000000000000000000000000000000000169055005b507f19ca5ebb0000000000000000000000000000000000000000000000000000000060005260045260246000fd5b504282101561054a565b7fc22c8022000000000000000000000000000000000000000000000000000000006000523360045260246000fd5b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576020610643611ca3565b65ffffffffffff60405191168152f35b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760206040517fcfd2b420c3d2b6ebd6af82f6e29c095b45a072b8d1b5d9eda2a56dcb850acaa68152f35b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576103bc6106e6611c1c565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a660005260066020527f3195c024b2ddd6d9b8f6c836aa52f67fe69376c8903d009b80229b3ce4425f525461073a90611dd3565b61074381612158565b507f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84860005260066020527f42d20fd6db25ea5a8e33f43724ad72f2ebd9488257fa78c86176b8175fc383fb5461079890611dd3565b612185565b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576107e16107d7611c1c565b6024359033611f5d565b602060405160018152f35b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57610823611c1c565b61082b611cdc565b73ffffffffffffffffffffffffffffffffffffffff80600554921691827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617600555167f9524c9e4b0b61eb018dd58a1cd856e3e74009528328ab4a613b434fa631d7242600080a3005b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57602060405160008152f35b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576008548060d01c908115158061094c575b156109425760a01c65ffffffffffff165b6040805165ffffffffffff928316815292909116602083015290f35b0390f35b5050600080610922565b5042821015610911565b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576103bc610990611c1c565b6024359061099c611d48565b6109a7823383611e40565b61208d565b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760405160006004548060011c90600181168015610afb575b602083108114610ace57828552908115610a8c5750600114610a2c575b61093e83610a2081850382611c62565b60405191829182611bb4565b91905060046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b916000905b808210610a7257509091508101602001610a20610a10565b919260018160209254838588010152019101909291610a5a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660208086019190915291151560051b84019091019150610a209050610a10565b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526022600452fd5b91607f16916109f3565b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57610b3c611c3f565b600435600052600660205273ffffffffffffffffffffffffffffffffffffffff60406000209116600052602052602060ff604060002054166040519015158152f35b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57602073ffffffffffffffffffffffffffffffffffffffff60055416604051908152f35b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57602073ffffffffffffffffffffffffffffffffffffffff60085416604051908152f35b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5773ffffffffffffffffffffffffffffffffffffffff610c6e611c1c565b1660005260006020526020604060002054604051908152f35b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760043565ffffffffffff81169081810361025c57610cd2611cdc565b610cdb4261236f565b9165ffffffffffff610ceb611ca3565b1680821115610e4e57507ff1038c18cf84a56e432fdbfaf746924b7ea511dfe03a6506a0ceba4888788d9b9265ffffffffffff826206978080610d3895109118026206978018169061213a565b906008548060d01c80610dca575b50506008805473ffffffffffffffffffffffffffffffffffffffff1660a083901b79ffffffffffff0000000000000000000000000000000000000000161760d084901b7fffffffffffff0000000000000000000000000000000000000000000000000000161790556040805165ffffffffffff9283168152919092166020820152a1005b421115610e235779ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff00000000000000000000000000000000000000000000000000006007549260301b169116176007555b8380610d46565b507f2b1fa2edafe6f7b9e97c1a9e0c3660e645beb2dcaa2d45bdbf9beaf5472e1ec5600080a1610e1c565b0365ffffffffffff8111610e88577ff1038c18cf84a56e432fdbfaf746924b7ea511dfe03a6506a0ceba4888788d9b92610d38919061213a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57610eee611c1c565b610ef6611cdc565b7f3377dc44241e779dd06afab5b788a35ca5f3b778836e2990bdb26a2a4b2e5ed66020610f33610f254261236f565b610f2d611ca3565b9061213a565b65ffffffffffff73ffffffffffffffffffffffffffffffffffffffff610f7c6007549065ffffffffffff73ffffffffffffffffffffffffffffffffffffffff83169260a01c1690565b9690501694600754867fffffffffffff000000000000000000000000000000000000000000000000000079ffffffffffff00000000000000000000000000000000000000008660a01b169216171760075516610fe4575b65ffffffffffff60405191168152a2005b7f8886ebfc4259abdbc16601dd8fb5678e54878f47b3c34836cfc51154a9605109600080a1610fd3565b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57611045611d48565b6103bc6004353361208d565b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57611088611c1c565b3360009081527f3195c024b2ddd6d9b8f6c836aa52f67fe69376c8903d009b80229b3ce4425f516020526040902054602435919060ff16156111fe5773ffffffffffffffffffffffffffffffffffffffff1680156111cf573081146111a25760025491808301809311610e88576020926002557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600093849284845283825260408420818154019055604051908152a37f000000000000000000000000000000000000000000000000000000000000000080611162575080f35b90600254918083116111745750905080f35b6044927fea058246000000000000000000000000000000000000000000000000000000008352600452602452fd5b7fec442f050000000000000000000000000000000000000000000000000000000060005260045260246000fd5b7fec442f0500000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7fe2517d3f00000000000000000000000000000000000000000000000000000000600052336004527f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a660245260446000fd5b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760043561128a611c3f565b8115806113a8575b6112e7575b3373ffffffffffffffffffffffffffffffffffffffff8216036112bd576103bc916122f9565b7f6697b2320000000000000000000000000000000000000000000000000000000060005260046000fd5b60075465ffffffffffff60a082901c169073ffffffffffffffffffffffffffffffffffffffff1615801590611398575b8015611386575b61135057507fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff60075416600755611297565b65ffffffffffff907f19ca5ebb000000000000000000000000000000000000000000000000000000006000521660045260246000fd5b504265ffffffffffff8216101561131e565b5065ffffffffffff811615611317565b5073ffffffffffffffffffffffffffffffffffffffff6008541673ffffffffffffffffffffffffffffffffffffffff821614611292565b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57600435611475611c3f565b81156103be578161149a6103b26103bc94600052600660205260016040600020015490565b612217565b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760206040517f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8488152f35b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576020611543600435600052600660205260016040600020015490565b604051908152f35b3461025c5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576107e1611585611c1c565b61158d611c3f565b6044359161159c833383611e40565b611f5d565b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57604051604081019080821067ffffffffffffffff8311176116285761093e91604052601581527f43726f7373436861696e546f6b656e20322e302e300000000000000000000000602082015260405191829182611bb4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576020600254604051908152f35b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576116ca611cdc565b6008548060d01c806116f5575b6008805473ffffffffffffffffffffffffffffffffffffffff169055005b42111561174e5779ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff00000000000000000000000000000000000000000000000000006007549260301b169116176007555b80806116d7565b507f2b1fa2edafe6f7b9e97c1a9e0c3660e645beb2dcaa2d45bdbf9beaf5472e1ec5600080a1611747565b3461025c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576117b0611c1c565b73ffffffffffffffffffffffffffffffffffffffff1660243530821461188d57331561185e57811561182f57336000526001602052604060002082600052602052806040600020556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b7f94280d6200000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b7fe602df0500000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b507f94280d620000000000000000000000000000000000000000000000000000000060005260045260246000fd5b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c5760405160006003548060011c9060018116801561198e575b602083108114610ace57828552908115610a8c575060011461192e5761093e83610a2081850382611c62565b91905060036000527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b916000905b80821061197457509091508101602001610a20610a10565b91926001816020925483858801015201910190929161195c565b91607f1691611902565b3461025c5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c576020604051620697808152f35b3461025c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261025c57600435907fffffffff00000000000000000000000000000000000000000000000000000000821680920361025c57817f314987860000000000000000000000000000000000000000000000000000000060209314908115611b59575b8115611a9e575b8115611a74575b5015158152f35b7fe6599b4d0000000000000000000000000000000000000000000000000000000091501483611a6d565b90507f36372b070000000000000000000000000000000000000000000000000000000081148015611b30575b8015611b07575b8015611ade575b90611a66565b507f01ffc9a7000000000000000000000000000000000000000000000000000000008114611ad8565b507fa219a025000000000000000000000000000000000000000000000000000000008114611ad1565b507f8fd6a6ac000000000000000000000000000000000000000000000000000000008114611aca565b90507f7965db0b0000000000000000000000000000000000000000000000000000000081148015611b8b575b90611a5f565b507f01ffc9a7000000000000000000000000000000000000000000000000000000008114611b85565b9190916020815282519283602083015260005b848110611c065750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006040809697860101520116010190565b8060208092840101516040828601015201611bc7565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361025c57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361025c57565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761162857604052565b6008548060d01c8015159081611cd2575b5015611cc85760a01c65ffffffffffff1690565b5060075460d01c90565b9050421138611cb4565b3360009081527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8602052604090205460ff1615611d1557565b7fe2517d3f0000000000000000000000000000000000000000000000000000000060005233600452600060245260446000fd5b3360009081527f42d20fd6db25ea5a8e33f43724ad72f2ebd9488257fa78c86176b8175fc383fa602052604090205460ff1615611d8157565b7fe2517d3f00000000000000000000000000000000000000000000000000000000600052336004527f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84860245260446000fd5b806000526006602052604060002073ffffffffffffffffffffffffffffffffffffffff331660005260205260ff6040600020541615611e0f5750565b7fe2517d3f000000000000000000000000000000000000000000000000000000006000523360045260245260446000fd5b73ffffffffffffffffffffffffffffffffffffffff9092919216806000526001602052604060002073ffffffffffffffffffffffffffffffffffffffff8416600052602052604060002054927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8410611eba575b50505050565b828410611f115773ffffffffffffffffffffffffffffffffffffffff169030821461188d57801561185e57811561182f57600052600160205260406000209060005260205260406000209103905538808080611eb4565b8373ffffffffffffffffffffffffffffffffffffffff84927ffb8f41b2000000000000000000000000000000000000000000000000000000006000521660045260245260445260646000fd5b73ffffffffffffffffffffffffffffffffffffffff1690811561205e5773ffffffffffffffffffffffffffffffffffffffff169182156111cf57308314612030576000828152806020526040812054828110611ffd5791604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815280845220818154019055604051908152a3565b6064937fe450d38c0000000000000000000000000000000000000000000000000000000083949352600452602452604452fd5b827fec442f050000000000000000000000000000000000000000000000000000000060005260045260246000fd5b7f96c6fd1e00000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff16801561205e5730156111cf5760009181835282602052604083205481811061210857817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b83927fe450d38c0000000000000000000000000000000000000000000000000000000060649552600452602452604452fd5b9065ffffffffffff8091169116019065ffffffffffff8211610e8857565b612182907f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66123b9565b90565b612182907f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486123b9565b6008549073ffffffffffffffffffffffffffffffffffffffff82166103be57612182917fffffffffffffffffffffffff000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff831691161760085560006123b9565b908115612228575b612182916123b9565b6008549173ffffffffffffffffffffffffffffffffffffffff83166103be577fffffffffffffffffffffffff000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff82161760085561221f565b6121829073ffffffffffffffffffffffffffffffffffffffff6008541673ffffffffffffffffffffffffffffffffffffffff8216146122cc575b6000612498565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000600854166008556122c5565b9061218291801580612338575b15612498577fffffffffffffffffffffffff000000000000000000000000000000000000000060085416600855612498565b5073ffffffffffffffffffffffffffffffffffffffff6008541673ffffffffffffffffffffffffffffffffffffffff831614612306565b65ffffffffffff81116123875765ffffffffffff1690565b7f6dfcc65000000000000000000000000000000000000000000000000000000000600052603060045260245260446000fd5b806000526006602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260ff604060002054161560001461249157806000526006602052604060002073ffffffffffffffffffffffffffffffffffffffff8316600052602052604060002060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905573ffffffffffffffffffffffffffffffffffffffff339216907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d600080a4600190565b5050600090565b806000526006602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260ff6040600020541660001461249157806000526006602052604060002073ffffffffffffffffffffffffffffffffffffffff831660005260205260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00815416905573ffffffffffffffffffffffffffffffffffffffff339216907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b600080a460019056fea164736f6c634300081a000acfd2b420c3d2b6ebd6af82f6e29c095b45a072b8d1b5d9eda2a56dcb850acaa6' as const +// generate:end diff --git a/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/lock-release-token-pool.ts b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/lock-release-token-pool.ts new file mode 100644 index 00000000..fbc5dcd8 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/lock-release-token-pool.ts @@ -0,0 +1,4 @@ +export default // generate: +// `'${require('fs').readFileSync(require.resolve('@chainlink/contracts-ccip/bytecode/v2_0_0/lock_release_token_pool.bin'), 'utf8').trim()}' as const` +'0x610100806040523461037a5760c081616038803803809161002082856103ba565b83398101031261037a5780516001600160a01b0381169182820361037a5761004a602082016103f3565b9061005760408201610401565b61006360608301610401565b9261007c60a061007560808601610401565b9401610401565b9333156103a957600180546001600160a01b0319163317905586158015610398575b8015610387575b6102df578560805260c0523086036102f0575b60a052600380546001600160a01b03199081166001600160a01b03938416179091556002805490911692821692909217909155169182156102df576040516375151b6360e01b815260048101829052602081602481875afa9081156102d357600091610291575b501561027d57604051906020600081840163095ea7b360e01b815286602486015281196044860152604485526101566064866103ba565b84519082875af1903d600051908361025e575b50505015610219575b8260e052604051615bc79081610471823960805181818161024a015281816121d3015281816129c701528181612c3a015281816130e8015281816137140152818161376e0152614f0c015260a0518181816135da015281816148ed015281816149370152614f60015260c0518181816102e50152818161134d0152818161226d01528181612a620152613183015260e0518181816126cf01528181612bc10152614e910152f35b6102579161025260405163095ea7b360e01b6020820152856024820152600060448201526044815261024c6064826103ba565b82610415565b610415565b3880610172565b9192509061027357503b15155b388080610169565b600191501461026b565b63961c9a4f60e01b60005260045260246000fd5b6020813d6020116102cb575b816102aa602093836103ba565b810103126102c757519081151582036102c457503861011f565b80fd5b5080fd5b3d915061029d565b6040513d6000823e3d90fd5b630a64406560e11b60005260046000fd5b60405163313ce56760e01b81526020816004818a5afa60009181610346575b5061031b575b506100b8565b60ff1660ff821681810361032f5750610315565b6332ad3e0760e11b60005260045260245260446000fd5b9091506020813d60201161037f575b81610362602093836103ba565b8101031261037a57610373906103f3565b903861030f565b600080fd5b3d9150610355565b506001600160a01b038116156100a5565b506001600160a01b0384161561009e565b639b15e16f60e01b60005260046000fd5b601f909101601f19168101906001600160401b038211908210176103dd57604052565b634e487b7160e01b600052604160045260246000fd5b519060ff8216820361037a57565b51906001600160a01b038216820361037a57565b906000602091828151910182855af1156102d3576000513d61046757506001600160a01b0381163b155b6104465750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b6001141561043f56fe608080604052600436101561001357600080fd5b600090813560e01c90816301ffc9a71461398f5750806306b859ef146138aa578063181f5a77146138495780631826b1e71461379257806321df0da714613741578063240028e8146136dd5780632422ac45146135fe57806324f65ee7146135c05780632cab0fb61461304d57806337a3210d14613019578063390775371461291c5780634c5ef0ed146128d557806362ddd3c41461284e5780637437ff9f1461280057806379ba5097146127395780638926f54f146126f35780638c6894fb146126a25780638da5cb5b1461266e5780639a4575b91461215a578063a42a7b8b14611ff3578063acfecf9114611efb578063ae39a25714611d70578063b6cfa3b714611cb5578063b794658014611c7d578063bfeffd3f14611bd1578063c4bffe2b14611aa6578063c7230a60146117f5578063dc04fa1f14611371578063dc0bd97114611320578063dcbd41bc1461111c578063e8a1da1714610a44578063ea6396db14610906578063ec6ae7a7146108c3578063f2fde38b146107f45763fbc801a7146101a257600080fd5b34610668576060600319360112610668576004359067ffffffffffffffff8211610668578160040160a060031984360301126107f0576101e0613ac1565b9160443567ffffffffffffffff81116107f0579061020661022393923690600401613bec565b93906102106145a9565b5061021b86856151c4565b943691613d66565b93608486019461023286614536565b73ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116036107a657602487019677ffffffffffffffff0000000000000000000000000000000061029889614557565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115610719578591610777575b5061074f5767ffffffffffffffff61032c89614557565b16610344816000526007602052604060002054151590565b1561072457602073ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156107195785906106c8575b73ffffffffffffffffffffffffffffffffffffffff915016330361069c576064810135946103d38787613f4d565b7fffffffff00000000000000000000000000000000000000000000000000000000851694851561067a5761042f907fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1690614a41565b61044b8161043c8b614536565b6104458d614557565b906154ac565b73ffffffffffffffffffffffffffffffffffffffff600354169384610549575b61053f8a61050e6105098e6104808e8e613f4d565b936104938561048e84614557565b614e7a565b7ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff6104cf6104c985614557565b93614536565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252336020830152810188905292169180606081015b0390a2614557565b61471a565b90610517614f59565b6040519261052484613cd1565b83526020830152604051928392604084526040840190613e2e565b9060208301520390f35b843b15610676578694928a949286928d604051998a98899788967fa8027c0f00000000000000000000000000000000000000000000000000000000885260048801608090528061059891615416565b6084890160a090526101248901906105af92613f7b565b936105b990613bd7565b67ffffffffffffffff1660a48801526044016105d490613b88565b73ffffffffffffffffffffffffffffffffffffffff1660c48701528d60e48701526105fe90613b88565b73ffffffffffffffffffffffffffffffffffffffff16610104860152602485015283810360031901604485015261063491613c1a565b90606483015203925af1801561066b57610653575b808080808061046b565b61065e828092613d25565b6106685780610649565b80fd5b6040513d84823e3d90fd5b8680fd5b50610697816106888b614536565b6106918d614557565b90615466565b61044b565b6024847f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b506020813d602011610711575b816106e260209383613d25565b8101031261070d5761070873ffffffffffffffffffffffffffffffffffffffff91613f5a565b6103a5565b8480fd5b3d91506106d5565b6040513d87823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008552600452602484fd5b6004847f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b610799915060203d60201161079f575b6107918183613d25565b810190614bad565b38610315565b503d610787565b60248373ffffffffffffffffffffffffffffffffffffffff6107c789614536565b7f961c9a4f00000000000000000000000000000000000000000000000000000000835216600452fd5b5080fd5b50346106685760206003193601126106685773ffffffffffffffffffffffffffffffffffffffff610823613b1f565b61082b614bc5565b1633811461089b57807fffffffffffffffffffffffff000000000000000000000000000000000000000083541617825573ffffffffffffffffffffffffffffffffffffffff600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12788380a380f35b6004827fdad89dca000000000000000000000000000000000000000000000000000000008152fd5b503461066857806003193601126106685760207fffffffff0000000000000000000000000000000000000000000000000000000060025460401b16604051908152f35b503461066857608060031936011261066857610920613b1f565b50610929613ba9565b610931613af0565b5060643567ffffffffffffffff8111610a40579167ffffffffffffffff60409261096160e0953690600401613bec565b50508260c0855161097181613d09565b82815282602082015282878201528260608201528260808201528260a08201520152168152600b60205220604051906109a982613d09565b5461ffff818163ffffffff82169485815263ffffffff60208201818560201c1681528160408401818760401c168152816060860193818960601c16855260ff60c060808901988a8c60801c168a528a60a082019c60901c168c52019b60a01c1615158b526040519b8c52511660208b0152511660408901525116606087015251166080850152511660a083015251151560c0820152f35b8280fd5b50346106685760406003193601126106685760043567ffffffffffffffff81116107f057610a76903690600401613e58565b9060243567ffffffffffffffff81116111185790610a9984923690600401613e58565b939091610aa4614bc5565b83905b828210610f595750505081927ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee182360301935b81811015610f55578060051b8301358581121561070d5783016101208136031261070d5760405194610b0b86613ced565b610b1482613bd7565b8652602082013567ffffffffffffffff81116107f05782019436601f870112156107f057853595610b4487613eba565b96610b526040519889613d25565b80885260208089019160051b8301019036821161070d5760208301905b828210610f26575050505060208701958652604083013567ffffffffffffffff8111610a4057610ba29036908501613dcb565b9160408801928352610bcc610bba36606087016147c6565b9460608a0195865260c03691016147c6565b956080890196875283515115610efe57610bf067ffffffffffffffff8a5116615849565b15610ec75767ffffffffffffffff8951168252600860205260408220610c17865182614f94565b610c25885160028301614f94565b6004855191019080519067ffffffffffffffff8211610e9a57610c488354614605565b601f8111610e5f575b50602090601f8311600114610dc057610c9f9291869183610db5575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b90555b815b88518051821015610cd95790610cd3600192610ccc8367ffffffffffffffff8f5116926145c2565b5190614c10565b01610ca4565b5050977f8d340f17e19058004c20453540862a9c62778504476f6756755cb33bcd6c38c2939199975095610da767ffffffffffffffff6001979694985116925193519151610d73610d3e60405196879687526101006020880152610100870190613c1a565b9360408601906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b60a08401906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b0390a1019392909193610ada565b015190508e80610c6d565b83865281862091907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08416875b818110610e475750908460019594939210610e10575b505050811b019055610ca2565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558d8080610e03565b92936020600181928786015181550195019301610ded565b610e8a9084875260208720601f850160051c81019160208610610e90575b601f0160051c0190614862565b8d610c51565b9091508190610e7d565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b60248267ffffffffffffffff8b51167f1d5ad3c5000000000000000000000000000000000000000000000000000000008252600452fd5b6004827f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b813567ffffffffffffffff811161067657602091610f4a8392833691890101613dcb565b815201910190610b6f565b8380f35b9267ffffffffffffffff610f7b610f768486889a9699979a614799565b614557565b1691610f868361557f565b156110ec578284526008602052610fa26005604086200161551c565b94845b8651811015610fdb576001908587526008602052610fd460056040892001610fcd838b6145c2565b5190615715565b5001610fa5565b50939692909450949094808752600860205260056040882088815588600182015588600282015588600382015588600482016110178154614605565b806110ab575b505050018054908881558161108d575b5050907f5204aec90a3c794d8e90fded8b46ae9c7c552803e7e832e0c1d358396d8599166020836001948a52600482528985604082208281550155808a52600582528985604082208281550155604051908152a101909194939294610aa7565b885260208820908101905b8181101561102d57888155600101611098565b601f81116001146110c15750555b888a8061101d565b818352602083206110dc91601f01861c810190600101614862565b80825281602081209155556110b9565b602484847f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b8380fd5b50346106685760206003193601126106685760043567ffffffffffffffff81116107f05761114e903690600401613e89565b73ffffffffffffffffffffffffffffffffffffffff600a5416331415806112fe575b6112d257825b818110611181578380f35b61118c81838561473c565b67ffffffffffffffff61119e82614557565b16906111b7826000526007602052604060002054151590565b156112a657907f41f7c8f7cfdad9350aa495e6c54cbbf750a07ab38a9098aed1256e30dd1682bb60e083611266611240602060019897018b6111f88261474c565b1561126d57879052600460205261121f60408d2061121936604088016147c6565b90614f94565b868c52600560205261123b60408d206112193660a088016147c6565b61474c565b916040519215158352611259602084016040830161481e565b60a060808401910161481e565ba201611176565b60026040828a61123b9452600860205261128f82822061121936858c016147c6565b8a8152600860205220016112193660a088016147c6565b602486837f1e670e4b000000000000000000000000000000000000000000000000000000008252600452fd5b6024837f8e4a23d600000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff60015416331415611170565b5034610668578060031936011261066857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346106685760406003193601126106685760043567ffffffffffffffff81116107f0576113a3903690600401613e89565b60243567ffffffffffffffff8111611118576113c3903690600401613e58565b9190926113ce614bc5565b845b82811061143a57505050825b8181106113e7578380f35b8067ffffffffffffffff611401610f766001948688614799565b16808652600b6020528560408120557f5479bbc0288b7eaeaf2ace0943b88016cc648964fcd42919a86fd93b15fdbee88680a2016113dc565b67ffffffffffffffff611451610f7683868661473c565b16611469816000526007602052604060002054151590565b156117ca5761147982858561473c565b602081019060e081019061148c8261474c565b1561179e5760a0810161271061ffff6114a483614759565b16101561178f5760c082019161271061ffff6114bf85614759565b1610156117575763ffffffff6114d486614768565b161561172b57858c52600b60205260408c206114ef86614768565b63ffffffff1690805490604084019161150783614768565b60201b67ffffffff000000001693606086019461152386614768565b60401b6bffffffff000000000000000016966080019661154288614768565b60601b6fffffffff00000000000000000000000016916115618a614759565b60801b71ffff0000000000000000000000000000000016936115828c614759565b60901b73ffff00000000000000000000000000000000000016957fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016177fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16177fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff16177fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff1617171781556116358761474c565b81547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff0000000000000000000000000000000000000000161790556040519661168690614779565b63ffffffff16875261169790614779565b63ffffffff1660208701526116ab90614779565b63ffffffff1660408601526116bf90614779565b63ffffffff1660608501526116d39061478a565b61ffff1660808401526116e59061478a565b61ffff1660a08301526116f790613c79565b151560c082015260e07ffae1e296719dac5269c3886fb5002bb29bf17ae403060c6eb063a55abaaa104191a26001016113d0565b60248c877f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b60248c61ffff61176686614759565b7f95f3517a00000000000000000000000000000000000000000000000000000000835216600452fd5b8a61ffff611766602493614759565b60248a857f12332265000000000000000000000000000000000000000000000000000000008252600452fd5b7f1e670e4b000000000000000000000000000000000000000000000000000000008752600452602486fd5b50346106685760406003193601126106685760043567ffffffffffffffff81116107f057611827903690600401613e58565b90611830613b65565b9173ffffffffffffffffffffffffffffffffffffffff6001541633141580611a84575b611a585773ffffffffffffffffffffffffffffffffffffffff8316908115611a3057845b818110611882578580f35b73ffffffffffffffffffffffffffffffffffffffff6118aa6118a5838588614799565b614536565b166040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152602081602481855afa908115611a255788916119f2575b50806118ff575b5050600101611877565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000602080830191825273ffffffffffffffffffffffffffffffffffffffff8a16602484015260448084018590528352918a9190611960606482613d25565b519082865af1156119e75787513d6119de5750813b155b6119b25790847f508d7d183612c18fc339b42618912b9fa3239f631dd7ec0671f950200a0fa66e602060019594604051908152a390386118f5565b602488837f5274afe7000000000000000000000000000000000000000000000000000000008252600452fd5b60011415611977565b6040513d89823e3d90fd5b905060203d8111611a1e575b611a088183613d25565b60208260009281010312610668575051386118ee565b503d6119fe565b6040513d8a823e3d90fd5b6004857f8579befe000000000000000000000000000000000000000000000000000000008152fd5b6024847fcb1afbd700000000000000000000000000000000000000000000000000000000815233600452fd5b5073ffffffffffffffffffffffffffffffffffffffff600c5416331415611853565b5034610668578060031936011261066857604051906006548083528260208101600684526020842092845b818110611bb8575050611ae692500383613d25565b8151611b0a611af482613eba565b91611b026040519384613d25565b808352613eba565b917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0602083019301368437805b8451811015611b69578067ffffffffffffffff611b56600193886145c2565b5116611b6282866145c2565b5201611b37565b50925090604051928392602084019060208552518091526040840192915b818110611b95575050500390f35b825167ffffffffffffffff16845285945060209384019390920191600101611b87565b8454835260019485019487945060209093019201611ad1565b50346106685760206003193601126106685760043573ffffffffffffffffffffffffffffffffffffffff81168091036107f057611c0c614bc5565b7fffffffffffffffffffffffff00000000000000000000000000000000000000006003547fbaff46844acf36d6ee996f489a1a288709c4542bd33cd557770afd267d5812096040805173ffffffffffffffffffffffffffffffffffffffff84168152856020820152a1161760035580f35b503461066857602060031936011261066857611cb1611c9d610509613bc0565b604051918291602083526020830190613c1a565b0390f35b5034610668576020600319360112610668577f307cf716eade81675bea3ccb6917b0f91baa2160056765d9a83d76f819caf06a6020611cf2613a8d565b611cfa614bc5565b6002547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff77ffffffff0000000000000000000000000000000000000000808460401c16169116176002557fffffffff0000000000000000000000000000000000000000000000000000000060405191168152a180f35b503461066857606060031936011261066857611d8a613b1f565b90611d93613b65565b6044359273ffffffffffffffffffffffffffffffffffffffff841680850361111857611dbd614bc5565b73ffffffffffffffffffffffffffffffffffffffff82168015611ed35794611ecd917f3f1036e85d016a93254a0b1415844f79b85424959d90ae5ad51ce8f4533fe70195967fffffffffffffffffffffffff0000000000000000000000000000000000000000600254161760025573ffffffffffffffffffffffffffffffffffffffff85167fffffffffffffffffffffffff0000000000000000000000000000000000000000600a541617600a557fffffffffffffffffffffffff0000000000000000000000000000000000000000600c541617600c556040519384938491604091949373ffffffffffffffffffffffffffffffffffffffff809281606087019816865216602085015216910152565b0390a180f35b6004857f14c880ca000000000000000000000000000000000000000000000000000000008152fd5b50346106685767ffffffffffffffff611f1336613de9565b929091611f1e614bc5565b1691611f37836000526007602052604060002054151590565b156110ec578284526008602052611f6660056040862001611f59368486613d66565b6020815191012090615715565b15611fab57907f52d00ee4d9bd51b40168f2afc5848837288ce258784ad914278791464b3f4d7691611fa5604051928392602084526020840191613f7b565b0390a280f35b82611fef836040519384937f74f23c7c0000000000000000000000000000000000000000000000000000000085526004850152604060248501526044840191613f7b565b0390fd5b50346106685760206003193601126106685767ffffffffffffffff612016613bc0565b168152600860205261202d6005604083200161551c565b80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061207261205c83613eba565b9261206a6040519485613d25565b808452613eba565b01835b818110612149575050825b82518110156120c65780612096600192856145c2565b51855260096020526120aa60408620614658565b6120b482856145c2565b526120bf81846145c2565b5001612080565b81846040519182916020830160208452825180915260408401602060408360051b870101940192905b8282106120fe57505050500390f35b91936020612139827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851613c1a565b96019201920185949391926120ef565b806060602080938601015201612075565b50346106685760206003193601126106685760043567ffffffffffffffff81116107f057806004019060a06003198236030112610a40576121996145a9565b506040516020936121aa8583613d25565b80825260848301916121bb83614536565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361264d57602484019477ffffffffffffffff0000000000000000000000000000000061222187614557565b60801b16604051907f2cbc26bb0000000000000000000000000000000000000000000000000000000082526004820152878160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156125d2578491612630575b506126085767ffffffffffffffff6122b487614557565b166122cc816000526007602052604060002054151590565b156125dd578773ffffffffffffffffffffffffffffffffffffffff60025416916024604051809481937fa8d87a3b00000000000000000000000000000000000000000000000000000000835260048301525afa80156125d257849061258a575b73ffffffffffffffffffffffffffffffffffffffff915016330361255e576064850135946123668661235d87614536565b6106918a614557565b73ffffffffffffffffffffffffffffffffffffffff600354169182612443575b886124136105098a8a7ff33bc26b4413b0e7f19f1ea739fdf99098c0061f1f87d954b11f5293fad9ae1067ffffffffffffffff8c6123c78461048e87614557565b6105016123dc6123d687614557565b92614536565b6040805173ffffffffffffffffffffffffffffffffffffffff90921682523360208301528101959095529116929081906060820190565b9061241c614f59565b6040519261242984613cd1565b835281830152611cb1604051928284938452830190613e2e565b823b1561070d57918791858094604051968795869485937fa8027c0f00000000000000000000000000000000000000000000000000000000855260048501608090528061248f91615416565b6084860160a090526101248601906124a692613f7b565b916124b090613bd7565b67ffffffffffffffff1660a48501526044016124cb90613b88565b73ffffffffffffffffffffffffffffffffffffffff1660c48401528b60e48401526124f58b613b88565b73ffffffffffffffffffffffffffffffffffffffff1661010484015283602484015282810360031901604484015261252c91613c1a565b8a606483015203925af1801561066b57612549575b808080612386565b612554828092613d25565b6106685780612541565b6024837f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b508781813d83116125cb575b6125a08183613d25565b81010312611118576125c673ffffffffffffffffffffffffffffffffffffffff91613f5a565b61232c565b503d612596565b6040513d86823e3d90fd5b7fa9902c7e000000000000000000000000000000000000000000000000000000008452600452602483fd5b6004837f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b6126479150883d8a1161079f576107918183613d25565b3861229d565b5073ffffffffffffffffffffffffffffffffffffffff6107c7602493614536565b5034610668578060031936011261066857602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b5034610668578060031936011261066857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461066857602060031936011261066857602061272f67ffffffffffffffff61271b613bc0565b166000526007602052604060002054151590565b6040519015158152f35b5034610668578060031936011261066857805473ffffffffffffffffffffffffffffffffffffffff811633036127d8577fffffffffffffffffffffffff000000000000000000000000000000000000000060015491338284161760015516825573ffffffffffffffffffffffffffffffffffffffff3391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b6004827f02b543c6000000000000000000000000000000000000000000000000000000008152fd5b5034610668578060031936011261066857600254600a54600c546040805173ffffffffffffffffffffffffffffffffffffffff94851681529284166020840152921691810191909152606090f35b50346106685761285d36613de9565b61286993929193614bc5565b67ffffffffffffffff821661288b816000526007602052604060002054151590565b156128aa57506128a792936128a1913691613d66565b90614c10565b80f35b7f1e670e4b000000000000000000000000000000000000000000000000000000008452600452602483fd5b5034610668576040600319360112610668576128ef613bc0565b906024359067ffffffffffffffff821161066857602061272f846129163660048701613dcb565b9061456c565b5034610668576020600319360112610668576004359067ffffffffffffffff82116106685781600401906101006003198436030112610668578060405161296281613c86565b528060405161297081613c86565b52606483013560c48401936129a061299a61299561298e88886144e5565b3691613d66565b614879565b83614934565b9360848201956129af87614536565b73ffffffffffffffffffffffffffffffffffffffff807f000000000000000000000000000000000000000000000000000000000000000016911603612ff857602483019377ffffffffffffffff00000000000000000000000000000000612a1586614557565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156119e7578791612fd9575b50612fb15767ffffffffffffffff612aa986614557565b16612ac1816000526007602052604060002054151590565b15612f8657602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa9081156119e7578791612f67575b5015612f3b57612b3885614557565b92612b4e60a486019461291661298e87856144e5565b15612ef457612b6f88612b608b614536565b612b6989614557565b9061532d565b73ffffffffffffffffffffffffffffffffffffffff600354169283612d22575b505050505060440191612ba183614536565b612baa83614557565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b1561111857608484928367ffffffffffffffff9373ffffffffffffffffffffffffffffffffffffffff60405197889687957f74fd18ac000000000000000000000000000000000000000000000000000000008752837f00000000000000000000000000000000000000000000000000000000000000001660048801521660248601528c60448601521660648401525af1801561066b57612d0d575b5050608067ffffffffffffffff60209573ffffffffffffffffffffffffffffffffffffffff612cd9612cd36104c97ffc5e3a5bddc11d92c2dc20fae6f7d5eb989f056be35239f7de7e86150609abc097614557565b96614536565b816040519716875233898801521660408601528560608601521692a260405190612d0282613c86565b815260405190518152f35b612d18828092613d25565b6106685780612c7e565b833b15612ef057878795938195938c93604051988997889687957f6371157400000000000000000000000000000000000000000000000000000000875260048701606090528d612d728780615416565b60648a0161010090526101648a0190612d8a92613f7b565b94612d9490613bd7565b67ffffffffffffffff166084890152604401612daf90613b88565b73ffffffffffffffffffffffffffffffffffffffff1660a488015260c4870152612dd890613b88565b73ffffffffffffffffffffffffffffffffffffffff1660e4860152612dfd9084615416565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c86840301610104870152612e329291613f7b565b90612e3d9083615416565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c85840301610124860152612e729291613f7b565b9060e48a01612e8091615416565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c84840301610144850152612eb59291613f7b565b8b602483015282604483015203925af180156125d257908491612edb575b808080612b8f565b81612ee591613d25565b610a40578238612ed3565b8780fd5b83612efe916144e5565b611fef6040519283927f24eb47e5000000000000000000000000000000000000000000000000000000008452602060048501526024840191613f7b565b6024867f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b612f80915060203d60201161079f576107918183613d25565b38612b29565b7fa9902c7e000000000000000000000000000000000000000000000000000000008752600452602486fd5b6004867f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b612ff2915060203d60201161079f576107918183613d25565b38612a92565b60248573ffffffffffffffffffffffffffffffffffffffff6107c78a614536565b5034610668578060031936011261066857602073ffffffffffffffffffffffffffffffffffffffff60035416604051908152f35b5034610668576040600319360112610668576004359067ffffffffffffffff821161066857816004019061010060031984360301126106685761308e613ac1565b918160405161309c81613c86565b5260648401359360c48101936130c16130bb61299561298e88876144e5565b87614934565b9460848301966130d088614536565b73ffffffffffffffffffffffffffffffffffffffff807f00000000000000000000000000000000000000000000000000000000000000001691160361359f57602484019477ffffffffffffffff0000000000000000000000000000000061313687614557565b60801b16604051907f2cbc26bb000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115611a25578891613580575b506135585767ffffffffffffffff6131ca87614557565b166131e2816000526007602052604060002054151590565b1561352d57602073ffffffffffffffffffffffffffffffffffffffff60025416916044604051809481937f83826b2b00000000000000000000000000000000000000000000000000000000835260048301523360248301525afa908115611a2557889161350e575b50156134e25761325986614557565b9361326f60a487019561291661298e88866144e5565b156134d8577fffffffff00000000000000000000000000000000000000000000000000000000169081156134bd576132b9896132aa8c614536565b6132b38a614557565b906153a6565b73ffffffffffffffffffffffffffffffffffffffff6003541693846132ec575b50505050505060440191612ba183614536565b843b156134b957868995938c959387938b6040519a8b998a9889977f63711574000000000000000000000000000000000000000000000000000000008952600489016060905261333c8780615416565b60648b0161010090526101648b019061335492613f7b565b9461335e90613bd7565b67ffffffffffffffff1660848a015260440161337990613b88565b73ffffffffffffffffffffffffffffffffffffffff1660a489015260c48801526133a290613b88565b73ffffffffffffffffffffffffffffffffffffffff1660e48701526133c79084615416565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c878403016101048801526133fc9291613f7b565b906134079083615416565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c8684030161012487015261343c9291613f7b565b9060e48b0161344a91615416565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c8584030161014486015261347f9291613f7b565b908c6024840152604483015203925af180156125d2576134a4575b80808080806132d9565b926134b28160449395613d25565b929061349a565b8880fd5b6134d3896134ca8c614536565b612b698a614557565b6132b9565b612efe85836144e5565b6024877f728fe07b00000000000000000000000000000000000000000000000000000000815233600452fd5b613527915060203d60201161079f576107918183613d25565b3861324a565b7fa9902c7e000000000000000000000000000000000000000000000000000000008852600452602487fd5b6004877f53ad11d8000000000000000000000000000000000000000000000000000000008152fd5b613599915060203d60201161079f576107918183613d25565b386131b3565b60248673ffffffffffffffffffffffffffffffffffffffff6107c78b614536565b5034610668578060031936011261066857602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461066857604060031936011261066857613618613bc0565b602435918215158303610668576101406136db6136358585614462565b61368b60409392935180946fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565b60a08301906fffffffffffffffffffffffffffffffff6080809282815116855263ffffffff6020820151166020860152604081015115156040860152826060820151166060860152015116910152565bf35b5034610668576020600319360112610668576020906136fa613b1f565b905073ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169116146040519015158152f35b5034610668578060031936011261066857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346106685760c0600319360112610668576137ac613b1f565b506137b5613ba9565b6137bd613b42565b50608435917fffffffff00000000000000000000000000000000000000000000000000000000831683036106685760a4359067ffffffffffffffff82116106685760a063ffffffff8061ffff613822888861381b3660048b01613bec565b50506142b2565b95926040979194975197885216602087015216604085015216606083015215156080820152f35b503461066857806003193601126106685750611cb160405161386c604082613d25565b601a81527f4c6f636b52656c65617365546f6b656e506f6f6c20322e302e300000000000006020820152604051918291602083526020830190613c1a565b50346106685760c0600319360112610668576138c4613b1f565b6138cc613ba9565b906064357fffffffff00000000000000000000000000000000000000000000000000000000811681036111185760843567ffffffffffffffff811161070d57613919903690600401613bec565b9160a435936002851015610676576139349560443591613fba565b90604051918291602083016020845282518091526020604085019301915b818110613960575050500390f35b825173ffffffffffffffffffffffffffffffffffffffff16845285945060209384019390920191600101613952565b9050346107f05760206003193601126107f0576020907fffffffff000000000000000000000000000000000000000000000000000000006139ce613a8d565b167faff2afbf000000000000000000000000000000000000000000000000000000008114908115613a63575b8115613a39575b8115613a0f575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483613a08565b7f0e64dd290000000000000000000000000000000000000000000000000000000081149150613a01565b7f940a154200000000000000000000000000000000000000000000000000000000811491506139fa565b600435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613abc57565b600080fd5b602435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613abc57565b604435907fffffffff0000000000000000000000000000000000000000000000000000000082168203613abc57565b6004359073ffffffffffffffffffffffffffffffffffffffff82168203613abc57565b6064359073ffffffffffffffffffffffffffffffffffffffff82168203613abc57565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203613abc57565b359073ffffffffffffffffffffffffffffffffffffffff82168203613abc57565b6024359067ffffffffffffffff82168203613abc57565b6004359067ffffffffffffffff82168203613abc57565b359067ffffffffffffffff82168203613abc57565b9181601f84011215613abc5782359167ffffffffffffffff8311613abc5760208381860195010111613abc57565b919082519283825260005b848110613c645750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b80602080928401015182828601015201613c25565b35908115158203613abc57565b6020810190811067ffffffffffffffff821117613ca257604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040810190811067ffffffffffffffff821117613ca257604052565b60a0810190811067ffffffffffffffff821117613ca257604052565b60e0810190811067ffffffffffffffff821117613ca257604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117613ca257604052565b92919267ffffffffffffffff8211613ca25760405191613dae601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184613d25565b829481845281830111613abc578281602093846000960137010152565b9080601f83011215613abc57816020613de693359101613d66565b90565b906040600319830112613abc5760043567ffffffffffffffff81168103613abc57916024359067ffffffffffffffff8211613abc57613e2a91600401613bec565b9091565b613de6916020613e478351604084526040840190613c1a565b920151906020818403910152613c1a565b9181601f84011215613abc5782359167ffffffffffffffff8311613abc576020808501948460051b010111613abc57565b9181601f84011215613abc5782359167ffffffffffffffff8311613abc576020808501948460081b010111613abc57565b67ffffffffffffffff8111613ca25760051b60200190565b81810292918115918404141715613ee557565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8115613f1e570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b91908203918211613ee557565b519073ffffffffffffffffffffffffffffffffffffffff82168203613abc57565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b92959390919473ffffffffffffffffffffffffffffffffffffffff6003541695861561429057809760028710156142615773ffffffffffffffffffffffffffffffffffffffff9861411b957fffffffff0000000000000000000000000000000000000000000000000000000093896142375767ffffffffffffffff8216600052600b6020526040600020906040519161405283613d09565b549163ffffffff8316815263ffffffff8360201c16602082015263ffffffff8360401c16604082015263ffffffff8360601c16606082015260c061ffff8460801c169182608082015260ff60a082019561ffff8160901c16875260a01c16151591829101526141e3575b50505067ffffffffffffffff905b6040519b8c997f06b859ef000000000000000000000000000000000000000000000000000000008b521660048a0152166024880152604487015216606485015260c0608485015260c4840191613f7b565b928180600095869560a483015203915afa9182156141d657819261413e57505090565b9091503d8083833e6141508183613d25565b810190602081830312610a405780519067ffffffffffffffff8211611118570181601f82011215610a405780519061418782613eba565b936141956040519586613d25565b82855260208086019360051b8301019384116106685750602001905b8282106141be5750505090565b602080916141cb84613f5a565b8152019101906141b1565b50604051903d90823e3d90fd5b92935067ffffffffffffffff928587161561421f575061271061420e61ffff61421594511683613ed2565b0490613f4d565b915b9038806140bc565b614231925061420e6127109183613ed2565b91614217565b67ffffffffffffffff91925061425b9061425561299536898b613d66565b90614934565b916140ca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b50505050505050506040516142a6602082613d25565b60008152600036813790565b67ffffffffffffffff909291926142f07fffffffff0000000000000000000000000000000000000000000000000000000060025460401b1685614a41565b16600052600b60205260406000206040519061430b82613d09565b549163ffffffff83169384835263ffffffff8460201c169384602085015263ffffffff8160401c169182604086015263ffffffff8260601c169081606087015261ffff8360801c169586608082015260ff61ffff8560901c16948560a084015260a01c16159060c082159101526143b8577fffffffff00000000000000000000000000000000000000000000000000000000166143ad57505093929190600190565b959493509160019150565b5050505092505050600090600090600090600090600090565b604051906143de82613ced565b60006080838281528260208201528260408201528260608201520152565b9060405161440981613ced565b60806001829460ff81546fffffffffffffffffffffffffffffffff8116865263ffffffff81861c16602087015260a01c161515604085015201546fffffffffffffffffffffffffffffffff81166060840152811c910152565b67ffffffffffffffff916144746143d1565b5061447d6143d1565b506144b157166000526008602052604060002090613de66144a560026144aa6144a5866143fc565b614b28565b94016143fc565b16908160005260046020526144cc6144a560406000206143fc565b916000526005602052613de66144a560406000206143fc565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215613abc570180359067ffffffffffffffff8211613abc57602001918136038313613abc57565b3573ffffffffffffffffffffffffffffffffffffffff81168103613abc5790565b3567ffffffffffffffff81168103613abc5790565b9067ffffffffffffffff613de692166000526008602052600560406000200190602081519101209060019160005201602052604060002054151590565b604051906145b682613cd1565b60606020838281520152565b80518210156145d65760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600182811c9216801561464e575b602083101461461f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f1691614614565b906040519182600082549261466c84614605565b80845293600181169081156146da5750600114614693575b5061469192500383613d25565b565b90506000929192526020600020906000915b8183106146be5750509060206146919282010138614684565b60209193508060019154838589010152019101909184926146a5565b602093506146919592507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682840152151560051b82010138614684565b67ffffffffffffffff166000526008602052613de66004604060002001614658565b91908110156145d65760081b0190565b358015158103613abc5790565b3561ffff81168103613abc5790565b3563ffffffff81168103613abc5790565b359063ffffffff82168203613abc57565b359061ffff82168203613abc57565b91908110156145d65760051b0190565b35906fffffffffffffffffffffffffffffffff82168203613abc57565b9190826060910312613abc576040516060810181811067ffffffffffffffff821117613ca257604052604061481981839561480081613c79565b855261480e602082016147a9565b6020860152016147a9565b910152565b6fffffffffffffffffffffffffffffffff61485c6040809361483f81613c79565b1515865283614850602083016147a9565b166020870152016147a9565b16910152565b81811061486d575050565b60008155600101614862565b805180156148e9576020036148ab578051602082810191830183900312613abc57519060ff82116148ab575060ff1690565b611fef906040519182917f953576f7000000000000000000000000000000000000000000000000000000008352602060048401526024830190613c1a565b50507f000000000000000000000000000000000000000000000000000000000000000090565b9060ff8091169116039060ff8211613ee557565b60ff16604d8111613ee557600a0a90565b907f00000000000000000000000000000000000000000000000000000000000000009060ff82169060ff811692828414614a3a57828411614a1057906149799161490f565b91604d60ff84161180156149d7575b6149a15750509061499b613de692614923565b90613ed2565b9091507fa9cb113d0000000000000000000000000000000000000000000000000000000060005260045260245260445260646000fd5b506149e183614923565b8015613f1e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048411614988565b614a199161490f565b91604d60ff8416116149a157505090614a34613de692614923565b90613f14565b5050505090565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115614b2357614a7481615252565b7dffff00000000000000000000000000000000000000000000000000000000601082811c9085901c1616614b235761ffff8360e01c168015918215614b12575b5050614abe575050565b7fffffffff0000000000000000000000000000000000000000000000000000000092507fdf63778f000000000000000000000000000000000000000000000000000000006000526004521660245260446000fd5b60e01c61ffff161090503880614ab4565b505050565b614b306143d1565b506fffffffffffffffffffffffffffffffff6060820151166fffffffffffffffffffffffffffffffff8083511691614b8d6020850193614b87614b7a63ffffffff87511642613f4d565b8560808901511690613ed2565b90615245565b80821015614ba657505b16825263ffffffff4216905290565b9050614b97565b90816020910312613abc57518015158103613abc5790565b73ffffffffffffffffffffffffffffffffffffffff600154163303614be657565b7f2b5c74de0000000000000000000000000000000000000000000000000000000060005260046000fd5b90805115614e505767ffffffffffffffff81516020830120921691826000526008602052614c458160056040600020016158a9565b15614e0c5760005260096020526040600020815167ffffffffffffffff8111613ca257614c728254614605565b601f8111614dda575b506020601f8211600114614d145791614cee827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea9593614d0495600091614d09575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b9055604051918291602083526020830190613c1a565b0390a2565b905084015138614cbd565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082169083600052806000209160005b818110614dc2575092614d049492600192827f7d628c9a1796743d365ab521a8b2a4686e419b3269919dc9145ea2ce853b54ea989610614d8b575b5050811b019055611c9d565b8501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690553880614d7f565b9192602060018192868a015181550194019201614d44565b614e0690836000526020600020601f840160051c81019160208510610e9057601f0160051c0190614862565b38614c7b565b5090611fef6040519283927f393b8ad20000000000000000000000000000000000000000000000000000000084526004840152604060248401526044830190613c1a565b7f14c880ca0000000000000000000000000000000000000000000000000000000060005260046000fd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016803b15613abc5767ffffffffffffffff906064604051809481937fa36a7fee0000000000000000000000000000000000000000000000000000000083526000978896879373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600487015216602485015260448401525af1801561066b57614f4c575050565b81614f5691613d25565b50565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016602082015260208152613de6604082613d25565b815191929115615116576fffffffffffffffffffffffffffffffff6040840151166fffffffffffffffffffffffffffffffff602085015116106150b35761469191925b805182547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690151560a01b74ff0000000000000000000000000000000000000000161782556020810151825460409290920151608090811b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff9290921691821760018501557fffffffffffffffffffffffff0000000000000000000000000000000000000000909216174290911b73ffffffff0000000000000000000000000000000016179055565b606483615114604051917f8020d12400000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565bfd5b6fffffffffffffffffffffffffffffffff604084015116158015906151a5575b615144576146919192614fd7565b606483615114604051917fd68af9cc00000000000000000000000000000000000000000000000000000000835260048301906fffffffffffffffffffffffffffffffff60408092805115158552826020820151166020860152015116910152565b506fffffffffffffffffffffffffffffffff6020840151161515615136565b906127109167ffffffffffffffff6151de60208301614557565b166000908152600b60205260409020917fffffffff00000000000000000000000000000000000000000000000000000000161561522f57606061ffff61522b935460901c16910135613ed2565b0490565b606061ffff61522b935460801c16910135613ed2565b91908201809211613ee557565b7fffffffff000000000000000000000000000000000000000000000000000000008116908115615329577dffff000000000000000000000000000000000000000000000000000000008116156153205760ff60015b169060f01c806152ea575b506001036152bd5750565b7fc512f96c0000000000000000000000000000000000000000000000000000000060005260045260246000fd5b60005b601081106152fb57506152b2565b6001811b821661530e575b6001016152ed565b9160018101809111613ee55791615306565b60ff60006152a7565b5050565b9167ffffffffffffffff7f50f6fbee3ceedce6b7fd7eaef18244487867e6718aec7208187efb6b7908c14c921692836000526008602052615376818360026040600020016158fe565b6040805173ffffffffffffffffffffffffffffffffffffffff909216825260208201929092529081908101614d04565b91909167ffffffffffffffff83169283600052600560205260ff60406000205460a01c161561540b5750907fc6735cd4fa2bbe7b203b1682936e6ee61bc1702464bbbd12abb6630229d9a5f991836000526005602052615376818360406000206158fe565b90614691935061532d565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182360301811215613abc57016020813591019167ffffffffffffffff8211613abc578136038313613abc57565b9167ffffffffffffffff7fff0133389f9bb82d5b9385826160eaf2328039f6fa950eeb8cf0836da8178944921692836000526008602052615376818360406000206158fe565b91909167ffffffffffffffff83169283600052600460205260ff60406000205460a01c16156155115750907f28d6c52e2b0b7587b0d195539fbe6af984b28791aca4d2cc0844244e38bce29e91836000526004602052615376818360406000206158fe565b906146919350615466565b906040519182815491828252602082019060005260206000209260005b81811061554e57505061469192500383613d25565b8454835260019485019487945060209093019201615539565b80548210156145d65760005260206000200190600090565b600081815260076020526040902054801561570e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613ee557600654907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613ee55781810361569f575b5050506006548015615670577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161562d816006615567565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b19169055600655600052600760205260006040812055600190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6156f66156b06156c1936006615567565b90549060031b1c9283926006615567565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b905560005260076020526040600020553880806155f4565b5050600090565b9060018201918160005282602052604060002054801515600014615840577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111613ee5578254907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211613ee557818103615809575b50505080548015615670577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01906157ca8282615567565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b191690555560005260205260006040812055600190565b6158296158196156c19386615567565b90549060031b1c92839286615567565b905560005283602052604060002055388080615792565b50505050600090565b806000526007602052604060002054156000146158a35760065468010000000000000000811015613ca25761588a6156c18260018594016006556006615567565b9055600654906000526007602052604060002055600190565b50600090565b600082815260018201602052604090205461570e5780549068010000000000000000821015613ca257826158e76156c1846001809601855584615567565b905580549260005201602052604060002055600190565b9182549060ff8260a01c16158015615bb2575b615bac576fffffffffffffffffffffffffffffffff8216916001850190815461595663ffffffff6fffffffffffffffffffffffffffffffff83169360801c1642613f4d565b9081615b0e575b5050848110615ac257508383106159b757505061598c6fffffffffffffffffffffffffffffffff928392613f4d565b16167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055565b9190915460801c928315615a5657816159cf91613f4d565b927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190808211613ee557615a1d615a229273ffffffffffffffffffffffffffffffffffffffff96615245565b613f14565b7fd0c8d23a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b73ffffffffffffffffffffffffffffffffffffffff83837fd0c8d23a000000000000000000000000000000000000000000000000000000006000527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6004526024521660445260646000fd5b828573ffffffffffffffffffffffffffffffffffffffff927f1a76572a000000000000000000000000000000000000000000000000000000006000526004526024521660445260646000fd5b828692939611615b8257615b2992614b879160801c90613ed2565b80841015615b7d5750825b85547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff164260801b73ffffffff000000000000000000000000000000001617865592388061595d565b615b34565b7f9725942a0000000000000000000000000000000000000000000000000000000060005260046000fd5b50505050565b50821561591156fea164736f6c634300081a000a' as const +// generate:end diff --git a/package-lock.json b/package-lock.json index 4f8683e6..43a772b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "ccip-api-ref" ], "devDependencies": { + "@chainlink/contracts-ccip": "2.0.0", "@eslint/js": "^10.0.1", "@types/node": "25.9.3", "c8": "^11.0.0", @@ -603,6 +604,28 @@ "node": ">=20.0.0" } }, + "node_modules/@arbitrum/nitro-contracts": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@arbitrum/nitro-contracts/-/nitro-contracts-3.0.0.tgz", + "integrity": "sha512-7VzNW9TxvrX9iONDDsi7AZlEUPa6z+cjBkB4Mxlnog9VQZAapRC3CdRXyUzHnBYmUhRzyNJdyxkWPw59QGcLmA==", + "dev": true, + "hasInstallScript": true, + "license": "BUSL-1.1", + "dependencies": { + "@offchainlabs/upgrade-executor": "1.1.0-beta.0", + "@openzeppelin/contracts": "4.7.3", + "@openzeppelin/contracts-upgradeable": "4.7.3", + "patch-package": "^6.4.7", + "solady": "0.0.182" + } + }, + "node_modules/@arbitrum/nitro-contracts/node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.3.tgz", + "integrity": "sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -2352,6 +2375,13 @@ "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", "license": "MIT" }, + "node_modules/@chainlink/ace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@chainlink/ace/-/ace-1.0.0.tgz", + "integrity": "sha512-lamF+fabw5cyIQ+7PA5QkEl0GyHmmH3lc875jrspo9VxsxiKbMxDcRDGPEuubFQS3Zcx7H/Z80C72+Xm/FgeqA==", + "dev": true, + "license": "BUSL-1.1" + }, "node_modules/@chainlink/ccip-api-ref": { "resolved": "ccip-api-ref", "link": true @@ -2364,6 +2394,115 @@ "resolved": "ccip-sdk", "link": true }, + "node_modules/@chainlink/contracts": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-1.5.0.tgz", + "integrity": "sha512-1fGJwjvivqAxvVOTqZUEXGR54CATtg0vjcXgSIk4Cfoad2nUhSG/qaWHXjLg1CkNTeOoteoxGQcpP/HiA5HsUA==", + "dev": true, + "license": "BUSL-1.1", + "dependencies": { + "@arbitrum/nitro-contracts": "3.0.0", + "@changesets/cli": "^2.29.6", + "@changesets/get-github-info": "^0.6.0", + "@eslint/eslintrc": "^3.3.1", + "@eth-optimism/contracts": "0.6.0", + "@openzeppelin/contracts-4.7.3": "npm:@openzeppelin/contracts@4.7.3", + "@openzeppelin/contracts-4.8.3": "npm:@openzeppelin/contracts@4.8.3", + "@openzeppelin/contracts-4.9.6": "npm:@openzeppelin/contracts@4.9.6", + "@openzeppelin/contracts-5.0.2": "npm:@openzeppelin/contracts@5.0.2", + "@openzeppelin/contracts-5.1.0": "npm:@openzeppelin/contracts@5.1.0", + "@openzeppelin/contracts-upgradeable": "4.9.6", + "@scroll-tech/contracts": "2.0.0", + "@zksync/contracts": "github:matter-labs/era-contracts#446d391d34bdb48255d5f8fef8a8248925fc98b9", + "semver": "^7.7.2" + }, + "engines": { + "node": ">=22", + "pnpm": ">=10" + } + }, + "node_modules/@chainlink/contracts-ccip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@chainlink/contracts-ccip/-/contracts-ccip-2.0.0.tgz", + "integrity": "sha512-P0KvQtZSYC1LevMSS16jOOSsqZG4g0n/MJdcWGmE0Z5U01NVYd1MnTQJOBPsbu1NWR79DBXPXLvyr9tR5y+tiw==", + "dev": true, + "license": "BUSL-1.1", + "dependencies": { + "@chainlink/ace": "1.0.0", + "@chainlink/contracts": "1.5.0", + "@openzeppelin/contracts-4.8.3": "npm:@openzeppelin/contracts@4.8.3", + "@openzeppelin/contracts-5.3.0": "npm:@openzeppelin/contracts@5.3.0" + }, + "engines": { + "node": ">=20", + "pnpm": ">=10" + } + }, + "node_modules/@chainlink/contracts/node_modules/@eth-optimism/contracts": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eth-optimism/contracts/-/contracts-0.6.0.tgz", + "integrity": "sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eth-optimism/core-utils": "0.12.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0" + }, + "peerDependencies": { + "ethers": "^5" + } + }, + "node_modules/@chainlink/contracts/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, "node_modules/@chainlink/design-system": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/@chainlink/design-system/-/design-system-0.2.8.tgz", @@ -2375,199 +2514,753 @@ "tailwindcss-animate": "1.0.7" } }, - "node_modules/@chevrotain/types": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz", - "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", - "license": "Apache-2.0" - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "node_modules/@changesets/apply-release-plan": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.1.1.tgz", + "integrity": "sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==", + "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" + "dependencies": { + "@changesets/config": "^3.1.4", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" } }, - "node_modules/@coral-xyz/anchor": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz", - "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==", - "license": "(MIT OR Apache-2.0)", + "node_modules/@changesets/apply-release-plan/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", "dependencies": { - "@coral-xyz/borsh": "^0.29.0", - "@noble/hashes": "^1.3.1", - "@solana/web3.js": "^1.68.0", - "bn.js": "^5.1.2", - "bs58": "^4.0.1", - "buffer-layout": "^1.2.2", - "camelcase": "^6.3.0", - "cross-fetch": "^3.1.5", - "crypto-hash": "^1.3.0", - "eventemitter3": "^4.0.7", - "pako": "^2.0.3", - "snake-case": "^3.0.4", - "superstruct": "^0.15.4", - "toml": "^3.0.0" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=11" + "node": ">=6 <7 || >=8" } }, - "node_modules/@coral-xyz/anchor/node_modules/base-x": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", - "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "node_modules/@changesets/apply-release-plan/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, "license": "MIT", - "dependencies": { - "safe-buffer": "^5.0.1" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/@coral-xyz/anchor/node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "node_modules/@changesets/apply-release-plan/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, "license": "MIT", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/@coral-xyz/anchor/node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "license": "MIT" - }, - "node_modules/@coral-xyz/borsh": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", - "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", - "license": "Apache-2.0", - "dependencies": { - "bn.js": "^5.1.2", - "buffer-layout": "^1.2.0" + "bin": { + "prettier": "bin-prettier.js" }, "engines": { - "node": ">=10" + "node": ">=10.13.0" }, - "peerDependencies": { - "@solana/web3.js": "^1.68.0" + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/@csstools/cascade-layer-name-parser": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", - "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], + "node_modules/@changesets/apply-release-plan/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "node": ">=8" } }, - "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", + "node_modules/@changesets/apply-release-plan/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">= 4.0.0" } }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.10.tgz", + "integrity": "sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz", + "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.31.0.tgz", + "integrity": "sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^7.1.1", + "@changesets/assemble-release-plan": "^6.0.10", + "@changesets/changelog-git": "^0.2.1", + "@changesets/config": "^3.1.4", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/get-release-plan": "^4.0.16", + "@changesets/git": "^3.0.4", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.7", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@changesets/write": "^0.4.0", + "@inquirer/external-editor": "^1.0.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "enquirer": "^2.4.1", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "bin": { + "changeset": "bin.js" } }, - "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], + "node_modules/@changesets/cli/node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" }, "engines": { "node": ">=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], + "node_modules/@changesets/cli/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@changesets/cli/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@changesets/cli/node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } + }, + "node_modules/@changesets/cli/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@changesets/cli/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@changesets/config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.4.tgz", + "integrity": "sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.4", + "@changesets/logger": "^0.1.1", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/config/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@changesets/config/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@changesets/config/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "license": "MIT", + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.4.tgz", + "integrity": "sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-github-info": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.6.0.tgz", + "integrity": "sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dataloader": "^1.4.0", + "node-fetch": "^2.5.0" + } + }, + "node_modules/@changesets/get-github-info/node_modules/dataloader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", + "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.16.tgz", + "integrity": "sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.10", + "@changesets/config": "^3.1.4", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.7", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/git": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz", + "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.3.tgz", + "integrity": "sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "js-yaml": "^4.1.1" + } + }, + "node_modules/@changesets/pre": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz", + "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/pre/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@changesets/pre/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@changesets/pre/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.7.tgz", + "integrity": "sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^3.0.4", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.3", + "@changesets/types": "^6.1.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/read/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@changesets/read/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@changesets/read/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz", + "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz", + "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@changesets/write": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz", + "integrity": "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^6.1.0", + "fs-extra": "^7.0.1", + "human-id": "^4.1.1", + "prettier": "^2.7.1" + } + }, + "node_modules/@changesets/write/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@changesets/write/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@changesets/write/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@changesets/write/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@chevrotain/types": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.2.tgz", + "integrity": "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==", + "license": "Apache-2.0" + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@coral-xyz/anchor": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/anchor/-/anchor-0.29.0.tgz", + "integrity": "sha512-eny6QNG0WOwqV0zQ7cs/b1tIuzZGmP7U7EcH+ogt4Gdbl8HDmIYVMh/9aTmYZPaFWjtUaI8qSn73uYEXWfATdA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@coral-xyz/borsh": "^0.29.0", + "@noble/hashes": "^1.3.1", + "@solana/web3.js": "^1.68.0", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^6.3.0", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "superstruct": "^0.15.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@coral-xyz/anchor/node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@coral-xyz/anchor/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@coral-xyz/anchor/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/@coral-xyz/borsh": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@coral-xyz/borsh/-/borsh-0.29.0.tgz", + "integrity": "sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.68.0" + } + }, + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", + "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" } }, "node_modules/@csstools/css-tokenizer": { @@ -5720,17 +6413,116 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@eslint/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", - "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@eslint/js": { @@ -5778,6 +6570,31 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, + "node_modules/@eth-optimism/core-utils": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eth-optimism/core-utils/-/core-utils-0.12.0.tgz", + "integrity": "sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/contracts": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/providers": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bufio": "^1.0.7", + "chai": "^4.3.4" + } + }, "node_modules/@ethers-ext/signer-ledger": { "version": "6.0.0-beta.1", "resolved": "https://registry.npmjs.org/@ethers-ext/signer-ledger/-/signer-ledger-6.0.0-beta.1.tgz", @@ -5895,10 +6712,274 @@ "@ethersproject/rlp": "^5.8.0" } }, - "node_modules/@ethersproject/base64": { + "node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz", + "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", + "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.8.0", + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.8.0.tgz", + "integrity": "sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", + "integrity": "sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", - "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", "funding": [ { "type": "individual", @@ -5911,13 +6992,14 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.8.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/@ethersproject/bignumber": { + "node_modules/@ethersproject/pbkdf2": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", - "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz", + "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==", + "dev": true, "funding": [ { "type": "individual", @@ -5929,16 +7011,16 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "bn.js": "^5.2.1" + "@ethersproject/sha2": "^5.8.0" } }, - "node_modules/@ethersproject/bytes": { + "node_modules/@ethersproject/properties": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", - "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", "funding": [ { "type": "individual", @@ -5954,10 +7036,11 @@ "@ethersproject/logger": "^5.8.0" } }, - "node_modules/@ethersproject/constants": { + "node_modules/@ethersproject/providers": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", - "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", + "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", + "dev": true, "funding": [ { "type": "individual", @@ -5970,13 +7053,33 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/bignumber": "^5.8.0" + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0", + "bech32": "1.1.4", + "ws": "8.18.0" } }, - "node_modules/@ethersproject/hash": { + "node_modules/@ethersproject/random": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", - "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.8.0.tgz", + "integrity": "sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==", + "dev": true, "funding": [ { "type": "individual", @@ -5989,21 +7092,14 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/@ethersproject/keccak256": { + "node_modules/@ethersproject/rlp": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", - "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", "funding": [ { "type": "individual", @@ -6017,13 +7113,14 @@ "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.8.0", - "js-sha3": "0.8.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/@ethersproject/logger": { + "node_modules/@ethersproject/sha2": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", - "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz", + "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==", + "dev": true, "funding": [ { "type": "individual", @@ -6034,12 +7131,17 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "license": "MIT" + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "hash.js": "1.1.7" + } }, - "node_modules/@ethersproject/networks": { + "node_modules/@ethersproject/signing-key": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", - "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", "funding": [ { "type": "individual", @@ -6052,13 +7154,19 @@ ], "license": "MIT", "dependencies": { - "@ethersproject/logger": "^5.8.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" } }, - "node_modules/@ethersproject/properties": { + "node_modules/@ethersproject/solidity": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", - "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.8.0.tgz", + "integrity": "sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==", + "dev": true, "funding": [ { "type": "individual", @@ -6070,14 +7178,20 @@ } ], "license": "MIT", + "peer": true, "dependencies": { - "@ethersproject/logger": "^5.8.0" + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, - "node_modules/@ethersproject/rlp": { + "node_modules/@ethersproject/strings": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", - "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", "funding": [ { "type": "individual", @@ -6091,13 +7205,14 @@ "license": "MIT", "dependencies": { "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", "@ethersproject/logger": "^5.8.0" } }, - "node_modules/@ethersproject/signing-key": { + "node_modules/@ethersproject/transactions": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", - "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", "funding": [ { "type": "individual", @@ -6110,18 +7225,22 @@ ], "license": "MIT", "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", "@ethersproject/logger": "^5.8.0", "@ethersproject/properties": "^5.8.0", - "bn.js": "^5.2.1", - "elliptic": "6.6.1", - "hash.js": "1.1.7" + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" } }, - "node_modules/@ethersproject/strings": { + "node_modules/@ethersproject/units": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", - "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", + "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", + "dev": true, "funding": [ { "type": "individual", @@ -6133,16 +7252,18 @@ } ], "license": "MIT", + "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", "@ethersproject/constants": "^5.8.0", "@ethersproject/logger": "^5.8.0" } }, - "node_modules/@ethersproject/transactions": { + "node_modules/@ethersproject/wallet": { "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", + "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", + "dev": true, "funding": [ { "type": "individual", @@ -6154,16 +7275,23 @@ } ], "license": "MIT", + "peer": true, "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", "@ethersproject/address": "^5.8.0", "@ethersproject/bignumber": "^5.8.0", "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/json-wallets": "^5.8.0", "@ethersproject/keccak256": "^5.8.0", "@ethersproject/logger": "^5.8.0", "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" + "@ethersproject/random": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" } }, "node_modules/@ethersproject/web": { @@ -6189,6 +7317,31 @@ "@ethersproject/strings": "^5.8.0" } }, + "node_modules/@ethersproject/wordlists": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.8.0.tgz", + "integrity": "sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, "node_modules/@exodus/schemasafe": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", @@ -7535,11 +8688,179 @@ "rxjs": "7.8.2" } }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "license": "MIT" + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" + }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@manypkg/find-root/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@manypkg/find-root/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@manypkg/find-root/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@manypkg/get-packages/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } }, "node_modules/@mdx-js/mdx": { "version": "3.1.1", @@ -7938,9 +9259,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7957,9 +9275,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -7976,9 +9291,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -7995,9 +9307,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -8118,6 +9427,86 @@ "node": ">= 8" } }, + "node_modules/@offchainlabs/upgrade-executor": { + "version": "1.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@offchainlabs/upgrade-executor/-/upgrade-executor-1.1.0-beta.0.tgz", + "integrity": "sha512-mpn6PHjH/KDDjNX0pXHEKdyv8m6DVGQiI2nGzQn0JbM1nOSHJpWx6fvfjtH7YxHJ6zBZTcsKkqGkFKDtCfoSLw==", + "dev": true, + "license": "Apache 2.0", + "dependencies": { + "@openzeppelin/contracts": "4.7.3", + "@openzeppelin/contracts-upgradeable": "4.7.3" + } + }, + "node_modules/@offchainlabs/upgrade-executor/node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.3.tgz", + "integrity": "sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz", + "integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-4.7.3": { + "name": "@openzeppelin/contracts", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz", + "integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-4.8.3": { + "name": "@openzeppelin/contracts", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.3.tgz", + "integrity": "sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-4.9.6": { + "name": "@openzeppelin/contracts", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.6.tgz", + "integrity": "sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-5.0.2": { + "name": "@openzeppelin/contracts", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.2.tgz", + "integrity": "sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-5.1.0": { + "name": "@openzeppelin/contracts", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.1.0.tgz", + "integrity": "sha512-p1ULhl7BXzjjbha5aqst+QMLY+4/LCWADXOCsmLHRM77AqiPjnd9vvUN9sosUfhL9JGKpZ0TjEGxgvnizmWGSA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-5.3.0": { + "name": "@openzeppelin/contracts", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.3.0.tgz", + "integrity": "sha512-zj/KGoW7zxWUE8qOI++rUM18v+VeLTTzKs/DJFkSzHpQFPD/jKKF0TrMxBfGLl3kpdELCNccvB3zmofSzm4nlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.6.tgz", + "integrity": "sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA==", + "dev": true, + "license": "MIT" + }, "node_modules/@parcel/watcher": { "version": "2.5.6", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", @@ -8241,9 +9630,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -8264,9 +9650,6 @@ "cpu": [ "arm" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -8287,9 +9670,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -8310,9 +9690,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -8333,9 +9710,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -8356,9 +9730,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -8783,6 +10154,13 @@ } } }, + "node_modules/@scroll-tech/contracts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@scroll-tech/contracts/-/contracts-2.0.0.tgz", + "integrity": "sha512-O8sVaA/bVKH/mp+bBfUjZ/vYr5mdBExCpKRLre4r9TbXTtiaY9Uo5xU8dcG3weLxyK0BZqDTP2aCNp4Q0f7SeA==", + "dev": true, + "license": "MIT" + }, "node_modules/@scure/base": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@scure/base/-/base-2.2.0.tgz", @@ -10840,9 +12218,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -10857,9 +12232,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -10874,9 +12246,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -10891,9 +12260,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -10908,9 +12274,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -10925,9 +12288,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -10942,9 +12302,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -10959,9 +12316,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -10976,9 +12330,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -10993,9 +12344,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -11245,6 +12593,31 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "license": "Apache-2.0" }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/@zksync/contracts": { + "name": "era-contracts", + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/matter-labs/era-contracts.git#446d391d34bdb48255d5f8fef8a8248925fc98b9", + "integrity": "sha512-KhgPVqd/MgV/ICUEsQf1uyL321GNPqsyHSAPMCaa9vW94fbuQK6RwMWoyQOPlZP17cQD8tzLNCSXqz73652kow==", + "dev": true, + "workspaces": { + "packages": [ + "l1-contracts", + "l2-contracts", + "system-contracts", + "gas-bound-caller" + ], + "nohoist": [ + "**/@openzeppelin/**" + ] + } + }, "node_modules/abitype": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.4.tgz", @@ -11504,6 +12877,16 @@ "string-width": "^4.1.0" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -11631,6 +13014,16 @@ "node": ">=12.0.0" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/astring": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", @@ -11652,6 +13045,16 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/atomically": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.1.1.tgz", @@ -11848,6 +13251,26 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "license": "MIT" }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -12269,6 +13692,16 @@ "node": ">=6.14.2" } }, + "node_modules/bufio": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.2.3.tgz", + "integrity": "sha512-5Tt66bRzYUSlVZatc0E92uDenreJ+DpTBmSAUwL4VSxJn3e6cUyYwx+PoqML0GRZatgA/VX8ybhxItF8InZgqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/bundle-name": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", @@ -12516,6 +13949,25 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -12603,6 +14055,19 @@ "node": ">=4.0.0" } }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", @@ -14308,6 +15773,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -14471,6 +15949,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -14946,6 +16434,20 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -16018,6 +17520,13 @@ "node": ">=0.10.0" } }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true, + "license": "MIT" + }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -16383,6 +17892,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -16624,6 +18143,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -16811,6 +18340,19 @@ "node": ">=10" } }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -17610,6 +19152,16 @@ "node": ">= 6" } }, + "node_modules/human-id": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.2.0.tgz", + "integrity": "sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==", + "dev": true, + "license": "MIT", + "bin": { + "human-id": "dist/cli.js" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -18161,6 +19713,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -18180,6 +19745,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -18877,6 +20452,13 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "license": "MIT" }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -18905,6 +20487,16 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -21609,6 +23201,16 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT" }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -21737,6 +23339,13 @@ "node": ">= 10" } }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -22354,6 +23963,23 @@ "node": ">= 0.8.0" } }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true, + "license": "MIT" + }, "node_modules/ox": { "version": "0.14.29", "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.29.tgz", @@ -22413,11 +24039,34 @@ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "license": "MIT", - "peer": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^2.0.0" + }, "engines": { "node": ">=8" } }, + "node_modules/p-filter/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -22525,6 +24174,16 @@ "node": ">=8" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/package-json": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz", @@ -22734,6 +24393,182 @@ "tslib": "^2.0.3" } }, + "node_modules/patch-package": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz", + "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^9.0.0", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33", + "yaml": "^1.10.2" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "node": ">=10", + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/patch-package/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/patch-package/node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/patch-package/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/patch-package/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/patch-package/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-package/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/patch-package/node_modules/yaml": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -22821,6 +24656,16 @@ "node": ">=8" } }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -25087,6 +26932,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -25444,6 +27306,32 @@ "pify": "^2.3.0" } }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -26072,6 +27960,73 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rimraf/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/robust-predicates": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", @@ -26407,6 +28362,14 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/search-insights": { "version": "2.17.3", "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", @@ -27117,6 +29080,13 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/solady": { + "version": "0.0.182", + "resolved": "https://registry.npmjs.org/solady/-/solady-0.0.182.tgz", + "integrity": "sha512-FW6xo1akJoYpkXMzu58/56FcNU3HYYNamEbnFO3iSibXk0nSHo0DV2Gu/zI3FPg3So5CCX6IYli1TT1IWATnvg==", + "dev": true, + "license": "MIT" + }, "node_modules/sort-css-media-queries": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", @@ -27173,6 +29143,17 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", @@ -27349,6 +29330,16 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/strip-bom-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", @@ -27721,6 +29712,19 @@ "node": ">=6" } }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/terser": { "version": "5.48.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", @@ -27949,6 +29953,19 @@ "node": "^18.0.0 || >=20.0.0" } }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -28152,6 +30169,16 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.7.0.tgz", diff --git a/package.json b/package.json index a3cebcad..3abfca46 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "prepare": "npm run build" }, "devDependencies": { + "@chainlink/contracts-ccip": "2.0.0", "@eslint/js": "^10.0.1", "@types/node": "25.9.3", "c8": "^11.0.0", From 653053837701a1756a2dfc7b9e6a60bfc57ddd3e Mon Sep 17 00:00:00 2001 From: Pedro Barbosa <14206093+apedrob@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:54:08 +0100 Subject: [PATCH 10/22] feat(cct-sdk): Add CrossChainToken deployment + token versioning (#305) * feat(cct-sdk): Source token + pool abi/bytecode from contracts-ccip * feat(cct-sdk): Add versioned Deploy Token (CCT + ERC20) * Remove outdated bytecodes * Deploy only CrossChainToken * Recover previous type changes --- ccip-cli/src/index.ts | 2 +- ccip-sdk/src/api/index.ts | 2 +- ccip-sdk/src/cct/evm/index.ts | 15 +- ccip-sdk/src/cct/evm/operation.ts | 8 + ccip-sdk/src/cct/evm/token/bytecode.ts | 15 - .../evm/token/operations/deploy-token.test.ts | 264 +++++++++++------- .../cct/evm/token/operations/deploy-token.ts | 92 ++++-- ccip-sdk/src/cct/evm/token/version.ts | 74 +++++ ccip-sdk/src/selectors.ts | 12 + 9 files changed, 331 insertions(+), 153 deletions(-) delete mode 100644 ccip-sdk/src/cct/evm/token/bytecode.ts create mode 100644 ccip-sdk/src/cct/evm/token/version.ts diff --git a/ccip-cli/src/index.ts b/ccip-cli/src/index.ts index bfde8466..e38ab5b5 100755 --- a/ccip-cli/src/index.ts +++ b/ccip-cli/src/index.ts @@ -28,7 +28,7 @@ Error.stackTraceLimit = 50 // show more stack frames for better debugging // generate:nofail // `const VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -const VERSION = '1.10.2-ca537a7' +const VERSION = '1.10.2-f7eb21b' // generate:end const require = createRequire(import.meta.url) diff --git a/ccip-sdk/src/api/index.ts b/ccip-sdk/src/api/index.ts index 1a9af743..9e4d68b4 100644 --- a/ccip-sdk/src/api/index.ts +++ b/ccip-sdk/src/api/index.ts @@ -62,7 +62,7 @@ export const DEFAULT_TIMEOUT_MS = 30000 /** SDK version string for telemetry header */ // generate:nofail // `export const SDK_VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -export const SDK_VERSION = '1.10.2-ca537a7' +export const SDK_VERSION = '1.10.2-f7eb21b' // generate:end /** SDK telemetry header name */ diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 0c96ef8c..3658f1f8 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -121,9 +121,9 @@ export class EVMTokenManager extends TokenManager { } /** - * Builds an unsigned `BurnMintERC677Token` deployment tx (for multisig / offline signing). - * The deployed address is only known once mined, so it is NOT returned here — use - * {@link deployToken} to deploy and receive `{ hash, contractAddress }`. + * Builds an unsigned `CrossChainToken` (v2.0.0) deployment tx (for multisig / offline + * signing). The deployed address is only known once mined, so it is NOT returned here — + * use {@link deployToken} to deploy and receive `{ hash, contractAddress }`. * @throws {@link CCTParamsInvalidError} if any param is invalid * @example * ```typescript @@ -132,6 +132,7 @@ export class EVMTokenManager extends TokenManager { * symbol: 'MTK', * decimals: 18, * maxSupply: 0n, // 0 = unlimited + * owner: '0xOwner...', // CrossChainToken v2.0.0; ccipAdmin/burnMintRoleAdmin default to owner * sender: '0xDeployer...', * }) * ``` @@ -141,9 +142,8 @@ export class EVMTokenManager extends TokenManager { } /** - * Deploys a `BurnMintERC677Token`, signing + submitting with `opts.wallet`; resolves to - * the tx hash and the newly deployed token address. Deploys with zero supply and no roles - * granted — call `grantMintAndBurnRoles` before `mint`, or it reverts on access control. + * Deploys a `CrossChainToken` (v2.0.0), signing + submitting with `opts.wallet`; resolves + * to the tx hash and the newly deployed token address. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address @@ -154,6 +154,7 @@ export class EVMTokenManager extends TokenManager { * symbol: 'MTK', * decimals: 18, * maxSupply: 0n, + * owner: '0xOwner...', * wallet, * }) * ``` @@ -166,5 +167,5 @@ export class EVMTokenManager extends TokenManager { export * from '../errors.ts' export type { SetPoolParams } from './token-admin-registry/operations/set-pool.ts' export type { DeployTokenParams } from './token/operations/deploy-token.ts' +export type { DeployResult } from './operation.ts' export type { TransactionResult } from '../operation.ts' -export type { DeployResult, EVMExecuteParams } from './operation.ts' diff --git a/ccip-sdk/src/cct/evm/operation.ts b/ccip-sdk/src/cct/evm/operation.ts index 09feb956..d0f29432 100644 --- a/ccip-sdk/src/cct/evm/operation.ts +++ b/ccip-sdk/src/cct/evm/operation.ts @@ -9,8 +9,15 @@ import type { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' +import { ChainFamily } from '../../networks.ts' import { type ExecuteParams, type TransactionResult, Operation } from '../operation.ts' import { submit } from './submit.ts' +import { validateAddress } from './validate.ts' + +/** Assembles a contract-deployment tx (no `to`): creation bytecode + ABI-encoded ctor args. */ +export function deploymentTx(bytecode: `0x${string}`, ctorArgs: string): UnsignedEVMTx { + return { family: ChainFamily.EVM, transactions: [{ data: bytecode + ctorArgs.slice(2) }] } +} /** EVM {@link ExecuteParams} — EVM ops need nothing beyond the signing `wallet`. */ export type EVMExecuteParams

= ExecuteParams

@@ -42,6 +49,7 @@ export abstract class EVMOperation

extends Operat /** Run {@link validate} and {@link buildUnsigned}, applying optional `sender`; no signing. */ async generate(chain: EVMChain, params: P): Promise { this.validate(params) + if (params.sender !== undefined) validateAddress(this.name, 'sender', params.sender) const unsigned = await this.buildUnsigned(chain, params) if (params.sender && unsigned.transactions[0]) unsigned.transactions[0].from = params.sender return unsigned diff --git a/ccip-sdk/src/cct/evm/token/bytecode.ts b/ccip-sdk/src/cct/evm/token/bytecode.ts deleted file mode 100644 index 57192207..00000000 --- a/ccip-sdk/src/cct/evm/token/bytecode.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Creation bytecode (init-code) for `BurnMintERC677Token` v1.5.1, paired with the - * ABI in `evm/abi/BurnMintERC677Token.ts` (same gethwrapper origin). ABI-encoded - * constructor args append directly to this to form a deployment transaction. - * - * @packageDocumentation - */ - -// generate: -// fetch('https://github.com/smartcontractkit/ccip/raw/release/contracts-ccip-1.5.1/core/gethwrappers/generated/burn_mint_erc677/burn_mint_erc677.go') -// .then((res) => res.text()) -// .then((body) => `export const BURN_MINT_ERC677_BYTECODE = '${body.match(/^\s*Bin: "(0x[0-9a-fA-F]+)",$/m)?.[1]}' as const`) -export const BURN_MINT_ERC677_BYTECODE = - '0x60c06040523480156200001157600080fd5b50604051620022dd380380620022dd833981016040819052620000349162000277565b338060008686818160036200004a838262000391565b50600462000059828262000391565b5050506001600160a01b0384169150620000bc90505760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600580546001600160a01b0319166001600160a01b0384811691909117909155811615620000ef57620000ef8162000106565b50505060ff90911660805260a052506200045d9050565b336001600160a01b03821603620001605760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000b3565b600680546001600160a01b0319166001600160a01b03838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001da57600080fd5b81516001600160401b0380821115620001f757620001f7620001b2565b604051601f8301601f19908116603f01168101908282118183101715620002225762000222620001b2565b816040528381526020925086838588010111156200023f57600080fd5b600091505b8382101562000263578582018301518183018401529082019062000244565b600093810190920192909252949350505050565b600080600080608085870312156200028e57600080fd5b84516001600160401b0380821115620002a657600080fd5b620002b488838901620001c8565b95506020870151915080821115620002cb57600080fd5b50620002da87828801620001c8565b935050604085015160ff81168114620002f257600080fd5b6060959095015193969295505050565b600181811c908216806200031757607f821691505b6020821081036200033857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200038c57600081815260208120601f850160051c81016020861015620003675750805b601f850160051c820191505b81811015620003885782815560010162000373565b5050505b505050565b81516001600160401b03811115620003ad57620003ad620001b2565b620003c581620003be845462000302565b846200033e565b602080601f831160018114620003fd5760008415620003e45750858301515b600019600386901b1c1916600185901b17855562000388565b600085815260208120601f198616915b828110156200042e578886015182559484019460019091019084016200040d565b50858210156200044d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a051611e4c6200049160003960008181610447015281816108c301526108ed015260006102710152611e4c6000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063c2e3273d116100a2578063d73dd62311610071578063d73dd6231461046b578063dd62ed3e1461047e578063f2fde38b146104c4578063f81094f3146104d757600080fd5b8063c2e3273d1461040c578063c630948d1461041f578063c64d0ebc14610432578063d5abeb011461044557600080fd5b80639dc29fac116100de5780639dc29fac146103c0578063a457c2d7146103d3578063a9059cbb146103e6578063aa271e1a146103f957600080fd5b806379cc67901461037557806386fe8b43146103885780638da5cb5b1461039057806395d89b41146103b857600080fd5b806340c10f19116101875780636618846311610156578063661884631461030f5780636b32810b1461032257806370a082311461033757806379ba50971461036d57600080fd5b806340c10f19146102c157806342966c68146102d65780634334614a146102e95780634f5632f8146102fc57600080fd5b806323b872dd116101c357806323b872dd14610257578063313ce5671461026a578063395093511461029b5780634000aea0146102ae57600080fd5b806301ffc9a7146101f557806306fdde031461021d578063095ea7b31461023257806318160ddd14610245575b600080fd5b6102086102033660046119b9565b6104ea565b60405190151581526020015b60405180910390f35b61022561061b565b6040516102149190611a5f565b610208610240366004611a9b565b6106ad565b6002545b604051908152602001610214565b610208610265366004611ac5565b6106c5565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610214565b6102086102a9366004611a9b565b6106e9565b6102086102bc366004611b30565b610735565b6102d46102cf366004611a9b565b610858565b005b6102d46102e4366004611c19565b61097f565b6102086102f7366004611c32565b6109cc565b6102d461030a366004611c32565b6109d9565b61020861031d366004611a9b565b610a35565b61032a610a48565b6040516102149190611c4d565b610249610345366004611c32565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6102d4610a59565b6102d4610383366004611a9b565b610b5a565b61032a610ba9565b60055460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b610225610bb5565b6102d46103ce366004611a9b565b610bc4565b6102086103e1366004611a9b565b610bce565b6102086103f4366004611a9b565b610c9f565b610208610407366004611c32565b610cad565b6102d461041a366004611c32565b610cba565b6102d461042d366004611c32565b610d16565b6102d4610440366004611c32565b610d24565b7f0000000000000000000000000000000000000000000000000000000000000000610249565b6102d4610479366004611a9b565b610d80565b61024961048c366004611ca7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6102d46104d2366004611c32565b610d8a565b6102d46104e5366004611c32565b610d9b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f36372b0700000000000000000000000000000000000000000000000000000000148061057d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4000aea000000000000000000000000000000000000000000000000000000000145b806105c957507fffffffff0000000000000000000000000000000000000000000000000000000082167fe6599b4d00000000000000000000000000000000000000000000000000000000145b8061061557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b60606003805461062a90611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461065690611cda565b80156106a35780601f10610678576101008083540402835291602001916106a3565b820191906000526020600020905b81548152906001019060200180831161068657829003601f168201915b5050505050905090565b6000336106bb818585610df7565b5060019392505050565b6000336106d3858285610e2b565b6106de858585610efc565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906106bb9082908690610730908790611d5c565b610df7565b60006107418484610c9f565b508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c1685856040516107a1929190611d6f565b60405180910390a373ffffffffffffffffffffffffffffffffffffffff84163b156106bb576040517fa4c0ed3600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063a4c0ed369061081c90339087908790600401611d90565b600060405180830381600087803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b505050505060019392505050565b61086133610cad565b61089e576040517fe2c8c9d50000000000000000000000000000000000000000000000000000000081523360048201526024015b60405180910390fd5b813073ffffffffffffffffffffffffffffffffffffffff8216036108c157600080fd5b7f00000000000000000000000000000000000000000000000000000000000000001580159061092257507f00000000000000000000000000000000000000000000000000000000000000008261091660025490565b6109209190611d5c565b115b15610970578161093160025490565b61093b9190611d5c565b6040517fcbbf111300000000000000000000000000000000000000000000000000000000815260040161089591815260200190565b61097a8383610f2a565b505050565b610988336109cc565b6109c0576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b6109c98161101d565b50565b6000610615600983611027565b6109e1611056565b6109ec6009826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f0a675452746933cefe3d74182e78db7afe57ba60eaa4234b5d85e9aa41b0610c90600090a250565b6000610a418383610bce565b9392505050565b6060610a5460076110fb565b905090565b60065473ffffffffffffffffffffffffffffffffffffffff163314610ada576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610895565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560068054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b610b63336109cc565b610b9b576040517fc820b10b000000000000000000000000000000000000000000000000000000008152336004820152602401610895565b610ba58282611108565b5050565b6060610a5460096110fb565b60606004805461062a90611cda565b610ba58282610b5a565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610895565b6106de8286868403610df7565b6000336106bb818585610efc565b6000610615600783611027565b610cc2611056565b610ccd60078261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fe46fef8bbff1389d9010703cf8ebb363fb3daf5bf56edc27080b67bc8d9251ea90600090a250565b610d1f81610cba565b6109c9815b610d2c611056565b610d3760098261111d565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907f92308bb7573b2a3d17ddb868b39d8ebec433f3194421abc22d084f89658c9bad90600090a250565b61097a82826106e9565b610d92611056565b6109c98161113f565b610da3611056565b610dae6007826110d9565b156109c95760405173ffffffffffffffffffffffffffffffffffffffff8216907fed998b960f6340d045f620c119730f7aa7995e7425c2401d3a5b64ff998a59e990600090a250565b813073ffffffffffffffffffffffffffffffffffffffff821603610e1a57600080fd5b610e25848484611235565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610e255781811015610eef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610895565b610e258484848403610df7565b813073ffffffffffffffffffffffffffffffffffffffff821603610f1f57600080fd5b610e258484846113e8565b73ffffffffffffffffffffffffffffffffffffffff8216610fa7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610895565b8060026000828254610fb99190611d5c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6109c93382611657565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610a41565b60055473ffffffffffffffffffffffffffffffffffffffff1633146110d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610895565b565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661181b565b60606000610a418361190e565b611113823383610e2b565b610ba58282611657565b6000610a418373ffffffffffffffffffffffffffffffffffffffff841661196a565b3373ffffffffffffffffffffffffffffffffffffffff8216036111be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610895565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600554604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b73ffffffffffffffffffffffffffffffffffffffff83166112d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661137a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661148b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff821661152e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902054818110156115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610e25565b73ffffffffffffffffffffffffffffffffffffffff82166116fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054818110156117b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610895565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6000818152600183016020526040812054801561190457600061183f600183611dce565b855490915060009061185390600190611dce565b90508181146118b857600086600001828154811061187357611873611de1565b906000526020600020015490508087600001848154811061189657611896611de1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118c9576118c9611e10565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610615565b6000915050610615565b60608160000180548060200260200160405190810160405280929190818152602001828054801561195e57602002820191906000526020600020905b81548152602001906001019080831161194a575b50505050509050919050565b60008181526001830160205260408120546119b157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610615565b506000610615565b6000602082840312156119cb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a4157600080fd5b6000815180845260005b81811015611a2157602081850181015186830182015201611a05565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610a4160208301846119fb565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a9657600080fd5b919050565b60008060408385031215611aae57600080fd5b611ab783611a72565b946020939093013593505050565b600080600060608486031215611ada57600080fd5b611ae384611a72565b9250611af160208501611a72565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080600060608486031215611b4557600080fd5b611b4e84611a72565b925060208401359150604084013567ffffffffffffffff80821115611b7257600080fd5b818601915086601f830112611b8657600080fd5b813581811115611b9857611b98611b01565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611bde57611bde611b01565b81604052828152896020848701011115611bf757600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b600060208284031215611c2b57600080fd5b5035919050565b600060208284031215611c4457600080fd5b610a4182611a72565b6020808252825182820181905260009190848201906040850190845b81811015611c9b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611c69565b50909695505050505050565b60008060408385031215611cba57600080fd5b611cc383611a72565b9150611cd160208401611a72565b90509250929050565b600181811c90821680611cee57607f821691505b602082108103611d27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561061557610615611d2d565b828152604060208201526000611d8860408301846119fb565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000611dc560608301846119fb565b95945050505050565b8181038181111561061557610615611d2d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a' as const -// generate:end diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts index 63d02600..0cec4faa 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts @@ -8,25 +8,48 @@ import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../err import type { EVMChain } from '../../../../evm/index.ts' import { ChainFamily } from '../../../../networks.ts' import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' -import { BURN_MINT_ERC677_BYTECODE } from '../bytecode.ts' +import crossChainBytecode from '../../artifacts/bytecode/V2_0_0/cross-chain-token.ts' const SENDER = '0x' + '11'.repeat(20) +const OWNER = '0x' + '11'.repeat(20) +const CCIP_ADMIN = '0x' + '22'.repeat(20) +const ROLE_ADMIN = '0x' + '33'.repeat(20) +const PREMINT_RECIPIENT = '0x' + '44'.repeat(20) const DEPLOYED = '0x' + '77'.repeat(20) const HASH = '0x' + 'ab'.repeat(32) -// Golden vector: pinned constructor-arg encoding for the fixed inputs below. Independent of -// the SDK encoder — guards the init-code (bytecode + BurnMintERC677 constructor) against drift. -const INPUTS = { name: 'CCIP Test Token', symbol: 'CCIPT', decimals: 18, maxSupply: 0n } -const EXPECTED_CTOR_ARGS = - '0000000000000000000000000000000000000000000000000000000000000080' + - '00000000000000000000000000000000000000000000000000000000000000c0' + - '0000000000000000000000000000000000000000000000000000000000000012' + +// Golden vector: a pinned constructor-arg encoding for the fixed inputs below. Independent of +// the SDK encoder — it guards CrossChainToken's init-code (bytecode + constructor) against drift. + +// CrossChainToken ctor: ((name, symbol, maxSupply, preMint, preMintRecipient, decimals, +// ccipAdmin), burnMintRoleAdmin, owner). +const INPUTS = { + name: 'CCIP Test Token', + symbol: 'CCIPT', + decimals: 18, + maxSupply: 0n, + preMint: 0n, + preMintRecipient: PREMINT_RECIPIENT, + ccipAdmin: CCIP_ADMIN, + burnMintRoleAdmin: ROLE_ADMIN, + owner: OWNER, +} +const CTOR_ARGS = + '0000000000000000000000000000000000000000000000000000000000000060' + + '0000000000000000000000003333333333333333333333333333333333333333' + + '0000000000000000000000001111111111111111111111111111111111111111' + + '00000000000000000000000000000000000000000000000000000000000000e0' + + '0000000000000000000000000000000000000000000000000000000000000120' + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000004444444444444444444444444444444444444444' + + '0000000000000000000000000000000000000000000000000000000000000012' + + '0000000000000000000000002222222222222222222222222222222222222222' + '000000000000000000000000000000000000000000000000000000000000000f' + '43434950205465737420546f6b656e0000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000005' + '4343495054000000000000000000000000000000000000000000000000000000' -const EXPECTED_DEPLOY_DATA = BURN_MINT_ERC677_BYTECODE + EXPECTED_CTOR_ARGS +const DEPLOY_DATA = crossChainBytecode + CTOR_ARGS /** Minimal EVMChain stub — deployToken's build path ignores it; execute uses only these. */ function stubChain(): EVMChain { @@ -59,117 +82,144 @@ function fakeSigner(opts: { contractAddress?: string | null; waitError?: Error } } } -describe('DeployToken (cct/evm token operation)', () => { - describe('generate', () => { - it('builds a deployment as init-code with no `to` (golden vector)', async () => { - const unsigned = await new DeployToken().generate(stubChain(), { ...INPUTS, sender: SENDER }) - - assert.equal(unsigned.family, ChainFamily.EVM) - assert.equal(unsigned.transactions.length, 1) - - const tx = unsigned.transactions[0]! - assert.equal(tx.to, undefined, 'deployment tx has no `to`') - assert.equal(tx.from, SENDER) - assert.ok( - tx.data!.startsWith(BURN_MINT_ERC677_BYTECODE), - 'data starts with creation bytecode', - ) - assert.equal(tx.data, EXPECTED_DEPLOY_DATA) - }) +describe('DeployToken (cct/evm)', () => { + it('builds a deployment as init-code with no `to` (golden vector)', async () => { + const unsigned = await new DeployToken().generate(stubChain(), { ...INPUTS, sender: SENDER }) + + assert.equal(unsigned.family, ChainFamily.EVM) + assert.equal(unsigned.transactions.length, 1) + const tx = unsigned.transactions[0]! + assert.equal(tx.to, undefined, 'deployment tx has no `to`') + assert.equal(tx.from, SENDER) + assert.ok(tx.data!.startsWith(crossChainBytecode), 'data starts with creation bytecode') + assert.equal(tx.data, DEPLOY_DATA) + }) - it('omits `from` when no sender is given', async () => { - const unsigned = await new DeployToken().generate(stubChain(), INPUTS) - assert.equal(unsigned.transactions[0]!.from, undefined) - }) + it('omits `from` when no sender is given', async () => { + const unsigned = await new DeployToken().generate(stubChain(), INPUTS) + assert.equal(unsigned.transactions[0]!.from, undefined) + }) - it('rejects an empty name, tagged with the operation and param', async () => { - await assert.rejects( - () => new DeployToken().generate(stubChain(), { ...INPUTS, name: '' }), - (err: unknown) => - err instanceof CCTParamsInvalidError && - err.context.operation === 'deployToken' && - err.context.param === 'name', - ) - }) + it('defaults preMint to 0n when omitted', async () => { + const { preMint: _preMint, ...withoutPreMint } = INPUTS + const unsigned = await new DeployToken().generate(stubChain(), withoutPreMint) + assert.equal(unsigned.transactions[0]!.data, DEPLOY_DATA) + }) - it('rejects an empty symbol', async () => { - await assert.rejects( - () => new DeployToken().generate(stubChain(), { ...INPUTS, symbol: '' }), - (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'symbol', - ) + it('defaults preMintRecipient/ccipAdmin/burnMintRoleAdmin to owner when omitted', async () => { + const omitted = await new DeployToken().generate(stubChain(), { + name: 'CCIP Test Token', + symbol: 'CCIPT', + decimals: 18, + maxSupply: 0n, + owner: OWNER, }) - - it('rejects decimals outside 0–255', async () => { - await assert.rejects( - () => new DeployToken().generate(stubChain(), { ...INPUTS, decimals: 256 }), - (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'decimals', - ) + const explicit = await new DeployToken().generate(stubChain(), { + name: 'CCIP Test Token', + symbol: 'CCIPT', + decimals: 18, + maxSupply: 0n, + preMint: 0n, + preMintRecipient: OWNER, + ccipAdmin: OWNER, + burnMintRoleAdmin: OWNER, + owner: OWNER, }) + assert.equal(omitted.transactions[0]!.data, explicit.transactions[0]!.data) + }) - it('rejects a non-integer decimals', async () => { - await assert.rejects( - () => new DeployToken().generate(stubChain(), { ...INPUTS, decimals: 1.5 }), - (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'decimals', - ) - }) + it('rejects an empty name, tagged with the operation and param', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, name: '' }), + (err: unknown) => + err instanceof CCTParamsInvalidError && + err.context.operation === 'deployToken' && + err.context.param === 'name', + ) + }) - it('rejects a negative maxSupply', async () => { - await assert.rejects( - () => new DeployToken().generate(stubChain(), { ...INPUTS, maxSupply: -1n }), - (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'maxSupply', - ) - }) + it('rejects decimals outside 0–255', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, decimals: 256 }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'decimals', + ) + }) - it('rejects a maxSupply above uint256 max', async () => { - await assert.rejects( - () => new DeployToken().generate(stubChain(), { ...INPUTS, maxSupply: 2n ** 256n }), - (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'maxSupply', - ) - }) + it('rejects a maxSupply above uint256 max', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, maxSupply: 2n ** 256n }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'maxSupply', + ) }) - describe('execute', () => { - it('deploys and returns the tx hash and deployed address', async () => { - const result = await new DeployToken().execute(stubChain(), { - ...INPUTS, - wallet: fakeSigner({ contractAddress: DEPLOYED }), - }) - assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) - }) + it('rejects an invalid owner', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, owner: 'nope' }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'owner', + ) + }) - it('throws CCTTxFailedError when the receipt carries no contract address', async () => { - await assert.rejects( - () => - new DeployToken().execute(stubChain(), { - ...INPUTS, - wallet: fakeSigner({ contractAddress: null }), - }), - (err: unknown) => - err instanceof CCTTxFailedError && - err.context.operation === 'deployToken' && - !err.isTransient, - ) - }) + it('rejects an invalid ccipAdmin', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, ccipAdmin: 'nope' }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'ccipAdmin', + ) + }) - it('throws CCIPExecTxRevertedError when the deployment reverts on-chain', async () => { - await assert.rejects( - () => - new DeployToken().execute(stubChain(), { - ...INPUTS, - wallet: fakeSigner({ waitError: makeError('execution reverted', 'CALL_EXCEPTION') }), - }), - (err: unknown) => - err instanceof CCIPExecTxRevertedError && - err.context.operation === 'deployToken' && - err.context.txHash === HASH, - ) - }) + it('rejects preMint greater than a capped maxSupply', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, maxSupply: 10n, preMint: 11n }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'preMint', + ) + }) - it('rejects a non-signer wallet', async () => { - await assert.rejects( - () => new DeployToken().execute(stubChain(), { ...INPUTS, wallet: {} }), - (err: unknown) => err instanceof CCIPWalletInvalidError, - ) + it('rejects an invalid sender', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, sender: 'nope' }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'sender', + ) + }) + + it('deploys and returns the tx hash and deployed address', async () => { + const result = await new DeployToken().execute(stubChain(), { + ...INPUTS, + wallet: fakeSigner({ contractAddress: DEPLOYED }), }) + assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) + }) + + it('throws CCTTxFailedError when the receipt carries no contract address', async () => { + await assert.rejects( + () => + new DeployToken().execute(stubChain(), { + ...INPUTS, + wallet: fakeSigner({ contractAddress: null }), + }), + (err: unknown) => + err instanceof CCTTxFailedError && + err.context.operation === 'deployToken' && + !err.isTransient, + ) + }) + + it('throws CCIPExecTxRevertedError when the deployment reverts on-chain', async () => { + await assert.rejects( + () => + new DeployToken().execute(stubChain(), { + ...INPUTS, + wallet: fakeSigner({ waitError: makeError('execution reverted', 'CALL_EXCEPTION') }), + }), + (err: unknown) => + err instanceof CCIPExecTxRevertedError && + err.context.operation === 'deployToken' && + err.context.txHash === HASH, + ) + }) + + it('rejects a non-signer wallet', async () => { + await assert.rejects( + () => new DeployToken().execute(stubChain(), { ...INPUTS, wallet: {} }), + (err: unknown) => err instanceof CCIPWalletInvalidError, + ) }) }) diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts index 9c872235..4b1e0b53 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts @@ -1,47 +1,98 @@ /** - * deployToken — deploys a `BurnMintERC677Token` (v1.5.1) via raw init-code. - * The tx has no `to`; `execute` returns the deployed contract address. + * deployToken — deploys a `CrossChainToken` (v2.0.0) via raw init-code. The tx has no + * `to`; `execute` returns the deployed contract address. * * @packageDocumentation */ -import { interfaces } from '../../../../evm/const.ts' +import type { Interface } from 'ethers' + import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' -import { ChainFamily } from '../../../../networks.ts' -import { CCTTxFailedError } from '../../../errors.ts' -import { type DeployResult, type EVMExecuteParams, EVMOperation } from '../../operation.ts' +import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' +import { + type DeployResult, + type EVMExecuteParams, + EVMOperation, + deploymentTx, +} from '../../operation.ts' import { submit } from '../../submit.ts' -import { validateNonEmptyString, validateUint256, validateUint8 } from '../../validate.ts' -import { BURN_MINT_ERC677_BYTECODE } from '../bytecode.ts' +import { + validateAddress, + validateNonEmptyString, + validateUint256, + validateUint8, +} from '../../validate.ts' +import { TokenVersion, tokenArtifact } from '../version.ts' -/** Parameters for {@link DeployToken}. */ +/** Parameters for {@link DeployToken} — deploys `CrossChainToken` (v2.0.0). */ export interface DeployTokenParams { name: string symbol: string decimals: number /** Max supply cap; `0n` means unlimited. */ maxSupply: bigint + /** Amount minted at deploy; defaults to `0n`. Must be `<= maxSupply` when capped. */ + preMint?: bigint + /** Receives ownership; a valid address. */ + owner: string + /** Recipient of `preMint`; defaults to `owner`. */ + preMintRecipient?: string + /** CCIP admin (`getCCIPAdmin`); defaults to `owner`. */ + ccipAdmin?: string + /** Admin of the burn/mint roles; defaults to `owner`. */ + burnMintRoleAdmin?: string sender?: string } -/** Deploys a `BurnMintERC677Token`; `execute` resolves to `{ hash, address }`. */ +/** Encodes the `CrossChainToken` (v2.0.0) constructor args; admin/recipient default to `owner`. */ +function encodeCrossChainToken(iface: Interface, p: DeployTokenParams): string { + return iface.encodeDeploy([ + [ + p.name, + p.symbol, + p.maxSupply, + p.preMint ?? 0n, + p.preMintRecipient ?? p.owner, + p.decimals, + p.ccipAdmin ?? p.owner, + ], + p.burnMintRoleAdmin ?? p.owner, + p.owner, + ]) +} + +/** Deploys a `CrossChainToken`; `execute` resolves to `{ hash, address }`. */ export class DeployToken extends EVMOperation { readonly name = 'deployToken' /** Validates the constructor params before building init-code. */ - protected validate({ name, symbol, decimals, maxSupply }: DeployTokenParams): void { - validateNonEmptyString(this.name, 'name', name) - validateNonEmptyString(this.name, 'symbol', symbol) - validateUint8(this.name, 'decimals', decimals) - validateUint256(this.name, 'maxSupply', maxSupply) + protected validate(params: DeployTokenParams): void { + validateNonEmptyString(this.name, 'name', params.name) + validateNonEmptyString(this.name, 'symbol', params.symbol) + validateUint8(this.name, 'decimals', params.decimals) + validateUint256(this.name, 'maxSupply', params.maxSupply) + const preMint = params.preMint ?? 0n + validateUint256(this.name, 'preMint', preMint) + validateAddress(this.name, 'owner', params.owner) + if (params.maxSupply !== 0n && preMint > params.maxSupply) + throw new CCTParamsInvalidError( + this.name, + 'preMint', + `must be <= maxSupply (${params.maxSupply}), got ${preMint}`, + ) + if (params.preMintRecipient !== undefined) + validateAddress(this.name, 'preMintRecipient', params.preMintRecipient) + if (params.ccipAdmin !== undefined) validateAddress(this.name, 'ccipAdmin', params.ccipAdmin) + if (params.burnMintRoleAdmin !== undefined) + validateAddress(this.name, 'burnMintRoleAdmin', params.burnMintRoleAdmin) } /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ - protected buildUnsigned(_chain: EVMChain, p: DeployTokenParams): UnsignedEVMTx { - const args = interfaces.Token.encodeDeploy([p.name, p.symbol, p.decimals, p.maxSupply]) - const data = BURN_MINT_ERC677_BYTECODE + args.slice(2) - return { family: ChainFamily.EVM, transactions: [{ data }] } + protected buildUnsigned(_chain: EVMChain, params: DeployTokenParams): UnsignedEVMTx { + // hardcoded to deploy CrossChainToken 2.0.0 + const { iface, bytecode } = tokenArtifact(TokenVersion.V2_0_0) + return deploymentTx(bytecode, encodeCrossChainToken(iface, params)) } /** @@ -62,9 +113,6 @@ export class DeployToken extends EVMOperation { if (!receipt.contractAddress) throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { context: { txHash: response.hash }, - // override the default CCT_TX_FAILED hint to point tx has mined but receipt carried no address - recovery: - 'Deployment mined but the receipt carried no contract address; re-fetch it by tx hash or retry against a different RPC.', }) return { hash: response.hash, contractAddress: receipt.contractAddress } } diff --git a/ccip-sdk/src/cct/evm/token/version.ts b/ccip-sdk/src/cct/evm/token/version.ts new file mode 100644 index 00000000..ae164bb0 --- /dev/null +++ b/ccip-sdk/src/cct/evm/token/version.ts @@ -0,0 +1,74 @@ +/** + * EVM token version axis for CCT. {@link TokenVersion} + {@link TOKEN_ABIS} cover every + * known token contract so read/write ops can resolve the right interface; + * {@link TOKEN_ARTIFACTS} / {@link tokenArtifact} add creation bytecode. `2.0.0` is + * `CrossChainToken`; `1.5.1` / `1.6.2` are `FactoryBurnMintERC20`. Mirrors + * `token-pool/version.ts`. + * + * @packageDocumentation + */ + +import { type InterfaceAbi, Interface } from 'ethers' + +import { CCTContractVersionUnsupportedError } from '../../errors.ts' +import FACTORY_BURN_MINT_ERC20_V1_5_1_ABI from '../artifacts/abi/V1_5_1/factory-burn-mint-erc20.ts' +import FACTORY_BURN_MINT_ERC20_V1_6_2_ABI from '../artifacts/abi/V1_6_2/factory-burn-mint-erc20.ts' +import CROSS_CHAIN_TOKEN_V2_0_0_ABI from '../artifacts/abi/V2_0_0/cross-chain-token.ts' +import CROSS_CHAIN_TOKEN_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/cross-chain-token.ts' + +/** + * Known token versions, low to high. `2.0.0` is `CrossChainToken`; `1.5.1` / `1.6.2` + * are `FactoryBurnMintERC20`. + */ +export const TokenVersion = { + V1_5_1: '1.5.1', + V1_6_2: '1.6.2', + V2_0_0: '2.0.0', +} as const + +/** A known token version. */ +export type TokenVersion = (typeof TokenVersion)[keyof typeof TokenVersion] + +/** Contract ABI per {@link TokenVersion} — lets read/write ops resolve the right interface. */ +export const TOKEN_ABIS: Record = { + [TokenVersion.V1_5_1]: FACTORY_BURN_MINT_ERC20_V1_5_1_ABI, + [TokenVersion.V1_6_2]: FACTORY_BURN_MINT_ERC20_V1_6_2_ABI, + [TokenVersion.V2_0_0]: CROSS_CHAIN_TOKEN_V2_0_0_ABI, +} + +/** + * Returns the contract ABI for `version`. + * @throws {@link CCTContractVersionUnsupportedError} if `version` has no vendored ABI + */ +export function tokenAbi(version: TokenVersion): InterfaceAbi { + const abi = TOKEN_ABIS[version] + if (!abi) throw new CCTContractVersionUnsupportedError('token', version) + return abi +} + +/** A token deploy artifact: the cached constructor {@link Interface} and creation bytecode. */ +export interface TokenArtifact { + iface: Interface + bytecode: `0x${string}` +} + +/** + * Deploy artifacts (ctor {@link Interface} + creation bytecode) keyed by {@link TokenVersion}, + * built once. Only versions with vendored bytecode appear; read via {@link tokenArtifact}. + */ +export const TOKEN_ARTIFACTS: Partial> = { + [TokenVersion.V2_0_0]: { + iface: new Interface(CROSS_CHAIN_TOKEN_V2_0_0_ABI), + bytecode: CROSS_CHAIN_TOKEN_V2_0_0_BYTECODE, + }, +} + +/** + * Returns the cached deploy artifact for `version`. + * @throws {@link CCTContractVersionUnsupportedError} if `version` has no vendored deploy bytecode + */ +export function tokenArtifact(version: TokenVersion): TokenArtifact { + const artifact = TOKEN_ARTIFACTS[version] + if (!artifact) throw new CCTContractVersionUnsupportedError('token', version) + return artifact +} diff --git a/ccip-sdk/src/selectors.ts b/ccip-sdk/src/selectors.ts index 277f3c87..340db547 100644 --- a/ccip-sdk/src/selectors.ts +++ b/ccip-sdk/src/selectors.ts @@ -943,6 +943,12 @@ const SELECTORS: Selectors = { network_type: 'TESTNET', family: 'EVM', }, + '10323': { + selector: 9211758560309513668n, + name: 'mova-testnet', + network_type: 'TESTNET', + family: 'EVM', + }, '11124': { selector: 16235373811196386733n, name: 'abstract-testnet', @@ -1234,6 +1240,12 @@ const SELECTORS: Selectors = { deprecated: true, family: 'EVM', }, + '61900': { + selector: 3314641565992046393n, + name: 'mova-mainnet', + network_type: 'MAINNET', + family: 'EVM', + }, '68414': { selector: 12657445206920369324n, name: 'nexon-mainnet-henesys', From 0549852ef7f8605c60414f7716f388d1f52b0c20 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Mon, 20 Jul 2026 16:31:18 +0100 Subject: [PATCH 11/22] Address preMint specs --- ccip-cli/src/index.ts | 2 +- ccip-sdk/src/api/index.ts | 2 +- ccip-sdk/src/cct/evm/index.ts | 7 ++- .../evm/token/operations/deploy-token.test.ts | 53 +++++++++++++++---- .../cct/evm/token/operations/deploy-token.ts | 33 +++++++++--- 5 files changed, 78 insertions(+), 19 deletions(-) diff --git a/ccip-cli/src/index.ts b/ccip-cli/src/index.ts index e38ab5b5..f3c327ab 100755 --- a/ccip-cli/src/index.ts +++ b/ccip-cli/src/index.ts @@ -28,7 +28,7 @@ Error.stackTraceLimit = 50 // show more stack frames for better debugging // generate:nofail // `const VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -const VERSION = '1.10.2-f7eb21b' +const VERSION = '1.10.2-6530538' // generate:end const require = createRequire(import.meta.url) diff --git a/ccip-sdk/src/api/index.ts b/ccip-sdk/src/api/index.ts index 9e4d68b4..4ab3ea5c 100644 --- a/ccip-sdk/src/api/index.ts +++ b/ccip-sdk/src/api/index.ts @@ -62,7 +62,7 @@ export const DEFAULT_TIMEOUT_MS = 30000 /** SDK version string for telemetry header */ // generate:nofail // `export const SDK_VERSION = '${require('./package.json').version}-${require('child_process').execSync('git rev-parse --short HEAD').toString().trim()}'` -export const SDK_VERSION = '1.10.2-f7eb21b' +export const SDK_VERSION = '1.10.2-6530538' // generate:end /** SDK telemetry header name */ diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 3658f1f8..f0e2575a 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -124,6 +124,8 @@ export class EVMTokenManager extends TokenManager { * Builds an unsigned `CrossChainToken` (v2.0.0) deployment tx (for multisig / offline * signing). The deployed address is only known once mined, so it is NOT returned here — * use {@link deployToken} to deploy and receive `{ hash, contractAddress }`. + * @remarks Same post-deploy roles caveat as {@link deployToken} — the pool needs + * `grantMintAndBurnRoles` before it can bridge. * @throws {@link CCTParamsInvalidError} if any param is invalid * @example * ```typescript @@ -144,6 +146,9 @@ export class EVMTokenManager extends TokenManager { /** * Deploys a `CrossChainToken` (v2.0.0), signing + submitting with `opts.wallet`; resolves * to the tx hash and the newly deployed token address. + * @remarks Mint/burn are role-gated (`MINTER_ROLE`/`BURNER_ROLE`); the token grants neither + * to any pool at deploy. `preMint` mints initial supply to `preMintRecipient`, but before a + * pool can bridge, `burnMintRoleAdmin` must `grantMintAndBurnRoles(pool)`. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address @@ -167,5 +172,5 @@ export class EVMTokenManager extends TokenManager { export * from '../errors.ts' export type { SetPoolParams } from './token-admin-registry/operations/set-pool.ts' export type { DeployTokenParams } from './token/operations/deploy-token.ts' -export type { DeployResult } from './operation.ts' +export type { DeployResult, EVMExecuteParams } from './operation.ts' export type { TransactionResult } from '../operation.ts' diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts index 0cec4faa..e8980ca5 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict' import { describe, it } from 'node:test' -import { makeError } from 'ethers' +import { ZeroAddress, makeError } from 'ethers' import { DeployToken } from './deploy-token.ts' import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../errors/index.ts' @@ -28,7 +28,7 @@ const INPUTS = { symbol: 'CCIPT', decimals: 18, maxSupply: 0n, - preMint: 0n, + preMint: 1000n, preMintRecipient: PREMINT_RECIPIENT, ccipAdmin: CCIP_ADMIN, burnMintRoleAdmin: ROLE_ADMIN, @@ -41,7 +41,7 @@ const CTOR_ARGS = '00000000000000000000000000000000000000000000000000000000000000e0' + '0000000000000000000000000000000000000000000000000000000000000120' + '0000000000000000000000000000000000000000000000000000000000000000' + - '0000000000000000000000000000000000000000000000000000000000000000' + + '00000000000000000000000000000000000000000000000000000000000003e8' + '0000000000000000000000004444444444444444444444444444444444444444' + '0000000000000000000000000000000000000000000000000000000000000012' + '0000000000000000000000002222222222222222222222222222222222222222' + @@ -100,13 +100,18 @@ describe('DeployToken (cct/evm)', () => { assert.equal(unsigned.transactions[0]!.from, undefined) }) - it('defaults preMint to 0n when omitted', async () => { - const { preMint: _preMint, ...withoutPreMint } = INPUTS - const unsigned = await new DeployToken().generate(stubChain(), withoutPreMint) - assert.equal(unsigned.transactions[0]!.data, DEPLOY_DATA) + it('defaults preMint to 0 and a zero preMintRecipient when both omitted', async () => { + const { preMint: _preMint, preMintRecipient: _recipient, ...zeroPreMint } = INPUTS + const unsigned = await new DeployToken().generate(stubChain(), zeroPreMint) + // preMint 0 must pair with the zero address, else CrossChainToken's ctor reverts. + const expected = DEPLOY_DATA.replace( + '00000000000000000000000000000000000000000000000000000000000003e8', + '0'.repeat(64), + ).replace('0000000000000000000000004444444444444444444444444444444444444444', '0'.repeat(64)) + assert.equal(unsigned.transactions[0]!.data, expected) }) - it('defaults preMintRecipient/ccipAdmin/burnMintRoleAdmin to owner when omitted', async () => { + it('defaults ccipAdmin/burnMintRoleAdmin to owner when omitted', async () => { const omitted = await new DeployToken().generate(stubChain(), { name: 'CCIP Test Token', symbol: 'CCIPT', @@ -119,8 +124,6 @@ describe('DeployToken (cct/evm)', () => { symbol: 'CCIPT', decimals: 18, maxSupply: 0n, - preMint: 0n, - preMintRecipient: OWNER, ccipAdmin: OWNER, burnMintRoleAdmin: OWNER, owner: OWNER, @@ -128,6 +131,36 @@ describe('DeployToken (cct/evm)', () => { assert.equal(omitted.transactions[0]!.data, explicit.transactions[0]!.data) }) + it('rejects a missing preMintRecipient when preMint > 0', async () => { + const { preMintRecipient: _recipient, ...withoutRecipient } = INPUTS + await assert.rejects( + () => new DeployToken().generate(stubChain(), withoutRecipient), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'preMintRecipient', + ) + }) + + it('rejects a preMintRecipient when preMint is 0', async () => { + await assert.rejects( + () => + new DeployToken().generate(stubChain(), { + ...INPUTS, + preMint: 0n, + preMintRecipient: PREMINT_RECIPIENT, + }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'preMintRecipient', + ) + }) + + it('rejects a zero-address preMintRecipient when preMint > 0', async () => { + await assert.rejects( + () => new DeployToken().generate(stubChain(), { ...INPUTS, preMintRecipient: ZeroAddress }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'preMintRecipient', + ) + }) + it('rejects an empty name, tagged with the operation and param', async () => { await assert.rejects( () => new DeployToken().generate(stubChain(), { ...INPUTS, name: '' }), diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts index 4b1e0b53..dbb0fe5e 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts @@ -5,7 +5,7 @@ * @packageDocumentation */ -import type { Interface } from 'ethers' +import { type Interface, ZeroAddress } from 'ethers' import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' @@ -36,7 +36,7 @@ export interface DeployTokenParams { preMint?: bigint /** Receives ownership; a valid address. */ owner: string - /** Recipient of `preMint`; defaults to `owner`. */ + /** Recipient of `preMint`; required when `preMint > 0`, must be unset otherwise. */ preMintRecipient?: string /** CCIP admin (`getCCIPAdmin`); defaults to `owner`. */ ccipAdmin?: string @@ -45,7 +45,7 @@ export interface DeployTokenParams { sender?: string } -/** Encodes the `CrossChainToken` (v2.0.0) constructor args; admin/recipient default to `owner`. */ +/** Encodes the `CrossChainToken` (v2.0.0) constructor args; admins default to `owner`. */ function encodeCrossChainToken(iface: Interface, p: DeployTokenParams): string { return iface.encodeDeploy([ [ @@ -53,7 +53,8 @@ function encodeCrossChainToken(iface: Interface, p: DeployTokenParams): string { p.symbol, p.maxSupply, p.preMint ?? 0n, - p.preMintRecipient ?? p.owner, + // preMintRecipient is set iff preMint > 0 (enforced in validate); zero address otherwise. + p.preMintRecipient ?? ZeroAddress, p.decimals, p.ccipAdmin ?? p.owner, ], @@ -62,7 +63,7 @@ function encodeCrossChainToken(iface: Interface, p: DeployTokenParams): string { ]) } -/** Deploys a `CrossChainToken`; `execute` resolves to `{ hash, address }`. */ +/** Deploys a `CrossChainToken`; `execute` resolves to `{ hash, contractAddress }`. */ export class DeployToken extends EVMOperation { readonly name = 'deployToken' @@ -81,8 +82,28 @@ export class DeployToken extends EVMOperation { 'preMint', `must be <= maxSupply (${params.maxSupply}), got ${preMint}`, ) - if (params.preMintRecipient !== undefined) + // Mirror CrossChainToken's ctor: preMintRecipient is set (and non-zero) iff preMint > 0. + if (preMint > 0n) { + if (params.preMintRecipient === undefined) + throw new CCTParamsInvalidError( + this.name, + 'preMintRecipient', + 'must be set when preMint > 0', + ) validateAddress(this.name, 'preMintRecipient', params.preMintRecipient) + if (params.preMintRecipient === ZeroAddress) + throw new CCTParamsInvalidError( + this.name, + 'preMintRecipient', + 'must be non-zero when preMint > 0', + ) + } else if (params.preMintRecipient !== undefined) { + throw new CCTParamsInvalidError( + this.name, + 'preMintRecipient', + 'must be unset when preMint is 0', + ) + } if (params.ccipAdmin !== undefined) validateAddress(this.name, 'ccipAdmin', params.ccipAdmin) if (params.burnMintRoleAdmin !== undefined) validateAddress(this.name, 'burnMintRoleAdmin', params.burnMintRoleAdmin) From b886b8eeaaf84e6a2f5dafe922c2a8ddd06e53b8 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Wed, 22 Jul 2026 12:20:46 +0100 Subject: [PATCH 12/22] feat(cct-sdk): Add deploy evm token pool + type/version resolution --- ccip-sdk/src/cct/evm/index.test.ts | 32 ++- ccip-sdk/src/cct/evm/index.ts | 57 +++- .../operations/set-pool.ts | 2 +- .../operations/deploy-token-pool.test.ts | 267 ++++++++++++++++++ .../operations/deploy-token-pool.ts | 164 +++++++++++ .../operations/transfer-ownership.ts | 31 +- .../src/cct/evm/token-pool/version.test.ts | 110 ++++++-- ccip-sdk/src/cct/evm/token-pool/version.ts | 122 +++++--- 8 files changed, 698 insertions(+), 87 deletions(-) create mode 100644 ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts create mode 100644 ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts diff --git a/ccip-sdk/src/cct/evm/index.test.ts b/ccip-sdk/src/cct/evm/index.test.ts index bcdf801a..4e42e604 100644 --- a/ccip-sdk/src/cct/evm/index.test.ts +++ b/ccip-sdk/src/cct/evm/index.test.ts @@ -7,7 +7,7 @@ import { EVMTokenManager } from './index.ts' import { CCIPWalletInvalidError } from '../../errors/index.ts' import type { EVMChain } from '../../evm/index.ts' import { ChainFamily } from '../../networks.ts' -import { CCTContractVersionUnsupportedError, CCTParamsInvalidError } from '../errors.ts' +import { CCTContractTypeInvalidError, CCTParamsInvalidError } from '../errors.ts' const TOKEN = '0x' + '11'.repeat(20) const POOL = '0x' + '22'.repeat(20) @@ -161,21 +161,39 @@ describe('EVMTokenManager (cct/evm)', () => { }) describe('transferOwnership', () => { - it('builds transferOwnership to the pool (floor-match across versions)', async () => { - const cct = EVMTokenManager.fromChain(stubChain({}, '1.6.1')) + it('probes the pool type/version, then builds transferOwnership to the pool', async () => { + const probed: string[] = [] + const cct = EVMTokenManager.fromChain( + stubChain({ + typeAndVersion: ((address: string) => { + probed.push(address) + return Promise.resolve(['BurnMintTokenPool', '1.5.1', 'BurnMintTokenPool 1.5.1']) + }) as unknown as EVMChain['typeAndVersion'], + }), + ) const unsigned = await cct.generateUnsignedTransferOwnership({ poolAddress: POOL, newOwner: TOKEN, }) + assert.deepEqual(probed, [POOL]) // resolved the pool's type/version from its own address assert.equal(unsigned.transactions[0]!.to, POOL) assert.equal(unsigned.transactions[0]!.data, EXPECTED_TRANSFER) }) - it('throws for an unsupported pool version', async () => { - const cct = EVMTokenManager.fromChain(stubChain({}, '1.6.0')) + it('surfaces an unsupported pool type reported by the probe', async () => { + const cct = EVMTokenManager.fromChain( + stubChain({ + typeAndVersion: (() => + Promise.resolve([ + 'NotATokenPool', + '1.5.1', + 'NotATokenPool 1.5.1', + ])) as unknown as EVMChain['typeAndVersion'], + }), + ) await assert.rejects( - () => cct.generateUnsignedTransferOwnership({ poolAddress: POOL, newOwner: TOKEN }), - CCTContractVersionUnsupportedError, + cct.generateUnsignedTransferOwnership({ poolAddress: POOL, newOwner: TOKEN }), + (err: unknown) => err instanceof CCTContractTypeInvalidError, ) }) }) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index f0e2575a..b7a38c97 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -17,6 +17,10 @@ import { TokenManager } from '../token-manager.ts' import type { DeployResult, EVMExecuteParams } from './operation.ts' import { type DeployTokenParams, DeployToken } from './token/operations/deploy-token.ts' import { type SetPoolParams, SetPool } from './token-admin-registry/operations/set-pool.ts' +import { + type DeployTokenPoolParams, + DeployTokenPool, +} from './token-pool/operations/deploy-token-pool.ts' import { type TransferOwnershipParams, TransferOwnership, @@ -28,6 +32,7 @@ export class EVMTokenManager extends TokenManager { readonly #setPool = new SetPool() readonly #transferOwnership = new TransferOwnership() readonly #deployToken = new DeployToken() + readonly #deployTokenPool = new DeployTokenPool() /** Wraps an {@link EVMChain}; prefer the static factory methods. */ constructor(chain: EVMChain) { @@ -100,9 +105,8 @@ export class EVMTokenManager extends TokenManager { /** * Builds an unsigned pool `transferOwnership` tx (for multisig / offline signing). + * `transferOwnership` is version/type-independent, so no on-chain pool probe is performed. * @throws {@link CCTParamsInvalidError} if any param is invalid - * @throws {@link CCTContractTypeInvalidError} if the pool is not a recognised pool type - * @throws {@link CCTContractVersionUnsupportedError} if the pool version is unsupported */ generateUnsignedTransferOwnership(opts: TransferOwnershipParams): Promise { return this.#transferOwnership.generate(this.chain, opts) @@ -112,14 +116,58 @@ export class EVMTokenManager extends TokenManager { * Proposes a new pool owner (two-step), signing + submitting with `opts.wallet`. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid - * @throws {@link CCTContractTypeInvalidError} if the pool is not a recognised pool type - * @throws {@link CCTContractVersionUnsupportedError} if the pool version is unsupported * @throws {@link CCTTxFailedError} if the tx reverts or fails */ transferOwnership(opts: EVMExecuteParams): Promise { return this.#transferOwnership.execute(this.chain, opts) } + /** + * Builds an unsigned pool deployment tx (for multisig / offline signing). `type` selects + * the pool contract — a `DeployableTokenPoolType` (`BurnMintTokenPool`, `BurnFromMintTokenPool`, + * `BurnWithFromMintTokenPool`, or `LockReleaseTokenPool`; all v2.0.0). The deployed address is + * only known once mined, so it is NOT returned here — use {@link deployTokenPool} to receive + * `{ hash, contractAddress }`. + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @example + * ```typescript + * const unsigned = await cct.generateUnsignedDeployTokenPool({ + * type: 'BurnMintTokenPool', // or BurnFromMint / BurnWithFromMint / LockRelease + * token: '0xToken...', + * localTokenDecimals: 18, + * rmnProxy: '0xRmnProxy...', + * router: '0xRouter...', + * sender: '0xDeployer...', + * }) + * ``` + */ + generateUnsignedDeployTokenPool(opts: DeployTokenPoolParams): Promise { + return this.#deployTokenPool.generate(this.chain, opts) + } + + /** + * Deploys a token pool, signing + submitting with `opts.wallet`; resolves to the tx hash + * and the newly deployed pool address. `type` selects the pool contract (a + * `DeployableTokenPoolType`, v2.0.0). + * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address + * @example + * ```typescript + * const { hash, contractAddress } = await cct.deployTokenPool({ + * type: 'LockReleaseTokenPool', + * token: '0xToken...', + * localTokenDecimals: 18, + * rmnProxy: '0xRmnProxy...', + * router: '0xRouter...', + * wallet, + * }) + * ``` + */ + deployTokenPool(opts: EVMExecuteParams): Promise { + return this.#deployTokenPool.execute(this.chain, opts) + } + /** * Builds an unsigned `CrossChainToken` (v2.0.0) deployment tx (for multisig / offline * signing). The deployed address is only known once mined, so it is NOT returned here — @@ -172,5 +220,6 @@ export class EVMTokenManager extends TokenManager { export * from '../errors.ts' export type { SetPoolParams } from './token-admin-registry/operations/set-pool.ts' export type { DeployTokenParams } from './token/operations/deploy-token.ts' +export type { DeployTokenPoolParams } from './token-pool/operations/deploy-token-pool.ts' export type { DeployResult, EVMExecuteParams } from './operation.ts' export type { TransactionResult } from '../operation.ts' diff --git a/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts b/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts index 4643d16c..a31f5736 100644 --- a/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts +++ b/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts @@ -15,7 +15,7 @@ import { validateAddress } from '../../validate.ts' /** Parameters for `setPool`. Zero `poolAddress` delists the token. */ export type SetPoolParams = { tokenAddress: string - /** A zero/empty `poolAddress` delists the token from the registry. */ + /** The zero address as `poolAddress` delists the token from the registry. */ poolAddress: string /** * Contract to resolve the TokenAdminRegistry from. Pass the registry itself for a diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts new file mode 100644 index 00000000..5b085f3f --- /dev/null +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts @@ -0,0 +1,267 @@ +import assert from 'node:assert/strict' +import { describe, it } from 'node:test' + +import { makeError } from 'ethers' + +import { type DeployTokenPoolParams, DeployTokenPool } from './deploy-token-pool.ts' +import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../errors/index.ts' +import type { EVMChain } from '../../../../evm/index.ts' +import { ChainFamily } from '../../../../networks.ts' +import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' +import BURN_FROM_MINT_V2_0_0 from '../../artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts' +import BURN_MINT_V2_0_0 from '../../artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts' +import BURN_WITH_FROM_MINT_V2_0_0 from '../../artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts' +import LOCK_RELEASE_V2_0_0 from '../../artifacts/bytecode/V2_0_0/lock-release-token-pool.ts' + +const SENDER = '0x' + '11'.repeat(20) +const TOKEN = '0x' + '22'.repeat(20) +const RMN_PROXY = '0x' + '33'.repeat(20) +const ROUTER = '0x' + '44'.repeat(20) +const HOOKS = '0x' + '55'.repeat(20) +const LOCK_BOX = '0x' + '66'.repeat(20) +const DEPLOYED = '0x' + '77'.repeat(20) +const HASH = '0x' + 'ab'.repeat(32) + +const COMMON = { token: TOKEN, localTokenDecimals: 18, rmnProxy: RMN_PROXY, router: ROUTER } + +// Word encodings (32-byte, hex) reused across the golden vectors below. +const W_TOKEN = '0000000000000000000000002222222222222222222222222222222222222222' +const W_DECIMALS = '0000000000000000000000000000000000000000000000000000000000000012' +const W_RMN = '0000000000000000000000003333333333333333333333333333333333333333' +const W_ROUTER = '0000000000000000000000004444444444444444444444444444444444444444' +const W_HOOKS = '0000000000000000000000005555555555555555555555555555555555555555' +const W_LOCKBOX = '0000000000000000000000006666666666666666666666666666666666666666' + +// Golden vectors: pinned 2.0.0 constructor-arg encodings for the fixed inputs above. Independent +// of the SDK encoder — they guard each pool's init-code against drift. The burn-* variants share +// the `BurnMint` constructor (token, decimals, advancedPoolHooks, rmnProxy, router); LockRelease +// adds `lockBox`. +const BURN_MINT_ARGS = W_TOKEN + W_DECIMALS + W_HOOKS + W_RMN + W_ROUTER +const LOCK_RELEASE_ARGS = W_TOKEN + W_DECIMALS + W_HOOKS + W_RMN + W_ROUTER + W_LOCKBOX + +const CASES: { + label: string + params: DeployTokenPoolParams + bytecode: string + ctorArgs: string +}[] = [ + { + label: 'BurnMintTokenPool', + params: { ...COMMON, type: 'BurnMintTokenPool', advancedPoolHooks: HOOKS }, + bytecode: BURN_MINT_V2_0_0, + ctorArgs: BURN_MINT_ARGS, + }, + { + label: 'BurnFromMintTokenPool', + params: { ...COMMON, type: 'BurnFromMintTokenPool', advancedPoolHooks: HOOKS }, + bytecode: BURN_FROM_MINT_V2_0_0, + ctorArgs: BURN_MINT_ARGS, + }, + { + label: 'BurnWithFromMintTokenPool', + params: { ...COMMON, type: 'BurnWithFromMintTokenPool', advancedPoolHooks: HOOKS }, + bytecode: BURN_WITH_FROM_MINT_V2_0_0, + ctorArgs: BURN_MINT_ARGS, + }, + { + label: 'LockReleaseTokenPool', + params: { + ...COMMON, + type: 'LockReleaseTokenPool', + advancedPoolHooks: HOOKS, + lockBox: LOCK_BOX, + }, + bytecode: LOCK_RELEASE_V2_0_0, + ctorArgs: LOCK_RELEASE_ARGS, + }, +] + +/** Minimal EVMChain stub — deployTokenPool's build path ignores it; execute uses only these. */ +function stubChain(): EVMChain { + return { + provider: {} as never, + logger: { debug() {}, info() {}, warn() {}, error() {} }, + nextNonce: async () => 0, + rollbackNonce: () => {}, + } as unknown as EVMChain +} + +/** Fake ethers Signer whose deployment receipt carries `contractAddress`. */ +function fakeSigner(opts: { contractAddress?: string | null; waitError?: Error }) { + return { + signTransaction: () => Promise.resolve('0x'), + getAddress: () => Promise.resolve(SENDER), + populateTransaction: (tx: unknown) => Promise.resolve({ ...(tx as object) }), + sendTransaction: () => + Promise.resolve({ + hash: HASH, + wait: () => + opts.waitError + ? Promise.reject(opts.waitError) + : Promise.resolve({ + status: 1, + contractAddress: + opts.contractAddress === undefined ? DEPLOYED : opts.contractAddress, + }), + }), + } +} + +describe('DeployTokenPool (cct/evm token-pool operation)', () => { + describe('generate (golden vectors per deployable type)', () => { + for (const { label, params, bytecode, ctorArgs } of CASES) { + it(`builds ${label} as init-code with no \`to\``, async () => { + const unsigned = await new DeployTokenPool().generate(stubChain(), { + ...params, + sender: SENDER, + }) + + assert.equal(unsigned.family, ChainFamily.EVM) + assert.equal(unsigned.transactions.length, 1) + const tx = unsigned.transactions[0]! + assert.equal(tx.to, undefined, 'deployment tx has no `to`') + assert.equal(tx.from, SENDER) + assert.ok(tx.data!.startsWith(bytecode), 'data starts with creation bytecode') + assert.equal(tx.data, bytecode + ctorArgs) + }) + } + + it('defaults advancedPoolHooks to the zero address when omitted', async () => { + const unsigned = await new DeployTokenPool().generate(stubChain(), { + ...COMMON, + type: 'BurnMintTokenPool', + }) + const zeroHooks = W_TOKEN + W_DECIMALS + '0'.repeat(64) + W_RMN + W_ROUTER + assert.equal(unsigned.transactions[0]!.data, BURN_MINT_V2_0_0 + zeroHooks) + }) + + it('defaults lockBox to the zero address when omitted (LockRelease)', async () => { + const unsigned = await new DeployTokenPool().generate(stubChain(), { + ...COMMON, + type: 'LockReleaseTokenPool', + advancedPoolHooks: HOOKS, + }) + const zeroLockBox = W_TOKEN + W_DECIMALS + W_HOOKS + W_RMN + W_ROUTER + '0'.repeat(64) + assert.equal(unsigned.transactions[0]!.data, LOCK_RELEASE_V2_0_0 + zeroLockBox) + }) + + it('omits `from` when no sender is given', async () => { + const unsigned = await new DeployTokenPool().generate(stubChain(), { + ...COMMON, + type: 'BurnMintTokenPool', + advancedPoolHooks: HOOKS, + }) + assert.equal(unsigned.transactions[0]!.from, undefined) + }) + }) + + describe('validation', () => { + const base: DeployTokenPoolParams = { + ...COMMON, + type: 'BurnMintTokenPool', + advancedPoolHooks: HOOKS, + } + + it('rejects an invalid token address', async () => { + await assert.rejects( + () => new DeployTokenPool().generate(stubChain(), { ...base, token: 'nope' }), + (err: unknown) => + err instanceof CCTParamsInvalidError && + err.context.operation === 'deployTokenPool' && + err.context.param === 'token', + ) + }) + + it('rejects an invalid router address', async () => { + await assert.rejects( + () => new DeployTokenPool().generate(stubChain(), { ...base, router: 'nope' }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'router', + ) + }) + + it('rejects decimals outside 0–255', async () => { + await assert.rejects( + () => new DeployTokenPool().generate(stubChain(), { ...base, localTokenDecimals: 256 }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'localTokenDecimals', + ) + }) + + it('rejects an invalid advancedPoolHooks address', async () => { + await assert.rejects( + () => new DeployTokenPool().generate(stubChain(), { ...base, advancedPoolHooks: 'nope' }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'advancedPoolHooks', + ) + }) + + it('rejects an invalid sender', async () => { + await assert.rejects( + () => new DeployTokenPool().generate(stubChain(), { ...base, sender: 'nope' }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'sender', + ) + }) + + it('rejects a non-deployable pool type', async () => { + await assert.rejects( + () => + new DeployTokenPool().generate(stubChain(), { + ...COMMON, + type: 'BurnToAddressTokenPool', + } as unknown as DeployTokenPoolParams), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'type', + ) + }) + // `lockBox` on a burn pool is a compile-time error (the DeployTokenPoolParams union), so + // there's no runtime case to test. + }) + + describe('execute', () => { + const params: DeployTokenPoolParams = { + ...COMMON, + type: 'BurnMintTokenPool', + advancedPoolHooks: HOOKS, + } + + it('deploys and returns the tx hash and deployed address', async () => { + const result = await new DeployTokenPool().execute(stubChain(), { + ...params, + wallet: fakeSigner({ contractAddress: DEPLOYED }), + }) + assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) + }) + + it('throws CCTTxFailedError when the receipt carries no contract address', async () => { + await assert.rejects( + () => + new DeployTokenPool().execute(stubChain(), { + ...params, + wallet: fakeSigner({ contractAddress: null }), + }), + (err: unknown) => + err instanceof CCTTxFailedError && + err.context.operation === 'deployTokenPool' && + !err.isTransient, + ) + }) + + it('throws CCIPExecTxRevertedError when the deployment reverts on-chain', async () => { + await assert.rejects( + () => + new DeployTokenPool().execute(stubChain(), { + ...params, + wallet: fakeSigner({ waitError: makeError('execution reverted', 'CALL_EXCEPTION') }), + }), + (err: unknown) => + err instanceof CCIPExecTxRevertedError && err.context.operation === 'deployTokenPool', + ) + }) + + it('rejects a non-signer wallet', async () => { + await assert.rejects( + () => new DeployTokenPool().execute(stubChain(), { ...params, wallet: {} }), + (err: unknown) => err instanceof CCIPWalletInvalidError, + ) + }) + }) +}) diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts new file mode 100644 index 00000000..eebcc30f --- /dev/null +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts @@ -0,0 +1,164 @@ +/** + * deployTokenPool — deploys a token pool (`type` selects the contract) via raw init-code at + * v2.0.0. The tx has no `to`; `execute` returns the deployed pool address. Mirrors + * `token/operations/deploy-token.ts`. + * + * @packageDocumentation + */ + +import { type Interface, ZeroAddress } from 'ethers' + +import type { EVMChain } from '../../../../evm/index.ts' +import type { UnsignedEVMTx } from '../../../../evm/types.ts' +import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' +import BURN_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts' +import BURN_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts' +import BURN_WITH_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts' +import LOCK_RELEASE_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/lock-release-token-pool.ts' +import { + type DeployResult, + type EVMExecuteParams, + EVMOperation, + deploymentTx, +} from '../../operation.ts' +import { submit } from '../../submit.ts' +import { validateAddress, validateUint8 } from '../../validate.ts' +import { + type TokenPoolFamily, + type TokenPoolType, + TokenPoolVersion, + getTokenPoolFamily, + getTokenPoolInterface, +} from '../version.ts' + +/** + * Creation bytecode per deployable pool type (2.0.0 only — pre-2.0.0 bytecode is not vendored). + * The keys define the deployable set ({@link DeployableTokenPoolType} derives from them). The + * burn-* variants share the `BurnMint` constructor ABI but are distinct contracts with distinct + * bytecode. + */ +const TOKEN_POOL_BYTECODE: Partial> = { + BurnMintTokenPool: BURN_MINT_TOKEN_POOL_V2_0_0_BYTECODE, + BurnFromMintTokenPool: BURN_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, + BurnWithFromMintTokenPool: BURN_WITH_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, + LockReleaseTokenPool: LOCK_RELEASE_TOKEN_POOL_V2_0_0_BYTECODE, +} + +/** A pool contract type that can be deployed (has vendored 2.0.0 creation bytecode). */ +export type DeployableTokenPoolType = keyof typeof TOKEN_POOL_BYTECODE + +/** Fields shared by every deployable token pool. */ +interface DeployTokenPoolBase { + /** Address of the token the pool manages. */ + token: string + /** The token's `decimals` (uint8). */ + localTokenDecimals: number + /** RMN proxy address. */ + rmnProxy: string + /** CCIP router address. */ + router: string + /** Advanced pool hooks; defaults to the zero address. */ + advancedPoolHooks?: string + /** Deployer address; sets `tx.from` for offline / multisig signing. */ + sender?: string +} + +/** Params for a burn-* mint pool — the burn family shares one constructor shape. */ +export interface DeployBurnMintTokenPoolParams extends DeployTokenPoolBase { + type: Exclude +} + +/** Params for a `LockReleaseTokenPool` — the burn constructor plus `lockBox`. */ +export interface DeployLockReleaseTokenPoolParams extends DeployTokenPoolBase { + type: 'LockReleaseTokenPool' + /** Lock-box address; defaults to the zero address. */ + lockBox?: string +} + +/** + * Parameters for {@link DeployTokenPool}, discriminated on `type`: the burn-* variants share one + * constructor; `LockReleaseTokenPool` additionally accepts `lockBox` (a compile-time guarantee). + */ +export type DeployTokenPoolParams = DeployBurnMintTokenPoolParams | DeployLockReleaseTokenPoolParams + +/** Encodes a v2.0.0 pool constructor into init-code args for a given ABI family. */ +type TokenPoolConstructorEncoder = (iface: Interface, p: DeployTokenPoolParams) => string + +/** Burn-* family constructor: `(token, localTokenDecimals, advancedPoolHooks, rmnProxy, router)`. */ +const encodeBurnMintTokenPool: TokenPoolConstructorEncoder = (iface, p) => + iface.encodeDeploy([ + p.token, + p.localTokenDecimals, + p.advancedPoolHooks ?? ZeroAddress, + p.rmnProxy, + p.router, + ]) + +/** LockRelease constructor: the burn-* args plus `lockBox` (only that variant carries it). */ +const encodeLockReleaseTokenPool: TokenPoolConstructorEncoder = (iface, p) => + iface.encodeDeploy([ + p.token, + p.localTokenDecimals, + p.advancedPoolHooks ?? ZeroAddress, + p.rmnProxy, + p.router, + p.type === 'LockReleaseTokenPool' ? (p.lockBox ?? ZeroAddress) : ZeroAddress, + ]) + +/** Deploys a token pool; `execute` resolves to `{ hash, contractAddress }`. */ +export class DeployTokenPool extends EVMOperation { + readonly name = 'deployTokenPool' + + /** Constructor encoder per ABI {@link TokenPoolFamily}; `type` narrows to its family. */ + private readonly encoders: Record = { + BurnMint: encodeBurnMintTokenPool, + LockRelease: encodeLockReleaseTokenPool, + } + + /** Validates the constructor params before building init-code. */ + protected validate(params: DeployTokenPoolParams): void { + if (!Object.hasOwn(TOKEN_POOL_BYTECODE, params.type)) + throw new CCTParamsInvalidError( + this.name, + 'type', + `unsupported pool type ${String(params.type)}`, + ) + validateAddress(this.name, 'token', params.token) + validateUint8(this.name, 'localTokenDecimals', params.localTokenDecimals) + validateAddress(this.name, 'rmnProxy', params.rmnProxy) + validateAddress(this.name, 'router', params.router) + if (params.advancedPoolHooks !== undefined) + validateAddress(this.name, 'advancedPoolHooks', params.advancedPoolHooks) + if (params.type === 'LockReleaseTokenPool' && params.lockBox !== undefined) + validateAddress(this.name, 'lockBox', params.lockBox) + } + + /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ + protected buildUnsigned(_chain: EVMChain, params: DeployTokenPoolParams): UnsignedEVMTx { + const iface = getTokenPoolInterface(params.type, TokenPoolVersion.V2_0_0) + const encode = this.encoders[getTokenPoolFamily(params.type)] + return deploymentTx(TOKEN_POOL_BYTECODE[params.type], encode(iface, params)) + } + + /** + * {@link generate}, then sign and submit; resolves to the tx hash and the newly deployed + * pool address (read from the mined receipt). + * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address + */ + override async execute( + chain: EVMChain, + params: EVMExecuteParams, + ): Promise { + const { response, receipt } = await submit( + chain, + params.wallet, + await this.generate(chain, params), + this.name, + ) + if (!receipt.contractAddress) + throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { + context: { txHash: response.hash }, + }) + return { hash: response.hash, contractAddress: receipt.contractAddress } + } +} diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts index db33d01c..7296b899 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts @@ -5,27 +5,33 @@ * @packageDocumentation */ -import { type InterfaceAbi, Interface } from 'ethers' +import type { Interface } from 'ethers' import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' import { ChainFamily } from '../../../../networks.ts' import { EVMOperation } from '../../operation.ts' import { validateAddress } from '../../validate.ts' -import { TokenPoolVersion, resolveEncoder, resolveTokenPool } from '../version.ts' +import { + TokenPoolVersion, + getTokenPoolInterface, + resolveEncoder, + resolveTokenPool, +} from '../version.ts' /** Parameters for {@link TransferOwnership}. */ export interface TransferOwnershipParams { poolAddress: string newOwner: string + /** Current pool owner; sets `tx.from` for offline / multisig signing. */ sender?: string } -/** Encodes `transferOwnership` calldata against the resolved pool ABI. */ -type Encoder = (abi: InterfaceAbi, params: TransferOwnershipParams) => UnsignedEVMTx +/** Encodes `transferOwnership` calldata against the resolved pool {@link Interface}. */ +type Encoder = (iface: Interface, params: TransferOwnershipParams) => UnsignedEVMTx -const encodeTransferOwnership: Encoder = (abi, { newOwner, poolAddress }) => { - const data = new Interface(abi).encodeFunctionData('transferOwnership', [newOwner]) +const encodeTransferOwnership: Encoder = (iface, { newOwner, poolAddress }) => { + const data = iface.encodeFunctionData('transferOwnership', [newOwner]) return { family: ChainFamily.EVM, transactions: [{ to: poolAddress, data }] } } @@ -47,12 +53,19 @@ export class TransferOwnership extends EVMOperation { validateAddress(this.name, 'newOwner', newOwner) } - /** Reads the pool's type-and-version, then floor-matches the encoder and its ABI. */ + /** + * Resolves the pool's on-chain type + version, then encodes `transferOwnership` against that + * ABI, floor-matching the encoder to the same version. The calldata is version-independent + * today (one encoder covers all); resolving keeps the interface and encoder in step if it + * diverges. + */ protected async buildUnsigned( chain: EVMChain, { poolAddress, newOwner }: TransferOwnershipParams, ): Promise { - const { version, abi } = await resolveTokenPool(chain, poolAddress) - return resolveEncoder(this.encoders, version, this.name)(abi, { poolAddress, newOwner }) + const { type, version } = await resolveTokenPool(chain, poolAddress) + const iface = getTokenPoolInterface(type, version) + const encode = resolveEncoder(this.encoders, version, this.name) + return encode(iface, { poolAddress, newOwner }) } } diff --git a/ccip-sdk/src/cct/evm/token-pool/version.test.ts b/ccip-sdk/src/cct/evm/token-pool/version.test.ts index 11382ba2..48ad8c85 100644 --- a/ccip-sdk/src/cct/evm/token-pool/version.test.ts +++ b/ccip-sdk/src/cct/evm/token-pool/version.test.ts @@ -1,15 +1,19 @@ import assert from 'node:assert/strict' import { describe, it } from 'node:test' +import { Interface } from 'ethers' + import { - TOKEN_POOL_ABIS, + TOKEN_POOL_FAMILIES, + TOKEN_POOL_INTERFACES, TOKEN_POOL_TYPES, TokenPoolVersion, + getTokenPoolFamily, + getTokenPoolInterface, isTokenPoolType, isTokenPoolVersion, parseTokenPoolVersion, resolveEncoder, - tokenPoolAbi, } from './version.ts' import { CCTContractTypeInvalidError, @@ -20,16 +24,38 @@ import { const ADDR = '0x' + '11'.repeat(20) describe('pool types', () => { - it('lists known EVM pool types', () => { - assert.deepEqual([...TOKEN_POOL_TYPES], ['BurnMintTokenPool', 'LockReleaseTokenPool']) + it('lists known EVM pool types (burn family + lock release)', () => { + assert.deepEqual( + [...TOKEN_POOL_TYPES].sort(), + [ + 'BurnFromMintTokenPool', + 'BurnMintTokenPool', + 'BurnMintWithLockReleaseFlagTokenPool', + 'BurnToAddressTokenPool', + 'BurnWithFromMintTokenPool', + 'LockReleaseTokenPool', + 'SiloedLockReleaseTokenPool', + ].sort(), + ) }) - it('isTokenPoolType narrows supported types and rejects others', () => { + it('isTokenPoolType accepts burn-family + lock-release, rejects others', () => { assert.equal(isTokenPoolType('BurnMintTokenPool'), true) + assert.equal(isTokenPoolType('BurnFromMintTokenPool'), true) + assert.equal(isTokenPoolType('BurnWithFromMintTokenPool'), true) assert.equal(isTokenPoolType('LockReleaseTokenPool'), true) assert.equal(isTokenPoolType('UpgradeableLockReleaseTokenPool'), false) + assert.equal(isTokenPoolType('CCTPThroughCCVTokenPool'), false) assert.equal(isTokenPoolType('TokenAdminRegistry'), false) }) + + it('maps burn-* variants to the BurnMint family, LockRelease to its own', () => { + assert.equal(getTokenPoolFamily('BurnFromMintTokenPool'), 'BurnMint') + assert.equal(getTokenPoolFamily('BurnWithFromMintTokenPool'), 'BurnMint') + assert.equal(getTokenPoolFamily('BurnToAddressTokenPool'), 'BurnMint') + assert.equal(getTokenPoolFamily('BurnMintWithLockReleaseFlagTokenPool'), 'BurnMint') + assert.equal(getTokenPoolFamily('LockReleaseTokenPool'), 'LockRelease') + }) }) describe('pool versions', () => { @@ -45,6 +71,8 @@ describe('pool versions', () => { it('isTokenPoolVersion narrows known versions and rejects others', () => { assert.equal(isTokenPoolVersion(TokenPoolVersion.V1_5_1), true) assert.equal(isTokenPoolVersion(TokenPoolVersion.V2_0_0), true) + // `1.6.0` is a real on-chain string for SiloedLockReleaseTokenPool (v1.6.0 tag), but its ABI + // isn't in the 2.0.0 dep, so it's deliberately deferred (rejected) — not "no such version". assert.equal(isTokenPoolVersion('1.6.0'), false) assert.equal(isTokenPoolVersion('garbage'), false) }) @@ -96,6 +124,17 @@ describe('parseTokenPoolVersion', () => { ) }) + it('narrows a burn-family variant to its exact type', () => { + assert.deepEqual( + parseTokenPoolVersion({ + address: ADDR, + contractType: 'BurnFromMintTokenPool', + version: '1.5.1', + }), + { type: 'BurnFromMintTokenPool', version: TokenPoolVersion.V1_5_1 }, + ) + }) + it('throws CCTContractVersionUnsupportedError for an unknown version', () => { assert.throws( () => @@ -109,38 +148,55 @@ describe('parseTokenPoolVersion', () => { }) }) -describe('TOKEN_POOL_ABIS', () => { - it('returns an array (ABI) for each supported version', () => { - assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_0])) - assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_1])) - assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V1_6_1])) - assert.ok(Array.isArray(TOKEN_POOL_ABIS[TokenPoolVersion.V2_0_0])) +describe('TOKEN_POOL_INTERFACES', () => { + it('provides a cached ethers Interface for each family and version', () => { + for (const family of TOKEN_POOL_FAMILIES) { + for (const version of Object.values(TokenPoolVersion)) { + assert.ok(TOKEN_POOL_INTERFACES[family][version] instanceof Interface) + } + } }) - it('returns distinct ABI objects for different version slots', () => { - assert.notDeepEqual( - TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_0], - TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_1], + it('resolves distinct Interfaces per family at the same version', () => { + assert.notEqual( + TOKEN_POOL_INTERFACES.BurnMint[TokenPoolVersion.V1_5_1], + TOKEN_POOL_INTERFACES.LockRelease[TokenPoolVersion.V1_5_1], ) }) -}) -describe('tokenPoolAbi', () => { - it('returns the exact ABI for the requested version', () => { - assert.equal( - tokenPoolAbi('BurnMintTokenPool', TokenPoolVersion.V1_5_0), - TOKEN_POOL_ABIS[TokenPoolVersion.V1_5_0], + it('uses the *_and_proxy variant at V1_5_0 (exposes getPreviousPool)', () => { + assert.ok( + TOKEN_POOL_INTERFACES.BurnMint[TokenPoolVersion.V1_5_0].hasFunction('getPreviousPool'), ) - assert.equal( - tokenPoolAbi('LockReleaseTokenPool', TokenPoolVersion.V2_0_0), - TOKEN_POOL_ABIS[TokenPoolVersion.V2_0_0], + assert.ok( + !TOKEN_POOL_INTERFACES.BurnMint[TokenPoolVersion.V1_5_1].hasFunction('getPreviousPool'), ) }) +}) - it('ignores type today: both types resolve to the same ABI per version', () => { +describe('getTokenPoolInterface', () => { + it('returns the cached family Interface for the type+version (same instance across calls)', () => { + const a = getTokenPoolInterface('BurnMintTokenPool', TokenPoolVersion.V1_5_1) + const b = getTokenPoolInterface('BurnMintTokenPool', TokenPoolVersion.V1_5_1) + assert.ok(a instanceof Interface) + assert.equal(a, b) + assert.equal(a, TOKEN_POOL_INTERFACES.BurnMint[TokenPoolVersion.V1_5_1]) + }) + + it('resolves all burn-* variants to the same BurnMint-family Interface', () => { + const burnMint = getTokenPoolInterface('BurnMintTokenPool', TokenPoolVersion.V1_5_1) + assert.equal(getTokenPoolInterface('BurnFromMintTokenPool', TokenPoolVersion.V1_5_1), burnMint) assert.equal( - tokenPoolAbi('BurnMintTokenPool', TokenPoolVersion.V1_6_1), - tokenPoolAbi('LockReleaseTokenPool', TokenPoolVersion.V1_6_1), + getTokenPoolInterface('BurnWithFromMintTokenPool', TokenPoolVersion.V1_5_1), + burnMint, + ) + assert.equal(getTokenPoolInterface('BurnToAddressTokenPool', TokenPoolVersion.V1_5_1), burnMint) + }) + + it('resolves LockRelease to a different Interface than the BurnMint family', () => { + assert.notEqual( + getTokenPoolInterface('BurnMintTokenPool', TokenPoolVersion.V1_6_1), + getTokenPoolInterface('LockReleaseTokenPool', TokenPoolVersion.V1_6_1), ) }) }) diff --git a/ccip-sdk/src/cct/evm/token-pool/version.ts b/ccip-sdk/src/cct/evm/token-pool/version.ts index 0415712c..9ac18255 100644 --- a/ccip-sdk/src/cct/evm/token-pool/version.ts +++ b/ccip-sdk/src/cct/evm/token-pool/version.ts @@ -1,37 +1,74 @@ /** - * EVM token-pool version axis for CCT: resolve on-chain pool metadata and ABI - * ({@link resolveTokenPool}), and floor-match encoders ({@link resolveEncoder}). + * EVM token-pool version axis for CCT: resolve an on-chain pool's type + version + * ({@link resolveTokenPool}), select its cached ABI ({@link getTokenPoolInterface}), and + * floor-match version-keyed encoders ({@link resolveEncoder}). * * @packageDocumentation */ -import type { InterfaceAbi } from 'ethers' +import { Interface } from 'ethers' -import LockReleaseTokenPool_1_5 from '../../../evm/abi/LockReleaseTokenPool_1_5.ts' -import LockReleaseTokenPool_1_5_1 from '../../../evm/abi/LockReleaseTokenPool_1_5_1.ts' -import LockReleaseTokenPool_1_6_1 from '../../../evm/abi/LockReleaseTokenPool_1_6_1.ts' -import TokenPool_2_0 from '../../../evm/abi/TokenPool_2_0.ts' import type { EVMChain } from '../../../evm/index.ts' import { CCTContractTypeInvalidError, CCTContractVersionUnsupportedError, CCTOperationUnsupportedError, } from '../../errors.ts' +import BURN_MINT_TOKEN_POOL_V1_5_0_ABI from '../artifacts/abi/V1_5_0/burn-mint-token-pool-and-proxy.ts' +import LOCK_RELEASE_TOKEN_POOL_V1_5_0_ABI from '../artifacts/abi/V1_5_0/lock-release-token-pool-and-proxy.ts' +import BURN_MINT_TOKEN_POOL_V1_5_1_ABI from '../artifacts/abi/V1_5_1/burn-mint-token-pool.ts' +import LOCK_RELEASE_TOKEN_POOL_V1_5_1_ABI from '../artifacts/abi/V1_5_1/lock-release-token-pool.ts' +import BURN_MINT_TOKEN_POOL_V1_6_1_ABI from '../artifacts/abi/V1_6_1/burn-mint-token-pool.ts' +import LOCK_RELEASE_TOKEN_POOL_V1_6_1_ABI from '../artifacts/abi/V1_6_1/lock-release-token-pool.ts' +import BURN_MINT_TOKEN_POOL_V2_0_0_ABI from '../artifacts/abi/V2_0_0/burn-mint-token-pool.ts' +import LOCK_RELEASE_TOKEN_POOL_V2_0_0_ABI from '../artifacts/abi/V2_0_0/lock-release-token-pool.ts' -/** Supported pool contract types; unsupported values fail in {@link parseTokenPoolVersion}. */ -export const TOKEN_POOL_TYPES = ['BurnMintTokenPool', 'LockReleaseTokenPool'] as const +/** + * ABI families for pool resolution. The burn-* variants are interface-compatible for CCT + * ops (identical constructor + `transferOwnership`, shared TokenPool surface), so they share + * the `BurnMint` ABI; `LockRelease` (with its liquidity functions) is distinct. + */ +export const TOKEN_POOL_FAMILIES = ['BurnMint', 'LockRelease'] as const + +/** An ABI family for pool resolution. */ +export type TokenPoolFamily = (typeof TOKEN_POOL_FAMILIES)[number] + +/** + * Supported on-chain `typeAndVersion` pool types. The burn-* variants are interface-compatible + * for CCT ops and share the `BurnMint` ABI (see {@link getTokenPoolFamily}); `LockReleaseTokenPool` + * is distinct. Unsupported values fail in {@link parseTokenPoolVersion}. + */ +export const TOKEN_POOL_TYPES = [ + 'BurnMintTokenPool', + 'BurnFromMintTokenPool', + 'BurnWithFromMintTokenPool', + 'BurnToAddressTokenPool', + 'BurnMintWithLockReleaseFlagTokenPool', + 'LockReleaseTokenPool', + 'SiloedLockReleaseTokenPool', +] as const /** A supported EVM token-pool contract type. */ export type TokenPoolType = (typeof TOKEN_POOL_TYPES)[number] /** Type guard for {@link TOKEN_POOL_TYPES}. */ export function isTokenPoolType(v: string): v is TokenPoolType { - return TOKEN_POOL_TYPES.some((known) => known === v) + return (TOKEN_POOL_TYPES as readonly string[]).includes(v) +} + +/** + * Classifies a supported pool type into its ABI {@link TokenPoolFamily} by name: every burn-* + * mint pool shares the `BurnMint` ABI (identical surface for CCT ops — including + * `BurnMintWithLockReleaseFlagTokenPool`, hence the anchored `^Burn`), while the non-burn pools + * (`LockReleaseTokenPool`, `SiloedLockReleaseTokenPool`) use the `LockRelease` ABI. + * {@link TOKEN_POOL_TYPES} is the gate, so only allowlisted, ABI-compatible names reach here. + */ +export function getTokenPoolFamily(type: TokenPoolType): TokenPoolFamily { + return /^Burn/.test(type) ? 'BurnMint' : 'LockRelease' } /** - * Known pool versions, low to high. Value order drives floor-match in - * {@link resolveEncoder}. + * Known pool versions, low to high. Value order drives floor-match in {@link resolveEncoder}. */ export const TokenPoolVersion = { V1_5_0: '1.5.0', @@ -64,46 +101,53 @@ export function parseTokenPoolVersion({ version: string }): { type: TokenPoolType; version: TokenPoolVersion } { if (!isTokenPoolType(contractType)) - throw new CCTContractTypeInvalidError( - address, - 'BurnMintTokenPool or LockReleaseTokenPool', - contractType, - ) + throw new CCTContractTypeInvalidError(address, TOKEN_POOL_TYPES.join(', '), contractType) if (!isTokenPoolVersion(version)) throw new CCTContractVersionUnsupportedError(contractType, version, { context: { address } }) return { type: contractType, version } } -/** Vendored pool ABIs keyed by {@link TokenPoolVersion}. - * TODO: split per type once BurnMint ABIs are imported from `@chainlink/contracts-ccip` */ -export const TOKEN_POOL_ABIS: Record = { - [TokenPoolVersion.V1_5_0]: LockReleaseTokenPool_1_5, - [TokenPoolVersion.V1_5_1]: LockReleaseTokenPool_1_5_1, - [TokenPoolVersion.V1_6_1]: LockReleaseTokenPool_1_6_1, - [TokenPoolVersion.V2_0_0]: TokenPool_2_0, +/** + * Resolves an on-chain pool's type + version from its `typeAndVersion`, narrowed to a known + * {@link TokenPoolType} and {@link TokenPoolVersion}. + * @throws {@link CCTContractTypeInvalidError} if the reported type is not a supported pool type + * @throws {@link CCTContractVersionUnsupportedError} if the reported version is not a known pool version + */ +export async function resolveTokenPool( + chain: EVMChain, + address: string, +): Promise<{ type: TokenPoolType; version: TokenPoolVersion }> { + const [contractType, version] = await chain.typeAndVersion(address) + return parseTokenPoolVersion({ address, contractType, version }) } /** - * Returns the pool ABI for `type` and `version`. `type` keeps call sites stable - * for a future per-type split; today only `version` selects the ABI. Never throws - * when `version` came from {@link parseTokenPoolVersion}. + * Cached pool {@link Interface}s per {@link TokenPoolFamily} and {@link TokenPoolVersion}, + * built once from the vendored `artifacts/` ABIs (no per-call `new Interface`). `V1_5_0` + * uses the `*_and_proxy` variants — the only form `@chainlink/contracts-ccip` ships at 1.5.0. */ -export function tokenPoolAbi(_type: TokenPoolType, version: TokenPoolVersion): InterfaceAbi { - return TOKEN_POOL_ABIS[version] +export const TOKEN_POOL_INTERFACES: Record> = { + BurnMint: { + [TokenPoolVersion.V1_5_0]: new Interface(BURN_MINT_TOKEN_POOL_V1_5_0_ABI), + [TokenPoolVersion.V1_5_1]: new Interface(BURN_MINT_TOKEN_POOL_V1_5_1_ABI), + [TokenPoolVersion.V1_6_1]: new Interface(BURN_MINT_TOKEN_POOL_V1_6_1_ABI), + [TokenPoolVersion.V2_0_0]: new Interface(BURN_MINT_TOKEN_POOL_V2_0_0_ABI), + }, + LockRelease: { + [TokenPoolVersion.V1_5_0]: new Interface(LOCK_RELEASE_TOKEN_POOL_V1_5_0_ABI), + [TokenPoolVersion.V1_5_1]: new Interface(LOCK_RELEASE_TOKEN_POOL_V1_5_1_ABI), + [TokenPoolVersion.V1_6_1]: new Interface(LOCK_RELEASE_TOKEN_POOL_V1_6_1_ABI), + [TokenPoolVersion.V2_0_0]: new Interface(LOCK_RELEASE_TOKEN_POOL_V2_0_0_ABI), + }, } /** - * Reads `chain.typeAndVersion(poolAddress)`, narrows the result, and attaches the - * pool ABI. Shared RPC boundary before versioned pool encoding. - * @throws the same errors as {@link parseTokenPoolVersion} + * Returns the cached pool {@link Interface} for `type` and `version`, selected by the + * type's {@link TokenPoolFamily}. Never throws when both came from + * {@link parseTokenPoolVersion}. */ -export async function resolveTokenPool( - chain: EVMChain, - poolAddress: string, -): Promise<{ type: TokenPoolType; version: TokenPoolVersion; abi: InterfaceAbi }> { - const [contractType, version] = await chain.typeAndVersion(poolAddress) - const pool = parseTokenPoolVersion({ address: poolAddress, contractType, version }) - return { ...pool, abi: tokenPoolAbi(pool.type, pool.version) } +export function getTokenPoolInterface(type: TokenPoolType, version: TokenPoolVersion): Interface { + return TOKEN_POOL_INTERFACES[getTokenPoolFamily(type)][version] } /** From 7bce7b543c1245ee9530db9aa4b7aea68d6024af Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Wed, 22 Jul 2026 12:27:31 +0100 Subject: [PATCH 13/22] add remarks ts doc comment --- ccip-sdk/src/cct/evm/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index b7a38c97..f4023524 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -128,6 +128,8 @@ export class EVMTokenManager extends TokenManager { * `BurnWithFromMintTokenPool`, or `LockReleaseTokenPool`; all v2.0.0). The deployed address is * only known once mined, so it is NOT returned here — use {@link deployTokenPool} to receive * `{ hash, contractAddress }`. + * @remarks Same post-deploy setup caveat as {@link deployTokenPool} — a fresh pool must be + * registered, role-granted, and lane-configured before it can bridge. * @throws {@link CCTParamsInvalidError} if any param is invalid * @example * ```typescript @@ -149,6 +151,9 @@ export class EVMTokenManager extends TokenManager { * Deploys a token pool, signing + submitting with `opts.wallet`; resolves to the tx hash * and the newly deployed pool address. `type` selects the pool contract (a * `DeployableTokenPoolType`, v2.0.0). + * @remarks Deploying the pool alone doesn't make it usable: register it with {@link setPool}, + * grant it the token's mint/burn roles (`grantMintAndBurnRoles`), and configure its remote + * pools + rate limits before it can bridge. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address From fbc053d9ecae495168c8ad6aa33b7b4a4f620e7b Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Thu, 23 Jul 2026 13:39:13 +0100 Subject: [PATCH 14/22] Address PR comments --- ccip-sdk/src/cct/evm/index.ts | 5 ++- .../operations/deploy-token-pool.test.ts | 38 +++++++++++++------ .../operations/deploy-token-pool.ts | 17 +++++---- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 352bfb9d..aae2e99e 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -104,8 +104,9 @@ export class EVMTokenManager extends TokenManager { } /** - * Builds an unsigned pool `transferOwnership` tx (for multisig / offline signing). - * `transferOwnership` is version/type-independent, so no on-chain pool probe is performed. + * Builds an unsigned pool `transferOwnership` tx (for multisig / offline signing). Probes the + * pool's on-chain `typeAndVersion` to resolve its interface + encoder; the `transferOwnership` + * calldata is stable across pool versions, so the resolved encoding is version/type-independent. * @throws {@link CCTParamsInvalidError} if any param is invalid */ generateUnsignedTransferOwnership(opts: TransferOwnershipParams): Promise { diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts index 5b085f3f..38a9f9bc 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict' import { describe, it } from 'node:test' -import { makeError } from 'ethers' +import { ZeroAddress, makeError } from 'ethers' import { type DeployTokenPoolParams, DeployTokenPool } from './deploy-token-pool.ts' import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../errors/index.ts' @@ -135,16 +135,6 @@ describe('DeployTokenPool (cct/evm token-pool operation)', () => { assert.equal(unsigned.transactions[0]!.data, BURN_MINT_V2_0_0 + zeroHooks) }) - it('defaults lockBox to the zero address when omitted (LockRelease)', async () => { - const unsigned = await new DeployTokenPool().generate(stubChain(), { - ...COMMON, - type: 'LockReleaseTokenPool', - advancedPoolHooks: HOOKS, - }) - const zeroLockBox = W_TOKEN + W_DECIMALS + W_HOOKS + W_RMN + W_ROUTER + '0'.repeat(64) - assert.equal(unsigned.transactions[0]!.data, LOCK_RELEASE_V2_0_0 + zeroLockBox) - }) - it('omits `from` when no sender is given', async () => { const unsigned = await new DeployTokenPool().generate(stubChain(), { ...COMMON, @@ -212,6 +202,32 @@ describe('DeployTokenPool (cct/evm token-pool operation)', () => { (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'type', ) }) + + it('rejects the zero address for a LockRelease lockBox', async () => { + await assert.rejects( + () => + new DeployTokenPool().generate(stubChain(), { + ...COMMON, + type: 'LockReleaseTokenPool', + advancedPoolHooks: HOOKS, + lockBox: ZeroAddress, + }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'lockBox', + ) + }) + + it('rejects an invalid lockBox address', async () => { + await assert.rejects( + () => + new DeployTokenPool().generate(stubChain(), { + ...COMMON, + type: 'LockReleaseTokenPool', + advancedPoolHooks: HOOKS, + lockBox: 'nope', + }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'lockBox', + ) + }) // `lockBox` on a burn pool is a compile-time error (the DeployTokenPoolParams union), so // there's no runtime case to test. }) diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts index eebcc30f..8e8e7b5a 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts @@ -37,12 +37,12 @@ import { * burn-* variants share the `BurnMint` constructor ABI but are distinct contracts with distinct * bytecode. */ -const TOKEN_POOL_BYTECODE: Partial> = { +const TOKEN_POOL_BYTECODE = { BurnMintTokenPool: BURN_MINT_TOKEN_POOL_V2_0_0_BYTECODE, BurnFromMintTokenPool: BURN_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, BurnWithFromMintTokenPool: BURN_WITH_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, LockReleaseTokenPool: LOCK_RELEASE_TOKEN_POOL_V2_0_0_BYTECODE, -} +} satisfies Partial> /** A pool contract type that can be deployed (has vendored 2.0.0 creation bytecode). */ export type DeployableTokenPoolType = keyof typeof TOKEN_POOL_BYTECODE @@ -71,13 +71,13 @@ export interface DeployBurnMintTokenPoolParams extends DeployTokenPoolBase { /** Params for a `LockReleaseTokenPool` — the burn constructor plus `lockBox`. */ export interface DeployLockReleaseTokenPoolParams extends DeployTokenPoolBase { type: 'LockReleaseTokenPool' - /** Lock-box address; defaults to the zero address. */ - lockBox?: string + /** Lock-box address; required and must be non-zero — the v2.0.0 constructor reverts on the zero address. */ + lockBox: string } /** * Parameters for {@link DeployTokenPool}, discriminated on `type`: the burn-* variants share one - * constructor; `LockReleaseTokenPool` additionally accepts `lockBox` (a compile-time guarantee). + * constructor; `LockReleaseTokenPool` additionally requires `lockBox` (a compile-time guarantee). */ export type DeployTokenPoolParams = DeployBurnMintTokenPoolParams | DeployLockReleaseTokenPoolParams @@ -102,7 +102,7 @@ const encodeLockReleaseTokenPool: TokenPoolConstructorEncoder = (iface, p) => p.advancedPoolHooks ?? ZeroAddress, p.rmnProxy, p.router, - p.type === 'LockReleaseTokenPool' ? (p.lockBox ?? ZeroAddress) : ZeroAddress, + p.type === 'LockReleaseTokenPool' ? p.lockBox : ZeroAddress, ]) /** Deploys a token pool; `execute` resolves to `{ hash, contractAddress }`. */ @@ -129,8 +129,11 @@ export class DeployTokenPool extends EVMOperation { validateAddress(this.name, 'router', params.router) if (params.advancedPoolHooks !== undefined) validateAddress(this.name, 'advancedPoolHooks', params.advancedPoolHooks) - if (params.type === 'LockReleaseTokenPool' && params.lockBox !== undefined) + if (params.type === 'LockReleaseTokenPool') { validateAddress(this.name, 'lockBox', params.lockBox) + if (params.lockBox === ZeroAddress) + throw new CCTParamsInvalidError(this.name, 'lockBox', 'must not be the zero address') + } } /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ From fa96c239b52c72e0e84356b1278c72bf0e4240dc Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Thu, 23 Jul 2026 14:19:07 +0100 Subject: [PATCH 15/22] add lockfile to fix ci issue --- package-lock.json | 94 +++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3dd06df8..8dad4ed7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -426,7 +426,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.55.1.tgz", "integrity": "sha512-GAqHl9zERhC3bbBfubwUu07G3UXO06gORvOcsiTBZB3et0s3auNUbHlYdYNp4VKa3sUZqH5AcD3OKzU/KDGXjQ==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.55.1", "@algolia/requester-browser-xhr": "5.55.1", @@ -659,7 +658,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -3262,7 +3260,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -3285,7 +3282,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -3395,7 +3391,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3817,7 +3812,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -5260,7 +5254,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.1.tgz", "integrity": "sha512-2jRVrtzjf8LClGTHQlwlwuD3wQXRx3WEoF7XUarJ8Ou+0onV+SLtejsyfY9JLpfUh9hPhXM4pbBGkyAY4Bi3HQ==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/core": "3.10.1", "@docusaurus/logger": "3.10.1", @@ -5530,7 +5523,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.10.1.tgz", "integrity": "sha512-0YtmIeoNo1fIw65LO8+/1dPgmDV86UmhMkow37gzjytuiCSQm9xob6PJy0L4kuQEMTLfUOGvkXvZr7GPrHquMA==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/mdx-loader": "3.10.1", "@docusaurus/module-type-aliases": "3.10.1", @@ -5677,7 +5669,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.10.1.tgz", "integrity": "sha512-3ojeJry9xBYdJO6qoyyzqeJFSJBVx2mXhyDzSdjwL2+URFQMf+h25gG38iswGImicK0ELjTd1EL2xzk8hf3QPw==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/logger": "3.10.1", "@docusaurus/types": "3.10.1", @@ -5723,7 +5714,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.10.1.tgz", "integrity": "sha512-cRv1X69jwaWv47waglllgZVWzeBFLhl53XT/XED/83BerVBTC5FTP8WTcVl8Z6sZOegDSwitu/wpCSPCDOT6lg==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/logger": "3.10.1", "@docusaurus/utils": "3.10.1", @@ -5857,6 +5847,27 @@ "entities": "^7.0.1" } }, + "node_modules/@emnapi/core": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", @@ -8460,7 +8471,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8898,7 +8908,6 @@ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", "license": "MIT", - "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -8946,7 +8955,6 @@ "resolved": "https://registry.npmjs.org/@metaplex-foundation/umi/-/umi-1.5.1.tgz", "integrity": "sha512-ONRv5a0kv+23AMlR8oyFBHnjVg3o3N8pUfFcV4gzbg6OgZf87zHsPWBfED3OTJqx267v1bEn6d6DABXNFq9Z3A==", "license": "MIT", - "peer": true, "dependencies": { "@metaplex-foundation/umi-options": "^1.5.1", "@metaplex-foundation/umi-public-keys": "^1.5.1", @@ -10723,7 +10731,6 @@ "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.98.4.tgz", "integrity": "sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.25.0", "@noble/curves": "^1.4.2", @@ -11022,7 +11029,6 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -11135,6 +11141,7 @@ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "license": "MIT", + "peer": true, "dependencies": { "defer-to-connect": "^2.0.0" }, @@ -11170,7 +11177,6 @@ "resolved": "https://registry.npmjs.org/@ton/core/-/core-0.63.1.tgz", "integrity": "sha512-hDWMjlKzc18W2E4OeV3hUP8ohRJNHPD4Wd1+AQJj8zshZyCRT0usrvnExgbNUTo/vntDqCGMzgYWbXxyaA+L4g==", "license": "MIT", - "peer": true, "peerDependencies": { "@ton/crypto": ">=3.2.0" } @@ -11254,6 +11260,7 @@ "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", "license": "MIT", + "peer": true, "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", @@ -11677,14 +11684,14 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -11721,7 +11728,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-26.0.1.tgz", "integrity": "sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~8.3.0" } @@ -11749,7 +11755,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -11759,7 +11764,6 @@ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -11801,6 +11805,7 @@ "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*" } @@ -12126,7 +12131,6 @@ "integrity": "sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.62.0", "@typescript-eslint/types": "8.62.0", @@ -12276,7 +12280,6 @@ "integrity": "sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.62.0", @@ -12864,7 +12867,6 @@ "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.4.tgz", "integrity": "sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/wevm" }, @@ -12908,7 +12910,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -13006,7 +13007,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13071,7 +13071,6 @@ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.55.1.tgz", "integrity": "sha512-FyaFnnsbVPtevQwqSj/SdxE3jAsSsY0BEH8IVLf9rXxEBdAhAmT6VKCVSMWoaPIHVN1Eufh/1w8q6k8URpIkWw==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/abtesting": "1.21.1", "@algolia/client-abtesting": "5.55.1", @@ -13861,7 +13860,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.38", "caniuse-lite": "^1.0.30001799", @@ -14020,6 +14018,7 @@ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.6.0" } @@ -14029,6 +14028,7 @@ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "license": "MIT", + "peer": true, "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -14047,6 +14047,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "license": "MIT", + "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -14518,6 +14519,7 @@ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "license": "MIT", + "peer": true, "dependencies": { "mimic-response": "^1.0.0" }, @@ -15106,7 +15108,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -15426,7 +15427,6 @@ "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.34.0.tgz", "integrity": "sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10" } @@ -15848,7 +15848,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -16909,7 +16908,6 @@ "integrity": "sha512-6lVbcqSodALYo+4ELD0heG6lFiFxnLMuLkiMi2qV8LMp54N8tE8FT1GMH+ev4Ti00nFjNze2+Su6DsV5OQW3Dg==", "dev": true, "license": "MIT", - "peer": true, "workspaces": [ "packages/*" ], @@ -16969,7 +16967,6 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -18697,7 +18694,6 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.14.2.tgz", "integrity": "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==", "license": "MIT", - "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -19378,6 +19374,7 @@ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", "license": "MIT", + "peer": true, "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" @@ -20758,6 +20755,7 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -23267,6 +23265,7 @@ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=4" } @@ -23739,6 +23738,7 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -24111,7 +24111,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -24284,6 +24283,7 @@ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -25122,7 +25122,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", @@ -26128,7 +26127,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -26788,7 +26786,6 @@ "integrity": "sha512-HWmu+K+zvHNpaMfSnYeqdqrDbR16cuIXaPx8WoHaviQkDJh1/0BNtOZmHVQI5jc3wXv0H1yXc9wjvFdXh+n3hQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -27293,7 +27290,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -27303,7 +27299,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -27340,7 +27335,6 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.80.0.tgz", "integrity": "sha512-4P+fk6oXsxY+6xSj7Euhc2sumQD8zQqCuVHoJwoyp9EchP+IUW9OESB7uHFJOKsIBQ4MQqYE84INJFqUCYNoOg==", "license": "MIT", - "peer": true, "engines": { "node": ">=18.0.0" }, @@ -27401,7 +27395,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/react": "*" }, @@ -27479,7 +27472,6 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz", "integrity": "sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==", "license": "MIT", - "peer": true, "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" @@ -27503,7 +27495,6 @@ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -27705,8 +27696,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/redux-thunk": { "version": "3.1.0", @@ -28187,6 +28177,7 @@ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "license": "MIT", + "peer": true, "dependencies": { "lowercase-keys": "^2.0.0" }, @@ -28441,7 +28432,6 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^5.0.0", "immutable": "^5.1.5", @@ -28570,7 +28560,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -29853,7 +29842,6 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz", "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==", "license": "MIT", - "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -30355,8 +30343,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tsx": { "version": "4.22.4", @@ -30513,7 +30500,6 @@ "integrity": "sha512-eJDEMAfxCmede22c/Jw7d0FA13ggAQv+KkwQYKYCdqI02cin6Rc9QRwbG/7XvvHWinuFejySnZVUWDtvGk3Vbg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 18" }, @@ -30526,7 +30512,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -30783,7 +30768,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "dependencies": { "napi-postinstall": "^0.3.4" }, @@ -31440,7 +31424,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.2.tgz", "integrity": "sha512-sUWBWPJwWH+QHUObS4lfNaQ368Tj8NaHDBsRJcU/NmQpeOqxV5iQUT2c5nvDWi8WYR5ynF7az+PuMdc+oDLJOA==", "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", @@ -31987,7 +31970,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" }, From e5fafc07fae3a3245496684ac4e3188b78a9a84b Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Mon, 27 Jul 2026 12:30:05 +0100 Subject: [PATCH 16/22] Add comments --- ccip-sdk/src/cct/evm/index.ts | 11 ++++++++--- .../evm/token-pool/operations/deploy-token-pool.ts | 10 +++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index aae2e99e..ab3c0eba 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -130,12 +130,14 @@ export class EVMTokenManager extends TokenManager { * only known once mined, so it is NOT returned here — use {@link deployTokenPool} to receive * `{ hash, contractAddress }`. * @remarks Same post-deploy setup caveat as {@link deployTokenPool} — a fresh pool must be - * registered, role-granted, and lane-configured before it can bridge. + * registered, role-granted, and lane-configured before it can bridge. `LockReleaseTokenPool` + * additionally requires a pre-deployed `lockBox` ({@link DeployLockReleaseTokenPoolParams}); + * deploying the lockbox and authorizing the pool on it are not yet SDK operations. * @throws {@link CCTParamsInvalidError} if any param is invalid * @example * ```typescript * const unsigned = await cct.generateUnsignedDeployTokenPool({ - * type: 'BurnMintTokenPool', // or BurnFromMint / BurnWithFromMint / LockRelease + * type: 'BurnMintTokenPool', // burn-* variant; LockReleaseTokenPool additionally requires `lockBox` * token: '0xToken...', * localTokenDecimals: 18, * rmnProxy: '0xRmnProxy...', @@ -154,7 +156,9 @@ export class EVMTokenManager extends TokenManager { * `DeployableTokenPoolType`, v2.0.0). * @remarks Deploying the pool alone doesn't make it usable: register it with {@link setPool}, * grant it the token's mint/burn roles (`grantMintAndBurnRoles`), and configure its remote - * pools + rate limits before it can bridge. + * pools + rate limits before it can bridge. `LockReleaseTokenPool` also needs a pre-deployed + * `lockBox` and the pool authorized on it ({@link DeployLockReleaseTokenPoolParams}) — neither is + * an SDK operation yet (follow-up). * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address @@ -166,6 +170,7 @@ export class EVMTokenManager extends TokenManager { * localTokenDecimals: 18, * rmnProxy: '0xRmnProxy...', * router: '0xRouter...', + * lockBox: '0xLockBox...', // required for LockReleaseTokenPool; must be a non-zero address * wallet, * }) * ``` diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts index 8e8e7b5a..3e16b2c4 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts @@ -68,7 +68,15 @@ export interface DeployBurnMintTokenPoolParams extends DeployTokenPoolBase { type: Exclude } -/** Params for a `LockReleaseTokenPool` — the burn constructor plus `lockBox`. */ +/** + * Params for a `LockReleaseTokenPool` — the burn constructor plus `lockBox`. + * + * @remarks Partial support: `lockBox` must be an already-deployed `ERC20LockBox` for the *same* + * `token` (the pool constructor calls `lockBox.isTokenSupported(token)` and reverts otherwise). + * This SDK does not yet deploy the lockbox or authorize the pool on it — deploy the `ERC20LockBox` + * and add the pool via the lockbox's `applyAuthorizedCallerUpdates` out-of-band before the pool can + * lock/release. A `deployLockBox` op + caller-authorization are tracked as a follow-up. + */ export interface DeployLockReleaseTokenPoolParams extends DeployTokenPoolBase { type: 'LockReleaseTokenPool' /** Lock-box address; required and must be non-zero — the v2.0.0 constructor reverts on the zero address. */ From a0172b076ea92d92fc0f44de5698930aab9efaef Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Mon, 27 Jul 2026 17:09:32 +0100 Subject: [PATCH 17/22] feat(cct-sdk): Add EVM deployLockbox operation (DAPP-10738) Vendor ERC20LockBox v2.0.0 artifacts; add the cached lockbox Interface + DeployLockbox op, wire generateUnsignedDeployLockbox/deployLockbox into EVMTokenManager, and document the LockRelease deploy sequence. --- .../evm/artifacts/abi/V2_0_0/erc20-lockbox.ts | 253 ++++++++++++++++++ .../bytecode/V2_0_0/erc20-lockbox.ts | 3 + ccip-sdk/src/cct/evm/index.ts | 113 +++++--- ccip-sdk/src/cct/evm/lockbox/interface.ts | 19 ++ .../lockbox/operations/deploy-lockbox.test.ts | 148 ++++++++++ .../evm/lockbox/operations/deploy-lockbox.ts | 70 +++++ .../operations/deploy-token-pool.test.ts | 20 +- .../operations/deploy-token-pool.ts | 32 ++- 8 files changed, 599 insertions(+), 59 deletions(-) create mode 100644 ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/erc20-lockbox.ts create mode 100644 ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/erc20-lockbox.ts create mode 100644 ccip-sdk/src/cct/evm/lockbox/interface.ts create mode 100644 ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.test.ts create mode 100644 ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts diff --git a/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/erc20-lockbox.ts b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/erc20-lockbox.ts new file mode 100644 index 00000000..192167b6 --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/abi/V2_0_0/erc20-lockbox.ts @@ -0,0 +1,253 @@ +export default [ + // generate: + // (() => { + // const abi = require('@chainlink/contracts-ccip/abi/v2_0_0/erc20_lock_box.json') + // return require('util').inspect(Array.isArray(abi) ? abi : abi.abi, { depth: 99 }).split('\n').slice(1, -1) + // })() + { + type: 'constructor', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'applyAuthorizedCallerUpdates', + inputs: [ + { + name: 'authorizedCallerArgs', + type: 'tuple', + internalType: 'struct AuthorizedCallers.AuthorizedCallerArgs', + components: [ + { + name: 'addedCallers', + type: 'address[]', + internalType: 'address[]', + }, + { + name: 'removedCallers', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'deposit', + inputs: [ + { name: 'token', type: 'address', internalType: 'address' }, + { name: '', type: 'uint64', internalType: 'uint64' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAllAuthorizedCallers', + inputs: [], + outputs: [{ name: '', type: 'address[]', internalType: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getToken', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'contract IERC20' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isTokenSupported', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + outputs: [{ name: '', type: 'bool', internalType: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [{ name: '', type: 'address', internalType: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [{ name: 'to', type: 'address', internalType: 'address' }], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'typeAndVersion', + inputs: [], + outputs: [{ name: '', type: 'string', internalType: 'string' }], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'withdraw', + inputs: [ + { name: 'token', type: 'address', internalType: 'address' }, + { name: '', type: 'uint64', internalType: 'uint64' }, + { name: 'amount', type: 'uint256', internalType: 'uint256' }, + { name: 'recipient', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'AuthorizedCallerAdded', + inputs: [ + { + name: 'caller', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'AuthorizedCallerRemoved', + inputs: [ + { + name: 'caller', + type: 'address', + indexed: false, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Deposit', + inputs: [ + { + name: 'token', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'depositor', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferRequested', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'from', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'to', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Withdrawal', + inputs: [ + { + name: 'token', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'recipient', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { type: 'error', name: 'CannotTransferToSelf', inputs: [] }, + { + type: 'error', + name: 'InsufficientBalance', + inputs: [ + { name: 'requested', type: 'uint256', internalType: 'uint256' }, + { name: 'available', type: 'uint256', internalType: 'uint256' }, + ], + }, + { type: 'error', name: 'MustBeProposedOwner', inputs: [] }, + { type: 'error', name: 'OnlyCallableByOwner', inputs: [] }, + { type: 'error', name: 'OwnerCannotBeZero', inputs: [] }, + { type: 'error', name: 'RecipientCannotBeZeroAddress', inputs: [] }, + { + type: 'error', + name: 'SafeERC20FailedOperation', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'TokenAmountCannotBeZero', inputs: [] }, + { + type: 'error', + name: 'UnauthorizedCaller', + inputs: [{ name: 'caller', type: 'address', internalType: 'address' }], + }, + { + type: 'error', + name: 'UnsupportedToken', + inputs: [{ name: 'token', type: 'address', internalType: 'address' }], + }, + { type: 'error', name: 'ZeroAddressNotAllowed', inputs: [] }, +] as const diff --git a/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/erc20-lockbox.ts b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/erc20-lockbox.ts new file mode 100644 index 00000000..7de3194e --- /dev/null +++ b/ccip-sdk/src/cct/evm/artifacts/bytecode/V2_0_0/erc20-lockbox.ts @@ -0,0 +1,3 @@ +export default // generate: +// `'${require('fs').readFileSync(require.resolve('@chainlink/contracts-ccip/bytecode/v2_0_0/erc20_lock_box.bin'), 'utf8').trim()}' as const` +'0x60a0604052346101d9576113cf6020813803918261001c816101de565b9384928339810103126101d957516001600160a01b038116908190036101d957602090610048826101de565b9160008352600036813733156101c857600180546001600160a01b03191633179055610073816101de565b60008152600036813760408051949085016001600160401b038111868210176101b2576040528452808285015260005b815181101561010a576001906001600160a01b036100c18285610203565b5116846100cd82610245565b6100da575b5050016100a3565b7fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda7758091604051908152a138846100d2565b5050915160005b8151811015610182576001600160a01b0361012c8284610203565b5116908115610171577feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef8583610163600195610343565b50604051908152a101610111565b6342bcdf7f60e11b60005260046000fd5b8280156101715760805260405161102b90816103a482396080518181816105f6015281816109960152610c060152f35b634e487b7160e01b600052604160045260246000fd5b639b15e16f60e01b60005260046000fd5b600080fd5b6040519190601f01601f191682016001600160401b038111838210176101b257604052565b80518210156102175760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b80548210156102175760005260206000200190600090565b600081815260036020526040902054801561033c57600019810181811161032657600254600019810191908211610326578082036102d5575b50505060025480156102bf576000190161029981600261022d565b8154906000199060031b1b19169055600255600052600360205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b61030e6102e66102f793600261022d565b90549060031b1c928392600261022d565b819391549060031b91821b91600019901b19161790565b9055600052600360205260406000205538808061027e565b634e487b7160e01b600052601160045260246000fd5b5050600090565b8060005260036020526040600020541560001461039d57600254680100000000000000008110156101b2576103846102f7826001859401600255600261022d565b9055600254906000526003602052604060002055600190565b5060009056fe608080604052600436101561001357600080fd5b60003560e01c908163181f5a77146109ba5750806321df0da71461094b5780632451a6271461085d57806374fd18ac1461061b57806375151b631461058c57806379ba5097146104a35780638da5cb5b1461045157806391a2749a14610267578063a36a7fee146101825763f2fde38b1461008d57600080fd5b3461017d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d5773ffffffffffffffffffffffffffffffffffffffff6100d9610a89565b6100e1610cc8565b1633811461015357807fffffffffffffffffffffffff0000000000000000000000000000000000000000600054161760005573ffffffffffffffffffffffffffffffffffffffff600154167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278600080a3005b7fdad89dca0000000000000000000000000000000000000000000000000000000060005260046000fd5b600080fd5b3461017d5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d576101b9610a89565b6101c1610aac565b5073ffffffffffffffffffffffffffffffffffffffff604435916101e58382610bd3565b166102396040517f23b872dd00000000000000000000000000000000000000000000000000000000602082015233602482015230604482015283606482015260648152610233608482610b0e565b82610d56565b6040519182527f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f6260203393a3005b3461017d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d5760043567ffffffffffffffff811161017d5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc823603011261017d57604051906102e182610ac3565b806004013567ffffffffffffffff811161017d576103059060043691840101610b4f565b825260248101359067ffffffffffffffff821161017d57600461032b9236920101610b4f565b6020820190815261033a610cc8565b519060005b82518110156103b2578073ffffffffffffffffffffffffffffffffffffffff61036a60019386610d13565b511661037581610df9565b610381575b500161033f565b60207fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda7758091604051908152a18461037a565b505160005b815181101561044f5773ffffffffffffffffffffffffffffffffffffffff6103df8284610d13565b5116908115610425577feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef602083610417600195610fbe565b50604051908152a1016103b7565b7f8579befe0000000000000000000000000000000000000000000000000000000060005260046000fd5b005b3461017d5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b3461017d5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d5760005473ffffffffffffffffffffffffffffffffffffffff81163303610562577fffffffffffffffffffffffff00000000000000000000000000000000000000006001549133828416176001551660005573ffffffffffffffffffffffffffffffffffffffff3391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b7f02b543c60000000000000000000000000000000000000000000000000000000060005260046000fd5b3461017d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d5760206105c5610a89565b73ffffffffffffffffffffffffffffffffffffffff604051911673ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148152f35b3461017d5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d57610652610a89565b61065a610aac565b506044356064359173ffffffffffffffffffffffffffffffffffffffff831680930361017d57819061068c8382610bd3565b83156108335773ffffffffffffffffffffffffffffffffffffffff1691604051907f70a08231000000000000000000000000000000000000000000000000000000008252306004830152602082602481875afa918215610827576000926107d0575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146107c8575b808211610797575060207f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b63989161078e6040517fa9059cbb000000000000000000000000000000000000000000000000000000008482015286602482015282604482015260448152610788606482610b0e565b85610d56565b604051908152a3005b907fcf4791810000000000000000000000000000000000000000000000000000000060005260045260245260446000fd5b905080610716565b90916020823d60201161081f575b816107eb60209383610b0e565b8101031261081c575051907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106ee565b80fd5b3d91506107de565b6040513d6000823e3d90fd5b7fd87070520000000000000000000000000000000000000000000000000000000060005260046000fd5b3461017d5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d576040518060206002549283815201809260026000527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace9060005b81811061093557505050816108dc910382610b0e565b6040519182916020830190602084525180915260408301919060005b818110610906575050500390f35b825173ffffffffffffffffffffffffffffffffffffffff168452859450602093840193909201916001016108f8565b82548452602090930192600192830192016108c6565b3461017d5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461017d5760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017d576109f281610ac3565b601281527f45524332304c6f636b426f7820322e302e300000000000000000000000000000602082015260405190602082528181519182602083015260005b838110610a715750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604080968601015201168101030190f35b60208282018101516040878401015285935001610a31565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361017d57565b6024359067ffffffffffffffff8216820361017d57565b6040810190811067ffffffffffffffff821117610adf57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610adf57604052565b81601f8201121561017d5780359167ffffffffffffffff8311610adf578260051b9160405193610b826020850186610b0e565b845260208085019382010191821161017d57602001915b818310610ba65750505090565b823573ffffffffffffffffffffffffffffffffffffffff8116810361017d57815260209283019201610b99565b9015610c9e5773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168103610c71575033600052600360205260406000205415610c4357565b7fd86ad9cf000000000000000000000000000000000000000000000000000000006000523360045260246000fd5b7fbf16aab60000000000000000000000000000000000000000000000000000000060005260045260246000fd5b7f8b1fa9dd0000000000000000000000000000000000000000000000000000000060005260046000fd5b73ffffffffffffffffffffffffffffffffffffffff600154163303610ce957565b7f2b5c74de0000000000000000000000000000000000000000000000000000000060005260046000fd5b8051821015610d275760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000602091828151910182855af115610827576000513d610dd8575073ffffffffffffffffffffffffffffffffffffffff81163b155b610d945750565b73ffffffffffffffffffffffffffffffffffffffff907f5274afe7000000000000000000000000000000000000000000000000000000006000521660045260246000fd5b60011415610d8d565b8054821015610d275760005260206000200190600090565b6000818152600360205260409020548015610fb7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101818111610f8857600254907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8201918211610f8857808203610f19575b5050506002548015610eea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ea7816002610de1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82549160031b1b19169055600255600052600360205260006040812055600190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610f70610f2a610f3b936002610de1565b90549060031b1c9283926002610de1565b81939154907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9060031b92831b921b19161790565b90556000526003602052604060002055388080610e6e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5050600090565b806000526003602052604060002054156000146110185760025468010000000000000000811015610adf57610fff610f3b8260018594016002556002610de1565b9055600254906000526003602052604060002055600190565b5060009056fea164736f6c634300081a000a' as const diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index ab3c0eba..4947e3fc 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -14,6 +14,7 @@ import type { UnsignedEVMTx } from '../../evm/types.ts' import type { ChainFamily } from '../../networks.ts' import type { TransactionResult } from '../operation.ts' import { TokenManager } from '../token-manager.ts' +import { type DeployLockboxParams, DeployLockbox } from './lockbox/operations/deploy-lockbox.ts' import type { DeployResult, EVMExecuteParams } from './operation.ts' import { type DeployTokenParams, DeployToken } from './token/operations/deploy-token.ts' import { type SetPoolParams, SetPool } from './token-admin-registry/operations/set-pool.ts' @@ -33,6 +34,7 @@ export class EVMTokenManager extends TokenManager { readonly #transferOwnership = new TransferOwnership() readonly #deployToken = new DeployToken() readonly #deployTokenPool = new DeployTokenPool() + readonly #deployLockbox = new DeployLockbox() /** Wraps an {@link EVMChain}; prefer the static factory methods. */ constructor(chain: EVMChain) { @@ -123,6 +125,54 @@ export class EVMTokenManager extends TokenManager { return this.#transferOwnership.execute(this.chain, opts) } + /** + * Builds an unsigned `CrossChainToken` (v2.0.0) deployment tx (for multisig / offline + * signing). The deployed address is only known once mined, so it is NOT returned here — + * use {@link deployToken} to deploy and receive `{ hash, contractAddress }`. + * @remarks Same post-deploy roles caveat as {@link deployToken} — the pool needs + * `grantMintAndBurnRoles` before it can bridge. + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @example + * ```typescript + * const unsigned = await cct.generateUnsignedDeployToken({ + * name: 'My Token', + * symbol: 'MTK', + * decimals: 18, + * maxSupply: 0n, // 0 = unlimited + * owner: '0xOwner...', // CrossChainToken v2.0.0; ccipAdmin/burnMintRoleAdmin default to owner + * sender: '0xDeployer...', + * }) + * ``` + */ + generateUnsignedDeployToken(opts: DeployTokenParams): Promise { + return this.#deployToken.generate(this.chain, opts) + } + + /** + * Deploys a `CrossChainToken` (v2.0.0), signing + submitting with `opts.wallet`; resolves + * to the tx hash and the newly deployed token address. + * @remarks Mint/burn are role-gated (`MINTER_ROLE`/`BURNER_ROLE`); the token grants neither + * to any pool at deploy. `preMint` mints initial supply to `preMintRecipient`, but before a + * pool can bridge, `burnMintRoleAdmin` must `grantMintAndBurnRoles(pool)`. + * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer + * @throws {@link CCTParamsInvalidError} if any param is invalid + * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address + * @example + * ```typescript + * const { hash, contractAddress } = await cct.deployToken({ + * name: 'My Token', + * symbol: 'MTK', + * decimals: 18, + * maxSupply: 0n, + * owner: '0xOwner...', + * wallet, + * }) + * ``` + */ + deployToken(opts: EVMExecuteParams): Promise { + return this.#deployToken.execute(this.chain, opts) + } + /** * Builds an unsigned pool deployment tx (for multisig / offline signing). `type` selects * the pool contract — a `DeployableTokenPoolType` (`BurnMintTokenPool`, `BurnFromMintTokenPool`, @@ -131,13 +181,15 @@ export class EVMTokenManager extends TokenManager { * `{ hash, contractAddress }`. * @remarks Same post-deploy setup caveat as {@link deployTokenPool} — a fresh pool must be * registered, role-granted, and lane-configured before it can bridge. `LockReleaseTokenPool` - * additionally requires a pre-deployed `lockBox` ({@link DeployLockReleaseTokenPoolParams}); - * deploying the lockbox and authorizing the pool on it are not yet SDK operations. + * additionally requires a pre-deployed `lockbox` ({@link DeployLockReleaseTokenPoolParams}) + * with the pool authorized on it. The full sequence: {@link deployToken} → {@link deployLockbox} + * → {@link deployTokenPool} (passing the lockbox) → {@link authorizeLockboxCallers} + * (`addedCallers: [pool]`) → {@link setPool} → configure lanes. * @throws {@link CCTParamsInvalidError} if any param is invalid * @example * ```typescript * const unsigned = await cct.generateUnsignedDeployTokenPool({ - * type: 'BurnMintTokenPool', // burn-* variant; LockReleaseTokenPool additionally requires `lockBox` + * type: 'BurnMintTokenPool', // burn-* variant; LockReleaseTokenPool additionally requires `lockbox` * token: '0xToken...', * localTokenDecimals: 18, * rmnProxy: '0xRmnProxy...', @@ -157,8 +209,10 @@ export class EVMTokenManager extends TokenManager { * @remarks Deploying the pool alone doesn't make it usable: register it with {@link setPool}, * grant it the token's mint/burn roles (`grantMintAndBurnRoles`), and configure its remote * pools + rate limits before it can bridge. `LockReleaseTokenPool` also needs a pre-deployed - * `lockBox` and the pool authorized on it ({@link DeployLockReleaseTokenPoolParams}) — neither is - * an SDK operation yet (follow-up). + * `lockbox` and the pool authorized on it ({@link DeployLockReleaseTokenPoolParams}). The full + * sequence: {@link deployToken} → {@link deployLockbox} → {@link deployTokenPool} (passing the + * lockbox) → {@link authorizeLockboxCallers} (`addedCallers: [pool]`) → {@link setPool} → + * configure lanes. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address @@ -170,7 +224,7 @@ export class EVMTokenManager extends TokenManager { * localTokenDecimals: 18, * rmnProxy: '0xRmnProxy...', * router: '0xRouter...', - * lockBox: '0xLockBox...', // required for LockReleaseTokenPool; must be a non-zero address + * lockbox: '0xLockbox...', // required for LockReleaseTokenPool; must be a non-zero address * wallet, * }) * ``` @@ -180,52 +234,46 @@ export class EVMTokenManager extends TokenManager { } /** - * Builds an unsigned `CrossChainToken` (v2.0.0) deployment tx (for multisig / offline - * signing). The deployed address is only known once mined, so it is NOT returned here — - * use {@link deployToken} to deploy and receive `{ hash, contractAddress }`. - * @remarks Same post-deploy roles caveat as {@link deployToken} — the pool needs - * `grantMintAndBurnRoles` before it can bridge. + * Builds an unsigned `ERC20LockBox` (v2.0.0) deployment tx (for multisig / offline signing). + * A lockbox escrows a single `token` for `LockReleaseTokenPool`s. The deployed address is + * only known once mined, so it is NOT returned here — use {@link deployLockbox} to receive + * `{ hash, contractAddress }`. + * @remarks Deploy the lockbox before its pool, then authorize the pool on it with + * {@link authorizeLockboxCallers} before the pool can lock/release. * @throws {@link CCTParamsInvalidError} if any param is invalid * @example * ```typescript - * const unsigned = await cct.generateUnsignedDeployToken({ - * name: 'My Token', - * symbol: 'MTK', - * decimals: 18, - * maxSupply: 0n, // 0 = unlimited - * owner: '0xOwner...', // CrossChainToken v2.0.0; ccipAdmin/burnMintRoleAdmin default to owner + * const unsigned = await cct.generateUnsignedDeployLockbox({ + * token: '0xToken...', // must be non-zero; the same token the LockReleaseTokenPool manages * sender: '0xDeployer...', * }) * ``` */ - generateUnsignedDeployToken(opts: DeployTokenParams): Promise { - return this.#deployToken.generate(this.chain, opts) + generateUnsignedDeployLockbox(opts: DeployLockboxParams): Promise { + return this.#deployLockbox.generate(this.chain, opts) } /** - * Deploys a `CrossChainToken` (v2.0.0), signing + submitting with `opts.wallet`; resolves - * to the tx hash and the newly deployed token address. - * @remarks Mint/burn are role-gated (`MINTER_ROLE`/`BURNER_ROLE`); the token grants neither - * to any pool at deploy. `preMint` mints initial supply to `preMintRecipient`, but before a - * pool can bridge, `burnMintRoleAdmin` must `grantMintAndBurnRoles(pool)`. + * Deploys an `ERC20LockBox` (v2.0.0), signing + submitting with `opts.wallet`; resolves to the + * tx hash and the newly deployed lockbox address. + * @remarks Step two of the lock/release flow: {@link deployToken} → {@link deployLockbox} → + * {@link deployTokenPool} (passing this lockbox) → {@link authorizeLockboxCallers} + * (`addedCallers: [pool]`) → {@link setPool} → configure lanes. * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer * @throws {@link CCTParamsInvalidError} if any param is invalid * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address * @example * ```typescript - * const { hash, contractAddress } = await cct.deployToken({ - * name: 'My Token', - * symbol: 'MTK', - * decimals: 18, - * maxSupply: 0n, - * owner: '0xOwner...', + * const { hash, contractAddress } = await cct.deployLockbox({ + * token: '0xToken...', * wallet, * }) * ``` */ - deployToken(opts: EVMExecuteParams): Promise { - return this.#deployToken.execute(this.chain, opts) + deployLockbox(opts: EVMExecuteParams): Promise { + return this.#deployLockbox.execute(this.chain, opts) } + } export * from '../errors.ts' @@ -235,5 +283,6 @@ export type { DeployTokenPoolParams, DeployableTokenPoolType, } from './token-pool/operations/deploy-token-pool.ts' +export type { DeployLockboxParams } from './lockbox/operations/deploy-lockbox.ts' export type { DeployResult, EVMExecuteParams } from './operation.ts' export type { TransactionResult } from '../operation.ts' diff --git a/ccip-sdk/src/cct/evm/lockbox/interface.ts b/ccip-sdk/src/cct/evm/lockbox/interface.ts new file mode 100644 index 00000000..0f0176e3 --- /dev/null +++ b/ccip-sdk/src/cct/evm/lockbox/interface.ts @@ -0,0 +1,19 @@ +/** + * Deploy artifacts for `ERC20LockBox`: the cached {@link Interface} (constructor + calldata + * encoding) and the creation {@link LOCKBOX_BYTECODE}, built/loaded once from the vendored + * `artifacts/`. Only one lockbox version is deployable, so there is no version framework here — + * ops import these directly. + * + * @packageDocumentation + */ + +import { Interface } from 'ethers' + +import ERC20_LOCKBOX_V2_0_0_ABI from '../artifacts/abi/V2_0_0/erc20-lockbox.ts' +import ERC20_LOCKBOX_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/erc20-lockbox.ts' + +/** Shared, cached `ERC20LockBox` interface for constructor and calldata encoding. */ +export const LOCKBOX_INTERFACE = new Interface(ERC20_LOCKBOX_V2_0_0_ABI) + +/** `ERC20LockBox` creation bytecode for `deployLockbox`. */ +export const LOCKBOX_BYTECODE = ERC20_LOCKBOX_V2_0_0_BYTECODE diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.test.ts b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.test.ts new file mode 100644 index 00000000..b62c4f02 --- /dev/null +++ b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.test.ts @@ -0,0 +1,148 @@ +import assert from 'node:assert/strict' +import { describe, it } from 'node:test' + +import { Interface, ZeroAddress, makeError } from 'ethers' + +import { DeployLockbox } from './deploy-lockbox.ts' +import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../errors/index.ts' +import type { EVMChain } from '../../../../evm/index.ts' +import { ChainFamily } from '../../../../networks.ts' +import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' +import ERC20_LOCKBOX_V2_0_0_ABI from '../../artifacts/abi/V2_0_0/erc20-lockbox.ts' +import LOCKBOX_V2_0_0 from '../../artifacts/bytecode/V2_0_0/erc20-lockbox.ts' + +const SENDER = '0x' + '11'.repeat(20) +const TOKEN = '0x' + '22'.repeat(20) +const DEPLOYED = '0x' + '77'.repeat(20) +const HASH = '0x' + 'ab'.repeat(32) + +// Golden vector: the ctor arg is a single 32-byte word holding the token address. Computed +// independently with a fresh ethers Interface so it guards the SDK's init-code against drift. +const W_TOKEN = '0000000000000000000000002222222222222222222222222222222222222222' +const CTOR_ARGS = new Interface(ERC20_LOCKBOX_V2_0_0_ABI).encodeDeploy([TOKEN]) + +/** Minimal EVMChain stub — deployLockbox's build path ignores it; execute uses only these. */ +function stubChain(): EVMChain { + return { + provider: {} as never, + logger: { debug() {}, info() {}, warn() {}, error() {} }, + nextNonce: async () => 0, + rollbackNonce: () => {}, + } as unknown as EVMChain +} + +/** Fake ethers Signer whose deployment receipt carries `contractAddress`. */ +function fakeSigner(opts: { contractAddress?: string | null; waitError?: Error }) { + return { + signTransaction: () => Promise.resolve('0x'), + getAddress: () => Promise.resolve(SENDER), + populateTransaction: (tx: unknown) => Promise.resolve({ ...(tx as object) }), + sendTransaction: () => + Promise.resolve({ + hash: HASH, + wait: () => + opts.waitError + ? Promise.reject(opts.waitError) + : Promise.resolve({ + status: 1, + contractAddress: + opts.contractAddress === undefined ? DEPLOYED : opts.contractAddress, + }), + }), + } +} + +describe('DeployLockbox (cct/evm lockbox operation)', () => { + describe('generate (golden vector)', () => { + it('builds the lockbox as init-code with no `to`', async () => { + const unsigned = await new DeployLockbox().generate(stubChain(), { + token: TOKEN, + sender: SENDER, + }) + + assert.equal(unsigned.family, ChainFamily.EVM) + assert.equal(unsigned.transactions.length, 1) + const tx = unsigned.transactions[0]! + assert.equal(tx.to, undefined, 'deployment tx has no `to`') + assert.equal(tx.from, SENDER) + assert.ok(tx.data!.startsWith(LOCKBOX_V2_0_0), 'data starts with creation bytecode') + // Pinned bytes: the constructor arg is exactly the token address, left-padded to 32 bytes. + assert.equal(CTOR_ARGS, '0x' + W_TOKEN) + assert.equal(tx.data, LOCKBOX_V2_0_0 + W_TOKEN) + }) + + it('omits `from` when no sender is given', async () => { + const unsigned = await new DeployLockbox().generate(stubChain(), { token: TOKEN }) + assert.equal(unsigned.transactions[0]!.from, undefined) + }) + }) + + describe('validation', () => { + it('rejects an invalid token address', async () => { + await assert.rejects( + () => new DeployLockbox().generate(stubChain(), { token: 'nope' }), + (err: unknown) => + err instanceof CCTParamsInvalidError && + err.context.operation === 'deployLockbox' && + err.context.param === 'token', + ) + }) + + it('rejects the zero address for token', async () => { + await assert.rejects( + () => new DeployLockbox().generate(stubChain(), { token: ZeroAddress }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'token', + ) + }) + + it('rejects an invalid sender', async () => { + await assert.rejects( + () => new DeployLockbox().generate(stubChain(), { token: TOKEN, sender: 'nope' }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'sender', + ) + }) + }) + + describe('execute', () => { + it('deploys and returns the tx hash and deployed address', async () => { + const result = await new DeployLockbox().execute(stubChain(), { + token: TOKEN, + wallet: fakeSigner({ contractAddress: DEPLOYED }), + }) + assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) + }) + + it('throws CCTTxFailedError when the receipt carries no contract address', async () => { + await assert.rejects( + () => + new DeployLockbox().execute(stubChain(), { + token: TOKEN, + wallet: fakeSigner({ contractAddress: null }), + }), + (err: unknown) => + err instanceof CCTTxFailedError && + err.context.operation === 'deployLockbox' && + !err.isTransient, + ) + }) + + it('throws CCIPExecTxRevertedError when the deployment reverts on-chain', async () => { + await assert.rejects( + () => + new DeployLockbox().execute(stubChain(), { + token: TOKEN, + wallet: fakeSigner({ waitError: makeError('execution reverted', 'CALL_EXCEPTION') }), + }), + (err: unknown) => + err instanceof CCIPExecTxRevertedError && err.context.operation === 'deployLockbox', + ) + }) + + it('rejects a non-signer wallet', async () => { + await assert.rejects( + () => new DeployLockbox().execute(stubChain(), { token: TOKEN, wallet: {} }), + (err: unknown) => err instanceof CCIPWalletInvalidError, + ) + }) + }) +}) diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts new file mode 100644 index 00000000..cbfff189 --- /dev/null +++ b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts @@ -0,0 +1,70 @@ +/** + * deployLockbox — deploys an `ERC20LockBox` (v2.0.0) via raw init-code. The tx has no + * `to`; `execute` returns the deployed contract address. A lockbox escrows a single token + * for `LockReleaseTokenPool`s; deploy it before the pool, then authorize the pool on it via + * {@link AuthorizeLockboxCallers}. Mirrors `token-pool/operations/deploy-token-pool.ts`. + * + * @packageDocumentation + */ + +import { ZeroAddress } from 'ethers' + +import type { EVMChain } from '../../../../evm/index.ts' +import type { UnsignedEVMTx } from '../../../../evm/types.ts' +import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' +import { + type DeployResult, + type EVMExecuteParams, + EVMOperation, + deploymentTx, +} from '../../operation.ts' +import { submit } from '../../submit.ts' +import { validateAddress } from '../../validate.ts' +import { LOCKBOX_BYTECODE, LOCKBOX_INTERFACE } from '../interface.ts' + +/** Parameters for {@link DeployLockbox} — deploys `ERC20LockBox` (v2.0.0). */ +export interface DeployLockboxParams { + /** Address of the token the lockbox escrows; the v2.0.0 constructor reverts on the zero address. */ + token: string + /** Deployer address; sets `tx.from` for offline / multisig signing. */ + sender?: string +} + +/** Deploys an `ERC20LockBox`; `execute` resolves to `{ hash, contractAddress }`. */ +export class DeployLockbox extends EVMOperation { + readonly name = 'deployLockbox' + + /** Validates the constructor params before building init-code. */ + protected validate(params: DeployLockboxParams): void { + validateAddress(this.name, 'token', params.token) + if (params.token === ZeroAddress) + throw new CCTParamsInvalidError(this.name, 'token', 'must not be the zero address') + } + + /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ + protected buildUnsigned(_chain: EVMChain, params: DeployLockboxParams): UnsignedEVMTx { + return deploymentTx(LOCKBOX_BYTECODE, LOCKBOX_INTERFACE.encodeDeploy([params.token])) + } + + /** + * {@link generate}, then sign and submit; resolves to the tx hash and the newly deployed + * lockbox address (read from the mined receipt). + * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address + */ + override async execute( + chain: EVMChain, + params: EVMExecuteParams, + ): Promise { + const { response, receipt } = await submit( + chain, + params.wallet, + await this.generate(chain, params), + this.name, + ) + if (!receipt.contractAddress) + throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { + context: { txHash: response.hash }, + }) + return { hash: response.hash, contractAddress: receipt.contractAddress } + } +} diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts index 38a9f9bc..673e0c91 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts @@ -18,7 +18,7 @@ const TOKEN = '0x' + '22'.repeat(20) const RMN_PROXY = '0x' + '33'.repeat(20) const ROUTER = '0x' + '44'.repeat(20) const HOOKS = '0x' + '55'.repeat(20) -const LOCK_BOX = '0x' + '66'.repeat(20) +const LOCKBOX = '0x' + '66'.repeat(20) const DEPLOYED = '0x' + '77'.repeat(20) const HASH = '0x' + 'ab'.repeat(32) @@ -35,7 +35,7 @@ const W_LOCKBOX = '0000000000000000000000006666666666666666666666666666666666666 // Golden vectors: pinned 2.0.0 constructor-arg encodings for the fixed inputs above. Independent // of the SDK encoder — they guard each pool's init-code against drift. The burn-* variants share // the `BurnMint` constructor (token, decimals, advancedPoolHooks, rmnProxy, router); LockRelease -// adds `lockBox`. +// adds `lockbox`. const BURN_MINT_ARGS = W_TOKEN + W_DECIMALS + W_HOOKS + W_RMN + W_ROUTER const LOCK_RELEASE_ARGS = W_TOKEN + W_DECIMALS + W_HOOKS + W_RMN + W_ROUTER + W_LOCKBOX @@ -69,7 +69,7 @@ const CASES: { ...COMMON, type: 'LockReleaseTokenPool', advancedPoolHooks: HOOKS, - lockBox: LOCK_BOX, + lockbox: LOCKBOX, }, bytecode: LOCK_RELEASE_V2_0_0, ctorArgs: LOCK_RELEASE_ARGS, @@ -203,32 +203,32 @@ describe('DeployTokenPool (cct/evm token-pool operation)', () => { ) }) - it('rejects the zero address for a LockRelease lockBox', async () => { + it('rejects the zero address for a LockRelease lockbox', async () => { await assert.rejects( () => new DeployTokenPool().generate(stubChain(), { ...COMMON, type: 'LockReleaseTokenPool', advancedPoolHooks: HOOKS, - lockBox: ZeroAddress, + lockbox: ZeroAddress, }), - (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'lockBox', + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'lockbox', ) }) - it('rejects an invalid lockBox address', async () => { + it('rejects an invalid lockbox address', async () => { await assert.rejects( () => new DeployTokenPool().generate(stubChain(), { ...COMMON, type: 'LockReleaseTokenPool', advancedPoolHooks: HOOKS, - lockBox: 'nope', + lockbox: 'nope', }), - (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'lockBox', + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'lockbox', ) }) - // `lockBox` on a burn pool is a compile-time error (the DeployTokenPoolParams union), so + // `lockbox` on a burn pool is a compile-time error (the DeployTokenPoolParams union), so // there's no runtime case to test. }) diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts index 3e16b2c4..06c18248 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts @@ -48,7 +48,7 @@ const TOKEN_POOL_BYTECODE = { export type DeployableTokenPoolType = keyof typeof TOKEN_POOL_BYTECODE /** Fields shared by every deployable token pool. */ -interface DeployTokenPoolBase { +interface DeployTokenPoolBaseParams { /** Address of the token the pool manages. */ token: string /** The token's `decimals` (uint8). */ @@ -64,28 +64,26 @@ interface DeployTokenPoolBase { } /** Params for a burn-* mint pool — the burn family shares one constructor shape. */ -export interface DeployBurnMintTokenPoolParams extends DeployTokenPoolBase { +export interface DeployBurnMintTokenPoolParams extends DeployTokenPoolBaseParams { type: Exclude } /** - * Params for a `LockReleaseTokenPool` — the burn constructor plus `lockBox`. + * Params for a `LockReleaseTokenPool` — the burn constructor plus `lockbox`. * - * @remarks Partial support: `lockBox` must be an already-deployed `ERC20LockBox` for the *same* - * `token` (the pool constructor calls `lockBox.isTokenSupported(token)` and reverts otherwise). - * This SDK does not yet deploy the lockbox or authorize the pool on it — deploy the `ERC20LockBox` - * and add the pool via the lockbox's `applyAuthorizedCallerUpdates` out-of-band before the pool can - * lock/release. A `deployLockBox` op + caller-authorization are tracked as a follow-up. + * @remarks `lockbox` must be a pre-deployed `ERC20LockBox` for the *same* `token` (the constructor + * calls `lockbox.isTokenSupported(token)`). Sequence: deployToken → deployLockbox → deployTokenPool + * (this) → authorizeLockboxCallers (`addedCallers: [pool]`) → setPool → configure lanes. */ -export interface DeployLockReleaseTokenPoolParams extends DeployTokenPoolBase { +export interface DeployLockReleaseTokenPoolParams extends DeployTokenPoolBaseParams { type: 'LockReleaseTokenPool' - /** Lock-box address; required and must be non-zero — the v2.0.0 constructor reverts on the zero address. */ - lockBox: string + /** Lockbox address; required and must be non-zero — the v2.0.0 constructor reverts on the zero address. */ + lockbox: string } /** * Parameters for {@link DeployTokenPool}, discriminated on `type`: the burn-* variants share one - * constructor; `LockReleaseTokenPool` additionally requires `lockBox` (a compile-time guarantee). + * constructor; `LockReleaseTokenPool` additionally requires `lockbox` (a compile-time guarantee). */ export type DeployTokenPoolParams = DeployBurnMintTokenPoolParams | DeployLockReleaseTokenPoolParams @@ -102,7 +100,7 @@ const encodeBurnMintTokenPool: TokenPoolConstructorEncoder = (iface, p) => p.router, ]) -/** LockRelease constructor: the burn-* args plus `lockBox` (only that variant carries it). */ +/** LockRelease constructor: the burn-* args plus `lockbox` (only that variant carries it). */ const encodeLockReleaseTokenPool: TokenPoolConstructorEncoder = (iface, p) => iface.encodeDeploy([ p.token, @@ -110,7 +108,7 @@ const encodeLockReleaseTokenPool: TokenPoolConstructorEncoder = (iface, p) => p.advancedPoolHooks ?? ZeroAddress, p.rmnProxy, p.router, - p.type === 'LockReleaseTokenPool' ? p.lockBox : ZeroAddress, + p.type === 'LockReleaseTokenPool' ? p.lockbox : ZeroAddress, ]) /** Deploys a token pool; `execute` resolves to `{ hash, contractAddress }`. */ @@ -138,9 +136,9 @@ export class DeployTokenPool extends EVMOperation { if (params.advancedPoolHooks !== undefined) validateAddress(this.name, 'advancedPoolHooks', params.advancedPoolHooks) if (params.type === 'LockReleaseTokenPool') { - validateAddress(this.name, 'lockBox', params.lockBox) - if (params.lockBox === ZeroAddress) - throw new CCTParamsInvalidError(this.name, 'lockBox', 'must not be the zero address') + validateAddress(this.name, 'lockbox', params.lockbox) + if (params.lockbox === ZeroAddress) + throw new CCTParamsInvalidError(this.name, 'lockbox', 'must not be the zero address') } } From 2e44675f886faebe81e2f2803f77b5d17502066a Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Mon, 27 Jul 2026 17:09:57 +0100 Subject: [PATCH 18/22] feat(cct-sdk): Add EVM authorizeLockboxCallers operation (DAPP-10788) Add AuthorizeLockboxCallers op (wraps ERC20LockBox applyAuthorizedCallerUpdates) + tests, and wire generateUnsignedAuthorizeLockboxCallers/authorizeLockboxCallers into EVMTokenManager to complete the LockRelease flow. --- ccip-sdk/src/cct/evm/index.ts | 48 ++++ .../operations/authorize-callers.test.ts | 238 ++++++++++++++++++ .../lockbox/operations/authorize-callers.ts | 69 +++++ 3 files changed, 355 insertions(+) create mode 100644 ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts create mode 100644 ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 4947e3fc..8cabcb7e 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -14,6 +14,10 @@ import type { UnsignedEVMTx } from '../../evm/types.ts' import type { ChainFamily } from '../../networks.ts' import type { TransactionResult } from '../operation.ts' import { TokenManager } from '../token-manager.ts' +import { + type AuthorizeLockboxCallersParams, + AuthorizeLockboxCallers, +} from './lockbox/operations/authorize-callers.ts' import { type DeployLockboxParams, DeployLockbox } from './lockbox/operations/deploy-lockbox.ts' import type { DeployResult, EVMExecuteParams } from './operation.ts' import { type DeployTokenParams, DeployToken } from './token/operations/deploy-token.ts' @@ -35,6 +39,7 @@ export class EVMTokenManager extends TokenManager { readonly #deployToken = new DeployToken() readonly #deployTokenPool = new DeployTokenPool() readonly #deployLockbox = new DeployLockbox() + readonly #authorizeLockboxCallers = new AuthorizeLockboxCallers() /** Wraps an {@link EVMChain}; prefer the static factory methods. */ constructor(chain: EVMChain) { @@ -274,6 +279,48 @@ export class EVMTokenManager extends TokenManager { return this.#deployLockbox.execute(this.chain, opts) } + /** + * Builds an unsigned `ERC20LockBox` `applyAuthorizedCallerUpdates` tx (for multisig / offline + * signing) that adds/removes authorized callers. Authorize a `LockReleaseTokenPool` here so it + * can lock/release against the lockbox. + * @throws {@link CCTParamsInvalidError} if any param is invalid, or if no caller is supplied + * @example + * ```typescript + * // `sender` must be the lockbox owner + * const unsigned = await cct.generateUnsignedAuthorizeLockboxCallers({ + * lockbox: '0xLockbox...', + * addedCallers: ['0xPool...'], // the LockReleaseTokenPool to authorize + * sender: '0xLockboxOwner...', + * }) + * ``` + */ + generateUnsignedAuthorizeLockboxCallers( + opts: AuthorizeLockboxCallersParams, + ): Promise { + return this.#authorizeLockboxCallers.generate(this.chain, opts) + } + + /** + * Adds/removes authorized callers on an `ERC20LockBox`, signing + submitting with `opts.wallet` + * (the lockbox owner). Authorize the `LockReleaseTokenPool` before it can lock/release. + * @throws {@link CCIPWalletInvalidError} if `wallet` is not a valid signer + * @throws {@link CCTParamsInvalidError} if any param is invalid, or if no caller is supplied + * @throws {@link CCTTxFailedError} if the tx reverts or fails + * @example + * ```typescript + * // `wallet` must sign as the lockbox owner + * const { hash } = await cct.authorizeLockboxCallers({ + * lockbox: '0xLockbox...', + * addedCallers: ['0xPool...'], + * wallet, + * }) + * ``` + */ + authorizeLockboxCallers( + opts: EVMExecuteParams, + ): Promise { + return this.#authorizeLockboxCallers.execute(this.chain, opts) + } } export * from '../errors.ts' @@ -284,5 +331,6 @@ export type { DeployableTokenPoolType, } from './token-pool/operations/deploy-token-pool.ts' export type { DeployLockboxParams } from './lockbox/operations/deploy-lockbox.ts' +export type { AuthorizeLockboxCallersParams } from './lockbox/operations/authorize-callers.ts' export type { DeployResult, EVMExecuteParams } from './operation.ts' export type { TransactionResult } from '../operation.ts' diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts new file mode 100644 index 00000000..2b3d1734 --- /dev/null +++ b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts @@ -0,0 +1,238 @@ +import assert from 'node:assert/strict' +import { describe, it } from 'node:test' + +import { ZeroAddress, makeError } from 'ethers' + +import { AuthorizeLockboxCallers } from './authorize-callers.ts' +import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../errors/index.ts' +import type { EVMChain } from '../../../../evm/index.ts' +import { ChainFamily } from '../../../../networks.ts' +import { CCTParamsInvalidError } from '../../../errors.ts' + +const SENDER = '0x' + '11'.repeat(20) +const LOCKBOX = '0x' + '66'.repeat(20) +const POOL = '0x' + '77'.repeat(20) +const OTHER = '0x' + '88'.repeat(20) +const HASH = '0x' + 'ab'.repeat(32) + +// applyAuthorizedCallerUpdates selector, per the vendored ABI (spec-pinned). +const SELECTOR = '0x91a2749a' +// Golden vectors: full literal calldata, hand-encoded from the ABI layout of +// applyAuthorizedCallerUpdates((address[] addedCallers, address[] removedCallers)) — a dynamic +// tuple of two dynamic address[] arrays. Pinning the whole byte string (rather than re-encoding +// through the SDK's own ABI) anchors every caller's position, so an added/removed swap or an +// ABI-ordering regression is caught instead of being mirrored into the expectation. +const W_TUPLE = '0000000000000000000000000000000000000000000000000000000000000020' // -> tuple +const OFF_40 = '0000000000000000000000000000000000000000000000000000000000000040' +const OFF_60 = '0000000000000000000000000000000000000000000000000000000000000060' +const OFF_80 = '0000000000000000000000000000000000000000000000000000000000000080' +const LEN_0 = '0000000000000000000000000000000000000000000000000000000000000000' +const LEN_1 = '0000000000000000000000000000000000000000000000000000000000000001' +// 20-byte address left-padded to a 32-byte word. +const word = (addr: string) => '000000000000000000000000' + addr.slice(2) + +/** Minimal EVMChain stub — the build path ignores it; execute uses only these. */ +function stubChain(): EVMChain { + return { + provider: {} as never, + logger: { debug() {}, info() {}, warn() {}, error() {} }, + nextNonce: async () => 0, + rollbackNonce: () => {}, + } as unknown as EVMChain +} + +/** Fake ethers Signer for a plain (non-deployment) tx. */ +function fakeSigner(opts: { waitError?: Error } = {}) { + return { + signTransaction: () => Promise.resolve('0x'), + getAddress: () => Promise.resolve(SENDER), + populateTransaction: (tx: unknown) => Promise.resolve({ ...(tx as object) }), + sendTransaction: () => + Promise.resolve({ + hash: HASH, + wait: () => + opts.waitError + ? Promise.reject(opts.waitError) + : Promise.resolve({ status: 1, contractAddress: null }), + }), + } +} + +describe('AuthorizeLockboxCallers (cct/evm lockbox operation)', () => { + describe('generate (golden vectors)', () => { + it('encodes an added caller as a call to the lockbox', async () => { + const unsigned = await new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL], + sender: SENDER, + }) + + assert.equal(unsigned.family, ChainFamily.EVM) + assert.equal(unsigned.transactions.length, 1) + const tx = unsigned.transactions[0]! + assert.equal(tx.to, LOCKBOX) + assert.equal(tx.from, SENDER) + assert.ok( + tx.data!.startsWith(SELECTOR), + 'data carries the applyAuthorizedCallerUpdates selector', + ) + // addedCallers:[POOL], removedCallers:[] — added array holds POOL, removed is empty. + assert.equal(tx.data, SELECTOR + W_TUPLE + OFF_40 + OFF_80 + LEN_1 + word(POOL) + LEN_0) + }) + + it('encodes both added and removed callers', async () => { + const unsigned = await new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL], + removedCallers: [OTHER], + }) + // POOL sits in the added array, OTHER in the removed array — swapping them changes these bytes. + assert.equal( + unsigned.transactions[0]!.data, + SELECTOR + W_TUPLE + OFF_40 + OFF_80 + LEN_1 + word(POOL) + LEN_1 + word(OTHER), + ) + }) + + it('defaults omitted caller arrays to empty', async () => { + const unsigned = await new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + removedCallers: [OTHER], + }) + // addedCallers omitted -> empty; OTHER lands in the removed array (removed offset is 0x60). + assert.equal( + unsigned.transactions[0]!.data, + SELECTOR + W_TUPLE + OFF_40 + OFF_60 + LEN_0 + LEN_1 + word(OTHER), + ) + }) + + it('omits `from` when no sender is given', async () => { + const unsigned = await new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL], + }) + assert.equal(unsigned.transactions[0]!.from, undefined) + }) + }) + + describe('validation', () => { + it('rejects an invalid lockbox address', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: 'nope', + addedCallers: [POOL], + }), + (err: unknown) => + err instanceof CCTParamsInvalidError && + err.context.operation === 'authorizeLockboxCallers' && + err.context.param === 'lockbox', + ) + }) + + it('rejects when no callers are supplied', async () => { + await assert.rejects( + () => new AuthorizeLockboxCallers().generate(stubChain(), { lockbox: LOCKBOX }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'addedCallers', + ) + }) + + it('rejects when both caller arrays are empty', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [], + removedCallers: [], + }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'addedCallers', + ) + }) + + it('rejects an invalid added caller address', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL, 'nope'], + }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'addedCallers[1]', + ) + }) + + it('rejects an invalid removed caller address', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + removedCallers: ['nope'], + }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'removedCallers[0]', + ) + }) + + it('rejects the zero address as a caller', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [ZeroAddress], + }), + (err: unknown) => + err instanceof CCTParamsInvalidError && err.context.param === 'addedCallers[0]', + ) + }) + + it('rejects an invalid sender', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL], + sender: 'nope', + }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'sender', + ) + }) + }) + + describe('execute', () => { + it('signs, submits, and returns the tx hash', async () => { + const result = await new AuthorizeLockboxCallers().execute(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL], + wallet: fakeSigner(), + }) + assert.deepEqual(result, { hash: HASH }) + }) + + it('throws CCIPExecTxRevertedError when the tx reverts on-chain', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().execute(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL], + wallet: fakeSigner({ waitError: makeError('execution reverted', 'CALL_EXCEPTION') }), + }), + (err: unknown) => + err instanceof CCIPExecTxRevertedError && + err.context.operation === 'authorizeLockboxCallers', + ) + }) + + it('rejects a non-signer wallet', async () => { + await assert.rejects( + () => + new AuthorizeLockboxCallers().execute(stubChain(), { + lockbox: LOCKBOX, + addedCallers: [POOL], + wallet: {}, + }), + (err: unknown) => err instanceof CCIPWalletInvalidError, + ) + }) + }) +}) diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts new file mode 100644 index 00000000..fc8a87f2 --- /dev/null +++ b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts @@ -0,0 +1,69 @@ +/** + * authorizeLockboxCallers — adds/removes authorized callers on an `ERC20LockBox` (v2.0.0) via + * `applyAuthorizedCallerUpdates`. A `LockReleaseTokenPool` must be an authorized caller of its + * lockbox before it can lock/release. Mirrors `token-pool/operations/transfer-ownership.ts`. + * + * @packageDocumentation + */ + +import { ZeroAddress } from 'ethers' + +import type { EVMChain } from '../../../../evm/index.ts' +import type { UnsignedEVMTx } from '../../../../evm/types.ts' +import { ChainFamily } from '../../../../networks.ts' +import { CCTParamsInvalidError } from '../../../errors.ts' +import { EVMOperation } from '../../operation.ts' +import { validateAddress } from '../../validate.ts' +import { LOCKBOX_INTERFACE } from '../interface.ts' + +/** Parameters for {@link AuthorizeLockboxCallers}. At least one caller across both arrays is required. */ +export interface AuthorizeLockboxCallersParams { + /** Address of the `ERC20LockBox` to update. */ + lockbox: string + /** Callers to authorize (e.g. the `LockReleaseTokenPool`); defaults to `[]`. */ + addedCallers?: string[] + /** Callers to deauthorize; defaults to `[]`. */ + removedCallers?: string[] + /** Lockbox owner; sets `tx.from` for offline / multisig signing. */ + sender?: string +} + +/** Applies authorized-caller updates on an `ERC20LockBox` via `applyAuthorizedCallerUpdates`. */ +export class AuthorizeLockboxCallers extends EVMOperation { + readonly name = 'authorizeLockboxCallers' + + /** Validates the lockbox and every caller address; requires at least one caller. */ + protected validate({ + lockbox, + addedCallers = [], + removedCallers = [], + }: AuthorizeLockboxCallersParams): void { + validateAddress(this.name, 'lockbox', lockbox) + if (addedCallers.length + removedCallers.length === 0) { + throw new CCTParamsInvalidError( + this.name, + 'addedCallers', + 'at least one caller must be added or removed', + ) + } + const validateCaller = (field: string, c: string, i: number): void => { + validateAddress(this.name, `${field}[${i}]`, c) + if (c === ZeroAddress) { + throw new CCTParamsInvalidError(this.name, `${field}[${i}]`, 'must not be the zero address') + } + } + addedCallers.forEach((c, i) => validateCaller('addedCallers', c, i)) + removedCallers.forEach((c, i) => validateCaller('removedCallers', c, i)) + } + + /** Builds `applyAuthorizedCallerUpdates` calldata targeting the lockbox. */ + protected buildUnsigned( + _chain: EVMChain, + { lockbox, addedCallers = [], removedCallers = [] }: AuthorizeLockboxCallersParams, + ): UnsignedEVMTx { + const data = LOCKBOX_INTERFACE.encodeFunctionData('applyAuthorizedCallerUpdates', [ + { addedCallers, removedCallers }, + ]) + return { family: ChainFamily.EVM, transactions: [{ to: lockbox, data }] } + } +} From 1bee3c2b329613caf3fc6bfc69c53ba88294dcf4 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Tue, 28 Jul 2026 16:03:54 +0100 Subject: [PATCH 19/22] refactor(cct-sdk): add validateNonZeroAddress + guard single-tx submit --- ccip-sdk/src/cct/evm/submit.ts | 4 +++- ccip-sdk/src/cct/evm/validate.ts | 12 +++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ccip-sdk/src/cct/evm/submit.ts b/ccip-sdk/src/cct/evm/submit.ts index 7e0c8add..35eafa57 100644 --- a/ccip-sdk/src/cct/evm/submit.ts +++ b/ccip-sdk/src/cct/evm/submit.ts @@ -51,7 +51,9 @@ export async function submit( let response: TransactionResponse let nonceConsumed = false try { - let tx: TransactionRequest = { ...unsigned.transactions[0]! } + const [first] = unsigned.transactions + if (!first) throw new CCTTxFailedError(operation, 'no transaction to submit') + let tx: TransactionRequest = { ...first } tx.from = undefined // drop any builder-set sender before populate, else ethers throws on a from/signer mismatch if (tx.nonce == null) { tx.nonce = await chain.nextNonce(sender) diff --git a/ccip-sdk/src/cct/evm/validate.ts b/ccip-sdk/src/cct/evm/validate.ts index 279f2e2a..c47a5735 100644 --- a/ccip-sdk/src/cct/evm/validate.ts +++ b/ccip-sdk/src/cct/evm/validate.ts @@ -5,7 +5,7 @@ * @packageDocumentation */ -import { isAddress } from 'ethers' +import { ZeroAddress, isAddress } from 'ethers' import { CCIPAddressInvalidError } from '../../errors/index.ts' import { ChainFamily } from '../../networks.ts' @@ -29,6 +29,16 @@ export function validateAddress(operation: string, param: string, value: unknown ) } +/** + * Asserts `value` is a valid, non-zero EVM address. + * @throws {@link CCTParamsInvalidError} if `value` is not a valid address, or is the zero address + */ +export function validateNonZeroAddress(operation: string, param: string, value: unknown): void { + validateAddress(operation, param, value) + if (value === ZeroAddress) + throw new CCTParamsInvalidError(operation, param, 'must not be the zero address') +} + /** * Asserts `value` is a non-empty (non-blank) string. * @throws {@link CCTParamsInvalidError} if `value` is not a non-empty string From 56a58f2375c6232ad998e467548e2c6729cf23f6 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Tue, 28 Jul 2026 16:03:59 +0100 Subject: [PATCH 20/22] feat(cct-sdk): EVM deploy verification + unify deploy ops --- ccip-sdk/src/cct/evm/index.ts | 7 +- ccip-sdk/src/cct/evm/lockbox/contracts.ts | 29 +++++ ccip-sdk/src/cct/evm/lockbox/interface.ts | 19 ---- .../lockbox/operations/authorize-callers.ts | 19 ++-- .../lockbox/operations/deploy-lockbox.test.ts | 6 +- .../evm/lockbox/operations/deploy-lockbox.ts | 52 +++------ ccip-sdk/src/cct/evm/operation.ts | 100 ++++++++++++++++-- .../operations/set-pool.ts | 5 +- .../{version.test.ts => contracts.test.ts} | 2 +- .../token-pool/{version.ts => contracts.ts} | 44 +++++++- .../operations/deploy-token-pool.test.ts | 20 +++- .../operations/deploy-token-pool.ts | 85 ++++----------- .../operations/transfer-ownership.ts | 11 +- ccip-sdk/src/cct/evm/token/contracts.ts | 69 ++++++++++++ .../evm/token/operations/deploy-token.test.ts | 15 ++- .../cct/evm/token/operations/deploy-token.ts | 47 ++------ ccip-sdk/src/cct/evm/token/version.ts | 74 ------------- 17 files changed, 330 insertions(+), 274 deletions(-) create mode 100644 ccip-sdk/src/cct/evm/lockbox/contracts.ts delete mode 100644 ccip-sdk/src/cct/evm/lockbox/interface.ts rename ccip-sdk/src/cct/evm/token-pool/{version.test.ts => contracts.test.ts} (99%) rename ccip-sdk/src/cct/evm/token-pool/{version.ts => contracts.ts} (75%) create mode 100644 ccip-sdk/src/cct/evm/token/contracts.ts delete mode 100644 ccip-sdk/src/cct/evm/token/version.ts diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 8cabcb7e..4edd0cc4 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -332,5 +332,10 @@ export type { } from './token-pool/operations/deploy-token-pool.ts' export type { DeployLockboxParams } from './lockbox/operations/deploy-lockbox.ts' export type { AuthorizeLockboxCallersParams } from './lockbox/operations/authorize-callers.ts' -export type { DeployResult, EVMExecuteParams } from './operation.ts' +export type { + DeployArtifact, + DeployResult, + DeployVerification, + EVMExecuteParams, +} from './operation.ts' export type { TransactionResult } from '../operation.ts' diff --git a/ccip-sdk/src/cct/evm/lockbox/contracts.ts b/ccip-sdk/src/cct/evm/lockbox/contracts.ts new file mode 100644 index 00000000..afbe7086 --- /dev/null +++ b/ccip-sdk/src/cct/evm/lockbox/contracts.ts @@ -0,0 +1,29 @@ +/** + * EVM lockbox contract layer for CCT: the cached `ERC20LockBox` {@link Interface} + * ({@link LOCKBOX_INTERFACE}) for calldata encoding, and its deploy artifact + * ({@link getLockboxArtifact}). Only one lockbox version is deployable, so there is no version + * framework here. Mirrors `token/contracts.ts`. + * + * @packageDocumentation + */ + +import { Interface } from 'ethers' + +import ERC20_LOCKBOX_V2_0_0_ABI from '../artifacts/abi/V2_0_0/erc20-lockbox.ts' +import ERC20_LOCKBOX_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/erc20-lockbox.ts' +import type { DeployArtifact } from '../operation.ts' + +/** Shared, cached `ERC20LockBox` interface for constructor and calldata encoding. */ +export const LOCKBOX_INTERFACE = new Interface(ERC20_LOCKBOX_V2_0_0_ABI) + +/** `ERC20LockBox` creation bytecode for `deployLockbox`. */ +export const LOCKBOX_BYTECODE = ERC20_LOCKBOX_V2_0_0_BYTECODE + +/** `ERC20LockBox` deploy artifact: contract name + ctor {@link Interface} + creation bytecode. */ +export function getLockboxArtifact(): DeployArtifact { + return { + contract: 'ERC20LockBox', + iface: LOCKBOX_INTERFACE, + bytecode: LOCKBOX_BYTECODE, + } +} diff --git a/ccip-sdk/src/cct/evm/lockbox/interface.ts b/ccip-sdk/src/cct/evm/lockbox/interface.ts deleted file mode 100644 index 0f0176e3..00000000 --- a/ccip-sdk/src/cct/evm/lockbox/interface.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Deploy artifacts for `ERC20LockBox`: the cached {@link Interface} (constructor + calldata - * encoding) and the creation {@link LOCKBOX_BYTECODE}, built/loaded once from the vendored - * `artifacts/`. Only one lockbox version is deployable, so there is no version framework here — - * ops import these directly. - * - * @packageDocumentation - */ - -import { Interface } from 'ethers' - -import ERC20_LOCKBOX_V2_0_0_ABI from '../artifacts/abi/V2_0_0/erc20-lockbox.ts' -import ERC20_LOCKBOX_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/erc20-lockbox.ts' - -/** Shared, cached `ERC20LockBox` interface for constructor and calldata encoding. */ -export const LOCKBOX_INTERFACE = new Interface(ERC20_LOCKBOX_V2_0_0_ABI) - -/** `ERC20LockBox` creation bytecode for `deployLockbox`. */ -export const LOCKBOX_BYTECODE = ERC20_LOCKBOX_V2_0_0_BYTECODE diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts index fc8a87f2..310daab8 100644 --- a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts +++ b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts @@ -6,15 +6,12 @@ * @packageDocumentation */ -import { ZeroAddress } from 'ethers' - import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' -import { ChainFamily } from '../../../../networks.ts' import { CCTParamsInvalidError } from '../../../errors.ts' -import { EVMOperation } from '../../operation.ts' -import { validateAddress } from '../../validate.ts' -import { LOCKBOX_INTERFACE } from '../interface.ts' +import { EVMOperation, callTx } from '../../operation.ts' +import { validateAddress, validateNonZeroAddress } from '../../validate.ts' +import { LOCKBOX_INTERFACE } from '../contracts.ts' /** Parameters for {@link AuthorizeLockboxCallers}. At least one caller across both arrays is required. */ export interface AuthorizeLockboxCallersParams { @@ -46,12 +43,8 @@ export class AuthorizeLockboxCallers extends EVMOperation { - validateAddress(this.name, `${field}[${i}]`, c) - if (c === ZeroAddress) { - throw new CCTParamsInvalidError(this.name, `${field}[${i}]`, 'must not be the zero address') - } - } + const validateCaller = (field: string, c: string, i: number): void => + validateNonZeroAddress(this.name, `${field}[${i}]`, c) addedCallers.forEach((c, i) => validateCaller('addedCallers', c, i)) removedCallers.forEach((c, i) => validateCaller('removedCallers', c, i)) } @@ -64,6 +57,6 @@ export class AuthorizeLockboxCallers extends EVMOperation { token: TOKEN, wallet: fakeSigner({ contractAddress: DEPLOYED }), }) - assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) + assert.deepEqual(result, { + hash: HASH, + contractAddress: DEPLOYED, + verification: { contract: 'ERC20LockBox', encodedConstructorArgs: '0x' + W_TOKEN }, + }) }) it('throws CCTTxFailedError when the receipt carries no contract address', async () => { diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts index cbfff189..83fdebe8 100644 --- a/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts +++ b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts @@ -7,20 +7,11 @@ * @packageDocumentation */ -import { ZeroAddress } from 'ethers' +import type { Interface } from 'ethers' -import type { EVMChain } from '../../../../evm/index.ts' -import type { UnsignedEVMTx } from '../../../../evm/types.ts' -import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' -import { - type DeployResult, - type EVMExecuteParams, - EVMOperation, - deploymentTx, -} from '../../operation.ts' -import { submit } from '../../submit.ts' -import { validateAddress } from '../../validate.ts' -import { LOCKBOX_BYTECODE, LOCKBOX_INTERFACE } from '../interface.ts' +import { type DeployArtifact, EVMDeployOperation } from '../../operation.ts' +import { validateNonZeroAddress } from '../../validate.ts' +import { getLockboxArtifact } from '../contracts.ts' /** Parameters for {@link DeployLockbox} — deploys `ERC20LockBox` (v2.0.0). */ export interface DeployLockboxParams { @@ -31,40 +22,21 @@ export interface DeployLockboxParams { } /** Deploys an `ERC20LockBox`; `execute` resolves to `{ hash, contractAddress }`. */ -export class DeployLockbox extends EVMOperation { +export class DeployLockbox extends EVMDeployOperation { readonly name = 'deployLockbox' /** Validates the constructor params before building init-code. */ protected validate(params: DeployLockboxParams): void { - validateAddress(this.name, 'token', params.token) - if (params.token === ZeroAddress) - throw new CCTParamsInvalidError(this.name, 'token', 'must not be the zero address') + validateNonZeroAddress(this.name, 'token', params.token) } - /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ - protected buildUnsigned(_chain: EVMChain, params: DeployLockboxParams): UnsignedEVMTx { - return deploymentTx(LOCKBOX_BYTECODE, LOCKBOX_INTERFACE.encodeDeploy([params.token])) + /** Deploy artifact for `ERC20LockBox` (v2.0.0). */ + protected artifact(): DeployArtifact { + return getLockboxArtifact() } - /** - * {@link generate}, then sign and submit; resolves to the tx hash and the newly deployed - * lockbox address (read from the mined receipt). - * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address - */ - override async execute( - chain: EVMChain, - params: EVMExecuteParams, - ): Promise { - const { response, receipt } = await submit( - chain, - params.wallet, - await this.generate(chain, params), - this.name, - ) - if (!receipt.contractAddress) - throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { - context: { txHash: response.hash }, - }) - return { hash: response.hash, contractAddress: receipt.contractAddress } + /** ABI-encodes the `ERC20LockBox` (v2.0.0) constructor args. */ + protected encode(iface: Interface, p: DeployLockboxParams): string { + return iface.encodeDeploy([p.token]) } } diff --git a/ccip-sdk/src/cct/evm/operation.ts b/ccip-sdk/src/cct/evm/operation.ts index d0f29432..94fa6eb0 100644 --- a/ccip-sdk/src/cct/evm/operation.ts +++ b/ccip-sdk/src/cct/evm/operation.ts @@ -1,38 +1,81 @@ /** * EVM {@link Operation} lifecycle: validate → encode → submit. * Concrete ops implement {@link EVMOperation.buildUnsigned}; the base wires - * {@link generate} and {@link execute}. Ops needing more than a tx hash (e.g. a - * deployment's address) override {@link execute}, reusing {@link submit}. + * {@link generate} and {@link execute}. Deployment ops instead extend + * {@link EVMDeployOperation}, supplying a {@link DeployArtifact} and constructor-arg + * encoding while inheriting a deploy-aware {@link execute} that also returns the + * deployed address, reusing {@link submit}. * * @packageDocumentation */ +import type { Interface } from 'ethers' + import type { EVMChain } from '../../evm/index.ts' import type { UnsignedEVMTx } from '../../evm/types.ts' import { ChainFamily } from '../../networks.ts' +import { CCTTxFailedError } from '../errors.ts' import { type ExecuteParams, type TransactionResult, Operation } from '../operation.ts' import { submit } from './submit.ts' import { validateAddress } from './validate.ts' /** Assembles a contract-deployment tx (no `to`): creation bytecode + ABI-encoded ctor args. */ -export function deploymentTx(bytecode: `0x${string}`, ctorArgs: string): UnsignedEVMTx { +export function deployTx(bytecode: `0x${string}`, ctorArgs: string): UnsignedEVMTx { return { family: ChainFamily.EVM, transactions: [{ data: bytecode + ctorArgs.slice(2) }] } } +/** Assembles an unsigned call to an existing contract: `to` + ABI-encoded calldata. */ +export function callTx(to: string, data: string): UnsignedEVMTx { + return { family: ChainFamily.EVM, transactions: [{ to, data }] } +} + +/** Block-explorer verification handle for a deployed contract: its name and ABI-encoded ctor args. */ +export interface DeployVerification { + contract: string + encodedConstructorArgs: string +} + +/** + * Recovers the verification handle from a deployment's init-code with no extra RPC. + * {@link deployTx} builds `data = bytecode + ctorArgs.slice(2)`, so slicing off + * `bytecode.length` chars recovers the (0x-prefixed) ABI-encoded constructor args. + */ +export function buildDeployVerification( + contract: string, + deployData: string, + bytecode: string, +): DeployVerification { + return { contract, encodedConstructorArgs: `0x${deployData.slice(bytecode.length)}` } +} + +/** + * A contract deploy artifact: the contract name (for verification), the cached constructor + * {@link Interface}, and the creation bytecode. Field is `iface` (not `interface`, a reserved word). + */ +export interface DeployArtifact { + contract: string + iface: Interface + bytecode: `0x${string}` +} + /** EVM {@link ExecuteParams} — EVM ops need nothing beyond the signing `wallet`. */ export type EVMExecuteParams

= ExecuteParams

/** * Result of a successful EVM deployment write: the tx hash plus the deployed - * contract address (token, pool, etc.). No block-explorer verification handle - * yet; it's recoverable from the init-code, so adding one later is non-breaking. + * contract address (token, pool, etc.). Also carries a {@link DeployVerification} + * handle (contract name + ABI-encoded ctor args) recovered from the init-code at + * deploy time — additive, so readers of `{ hash, contractAddress }` are unaffected. */ -export type DeployResult = TransactionResult & { contractAddress: string } +export type DeployResult = TransactionResult & { + contractAddress: string + verification: DeployVerification +} /** * EVM CCT write base. Subclasses supply {@link validate} and {@link buildUnsigned}; * {@link execute} signs and submits, returning the confirmed tx hash. Ops that - * resolve to more (e.g. a deployed address) override {@link execute}. + * resolve to more (e.g. a deployed address) extend {@link EVMDeployOperation}. */ export abstract class EVMOperation

extends Operation< EVMChain, @@ -66,3 +109,46 @@ export abstract class EVMOperation

extends Operat return { hash: response.hash } } } + +/** + * EVM contract-deployment base. Subclasses supply {@link validate}, {@link artifact} (name + + * ctor {@link Interface} + creation bytecode), and {@link encode}; the base wires + * {@link buildUnsigned} (init-code = bytecode + encoded ctor args) and {@link execute} (submit, + * then read the deployed address and recover a {@link DeployVerification} from the init-code). + */ +export abstract class EVMDeployOperation

extends EVMOperation

{ + /** Contract name, ctor {@link Interface}, and creation bytecode for this deployment. */ + protected abstract artifact(params: P): DeployArtifact + + /** ABI-encodes the constructor args (0x-prefixed) for this deployment. */ + protected abstract encode(iface: Interface, params: P): string + + /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ + protected buildUnsigned(_chain: EVMChain, params: P): UnsignedEVMTx { + const a = this.artifact(params) + return deployTx(a.bytecode, this.encode(a.iface, params)) + } + + /** + * {@link generate}, then sign and submit; resolves to the tx hash and the newly deployed + * contract address (read from the mined receipt), plus a {@link DeployVerification} handle + * recovered from the init-code. + * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address + */ + override async execute(chain: EVMChain, params: EVMExecuteParams

): Promise { + const unsigned = await this.generate(chain, params) + const data = unsigned.transactions[0]?.data + if (data == null) throw new CCTTxFailedError(this.name, 'deployment tx has no init-code') + const { contract, bytecode } = this.artifact(params) + const { response, receipt } = await submit(chain, params.wallet, unsigned, this.name) + if (!receipt.contractAddress) + throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { + context: { txHash: response.hash }, + }) + return { + hash: response.hash, + contractAddress: receipt.contractAddress, + verification: buildDeployVerification(contract, data, bytecode), + } + } +} diff --git a/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts b/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts index a31f5736..ed48c3ab 100644 --- a/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts +++ b/ccip-sdk/src/cct/evm/token-admin-registry/operations/set-pool.ts @@ -8,8 +8,7 @@ import { interfaces } from '../../../../evm/const.ts' import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' -import { ChainFamily } from '../../../../networks.ts' -import { EVMOperation } from '../../operation.ts' +import { EVMOperation, callTx } from '../../operation.ts' import { validateAddress } from '../../validate.ts' /** Parameters for `setPool`. Zero `poolAddress` delists the token. */ @@ -45,6 +44,6 @@ export class SetPool extends EVMOperation { p.tokenAddress, p.poolAddress, ]) - return { family: ChainFamily.EVM, transactions: [{ to, data }] } + return callTx(to, data) } } diff --git a/ccip-sdk/src/cct/evm/token-pool/version.test.ts b/ccip-sdk/src/cct/evm/token-pool/contracts.test.ts similarity index 99% rename from ccip-sdk/src/cct/evm/token-pool/version.test.ts rename to ccip-sdk/src/cct/evm/token-pool/contracts.test.ts index 48ad8c85..01108172 100644 --- a/ccip-sdk/src/cct/evm/token-pool/version.test.ts +++ b/ccip-sdk/src/cct/evm/token-pool/contracts.test.ts @@ -14,7 +14,7 @@ import { isTokenPoolVersion, parseTokenPoolVersion, resolveEncoder, -} from './version.ts' +} from './contracts.ts' import { CCTContractTypeInvalidError, CCTContractVersionUnsupportedError, diff --git a/ccip-sdk/src/cct/evm/token-pool/version.ts b/ccip-sdk/src/cct/evm/token-pool/contracts.ts similarity index 75% rename from ccip-sdk/src/cct/evm/token-pool/version.ts rename to ccip-sdk/src/cct/evm/token-pool/contracts.ts index 9ac18255..511c59bb 100644 --- a/ccip-sdk/src/cct/evm/token-pool/version.ts +++ b/ccip-sdk/src/cct/evm/token-pool/contracts.ts @@ -1,7 +1,8 @@ /** - * EVM token-pool version axis for CCT: resolve an on-chain pool's type + version - * ({@link resolveTokenPool}), select its cached ABI ({@link getTokenPoolInterface}), and - * floor-match version-keyed encoders ({@link resolveEncoder}). + * EVM token-pool contract layer for CCT: cached {@link Interface}s + on-chain type/version + * resolution ({@link resolveTokenPool}, {@link getTokenPoolInterface}, floor-matched via + * {@link resolveEncoder}) for read/write ops, plus the deployable pools' creation artifacts + * ({@link getTokenPoolArtifact}). Mirrors `token/contracts.ts`. * * @packageDocumentation */ @@ -22,6 +23,11 @@ import BURN_MINT_TOKEN_POOL_V1_6_1_ABI from '../artifacts/abi/V1_6_1/burn-mint-t import LOCK_RELEASE_TOKEN_POOL_V1_6_1_ABI from '../artifacts/abi/V1_6_1/lock-release-token-pool.ts' import BURN_MINT_TOKEN_POOL_V2_0_0_ABI from '../artifacts/abi/V2_0_0/burn-mint-token-pool.ts' import LOCK_RELEASE_TOKEN_POOL_V2_0_0_ABI from '../artifacts/abi/V2_0_0/lock-release-token-pool.ts' +import BURN_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts' +import BURN_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts' +import BURN_WITH_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts' +import LOCK_RELEASE_TOKEN_POOL_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/lock-release-token-pool.ts' +import type { DeployArtifact } from '../operation.ts' /** * ABI families for pool resolution. The burn-* variants are interface-compatible for CCT @@ -150,6 +156,38 @@ export function getTokenPoolInterface(type: TokenPoolType, version: TokenPoolVer return TOKEN_POOL_INTERFACES[getTokenPoolFamily(type)][version] } +/** + * Creation bytecode per deployable pool type (2.0.0 only — pre-2.0.0 bytecode is not vendored). + * The keys define the deployable set ({@link DeployableTokenPoolType}). The burn-* variants share + * the `BurnMint` constructor ABI but are distinct contracts with distinct bytecode. + */ +const TOKEN_POOL_BYTECODE = { + BurnMintTokenPool: BURN_MINT_TOKEN_POOL_V2_0_0_BYTECODE, + BurnFromMintTokenPool: BURN_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, + BurnWithFromMintTokenPool: BURN_WITH_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, + LockReleaseTokenPool: LOCK_RELEASE_TOKEN_POOL_V2_0_0_BYTECODE, +} satisfies Partial> + +/** A pool contract type that can be deployed (has vendored 2.0.0 creation bytecode). */ +export type DeployableTokenPoolType = keyof typeof TOKEN_POOL_BYTECODE + +/** Type guard for {@link DeployableTokenPoolType} (has vendored 2.0.0 creation bytecode). */ +export function isDeployableTokenPoolType(type: string): type is DeployableTokenPoolType { + return Object.hasOwn(TOKEN_POOL_BYTECODE, type) +} + +/** + * Deploy artifact for a deployable pool `type` (v2.0.0): contract name (= `type`), the cached + * constructor {@link Interface}, and the creation bytecode. + */ +export function getTokenPoolArtifact(type: DeployableTokenPoolType): DeployArtifact { + return { + contract: type, + iface: getTokenPoolInterface(type, TokenPoolVersion.V2_0_0), + bytecode: TOKEN_POOL_BYTECODE[type], + } +} + /** * Returns the encoder registered at the greatest version less than or equal to * `version`. One entry per calldata change covers all higher versions via floor-match. diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts index 673e0c91..21576292 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.test.ts @@ -244,9 +244,27 @@ describe('DeployTokenPool (cct/evm token-pool operation)', () => { ...params, wallet: fakeSigner({ contractAddress: DEPLOYED }), }) - assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) + assert.deepEqual(result, { + hash: HASH, + contractAddress: DEPLOYED, + verification: { + contract: 'BurnMintTokenPool', + encodedConstructorArgs: '0x' + BURN_MINT_ARGS, + }, + }) }) + for (const { label, params: caseParams, ctorArgs } of CASES) { + it(`carries the verification handle for ${label}`, async () => { + const result = await new DeployTokenPool().execute(stubChain(), { + ...caseParams, + wallet: fakeSigner({ contractAddress: DEPLOYED }), + }) + assert.equal(result.verification.contract, caseParams.type) + assert.equal(result.verification.encodedConstructorArgs, '0x' + ctorArgs) + }) + } + it('throws CCTTxFailedError when the receipt carries no contract address', async () => { await assert.rejects( () => diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts index 06c18248..7c7b4ee2 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts @@ -8,44 +8,19 @@ import { type Interface, ZeroAddress } from 'ethers' -import type { EVMChain } from '../../../../evm/index.ts' -import type { UnsignedEVMTx } from '../../../../evm/types.ts' -import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' -import BURN_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/burn-from-mint-token-pool.ts' -import BURN_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/burn-mint-token-pool.ts' -import BURN_WITH_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/burn-with-from-mint-token-pool.ts' -import LOCK_RELEASE_TOKEN_POOL_V2_0_0_BYTECODE from '../../artifacts/bytecode/V2_0_0/lock-release-token-pool.ts' -import { - type DeployResult, - type EVMExecuteParams, - EVMOperation, - deploymentTx, -} from '../../operation.ts' -import { submit } from '../../submit.ts' -import { validateAddress, validateUint8 } from '../../validate.ts' +import { CCTParamsInvalidError } from '../../../errors.ts' +import { type DeployArtifact, EVMDeployOperation } from '../../operation.ts' +import { validateAddress, validateNonZeroAddress, validateUint8 } from '../../validate.ts' import { + type DeployableTokenPoolType, type TokenPoolFamily, - type TokenPoolType, - TokenPoolVersion, + getTokenPoolArtifact, getTokenPoolFamily, - getTokenPoolInterface, -} from '../version.ts' - -/** - * Creation bytecode per deployable pool type (2.0.0 only — pre-2.0.0 bytecode is not vendored). - * The keys define the deployable set ({@link DeployableTokenPoolType} derives from them). The - * burn-* variants share the `BurnMint` constructor ABI but are distinct contracts with distinct - * bytecode. - */ -const TOKEN_POOL_BYTECODE = { - BurnMintTokenPool: BURN_MINT_TOKEN_POOL_V2_0_0_BYTECODE, - BurnFromMintTokenPool: BURN_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, - BurnWithFromMintTokenPool: BURN_WITH_FROM_MINT_TOKEN_POOL_V2_0_0_BYTECODE, - LockReleaseTokenPool: LOCK_RELEASE_TOKEN_POOL_V2_0_0_BYTECODE, -} satisfies Partial> + isDeployableTokenPoolType, +} from '../contracts.ts' -/** A pool contract type that can be deployed (has vendored 2.0.0 creation bytecode). */ -export type DeployableTokenPoolType = keyof typeof TOKEN_POOL_BYTECODE +/** Deployable pool types + their creation bytecode/artifact live in `../contracts.ts`. */ +export type { DeployableTokenPoolType } /** Fields shared by every deployable token pool. */ interface DeployTokenPoolBaseParams { @@ -112,7 +87,7 @@ const encodeLockReleaseTokenPool: TokenPoolConstructorEncoder = (iface, p) => ]) /** Deploys a token pool; `execute` resolves to `{ hash, contractAddress }`. */ -export class DeployTokenPool extends EVMOperation { +export class DeployTokenPool extends EVMDeployOperation { readonly name = 'deployTokenPool' /** Constructor encoder per ABI {@link TokenPoolFamily}; `type` narrows to its family. */ @@ -123,7 +98,7 @@ export class DeployTokenPool extends EVMOperation { /** Validates the constructor params before building init-code. */ protected validate(params: DeployTokenPoolParams): void { - if (!Object.hasOwn(TOKEN_POOL_BYTECODE, params.type)) + if (!isDeployableTokenPoolType(params.type)) throw new CCTParamsInvalidError( this.name, 'type', @@ -135,39 +110,17 @@ export class DeployTokenPool extends EVMOperation { validateAddress(this.name, 'router', params.router) if (params.advancedPoolHooks !== undefined) validateAddress(this.name, 'advancedPoolHooks', params.advancedPoolHooks) - if (params.type === 'LockReleaseTokenPool') { - validateAddress(this.name, 'lockbox', params.lockbox) - if (params.lockbox === ZeroAddress) - throw new CCTParamsInvalidError(this.name, 'lockbox', 'must not be the zero address') - } + if (params.type === 'LockReleaseTokenPool') + validateNonZeroAddress(this.name, 'lockbox', params.lockbox) } - /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ - protected buildUnsigned(_chain: EVMChain, params: DeployTokenPoolParams): UnsignedEVMTx { - const iface = getTokenPoolInterface(params.type, TokenPoolVersion.V2_0_0) - const encode = this.encoders[getTokenPoolFamily(params.type)] - return deploymentTx(TOKEN_POOL_BYTECODE[params.type], encode(iface, params)) + /** Deploy artifact for the selected pool `type` (v2.0.0): name + ctor interface + bytecode. */ + protected artifact(p: DeployTokenPoolParams): DeployArtifact { + return getTokenPoolArtifact(p.type) } - /** - * {@link generate}, then sign and submit; resolves to the tx hash and the newly deployed - * pool address (read from the mined receipt). - * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address - */ - override async execute( - chain: EVMChain, - params: EVMExecuteParams, - ): Promise { - const { response, receipt } = await submit( - chain, - params.wallet, - await this.generate(chain, params), - this.name, - ) - if (!receipt.contractAddress) - throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { - context: { txHash: response.hash }, - }) - return { hash: response.hash, contractAddress: receipt.contractAddress } + /** ABI-encodes the pool constructor args via the encoder for the type's ABI family. */ + protected encode(iface: Interface, p: DeployTokenPoolParams): string { + return this.encoders[getTokenPoolFamily(p.type)](iface, p) } } diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts index acf2f604..ae9ce1db 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/transfer-ownership.ts @@ -9,15 +9,14 @@ import type { Interface } from 'ethers' import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' -import { ChainFamily } from '../../../../networks.ts' -import { EVMOperation } from '../../operation.ts' +import { EVMOperation, callTx } from '../../operation.ts' import { validateAddress } from '../../validate.ts' import { TokenPoolVersion, getTokenPoolInterface, resolveEncoder, resolveTokenPool, -} from '../version.ts' +} from '../contracts.ts' /** Parameters for {@link TransferOwnership}. */ export interface TransferOwnershipParams { @@ -30,10 +29,8 @@ export interface TransferOwnershipParams { /** Encodes `transferOwnership` calldata against the resolved pool {@link Interface}. */ type Encoder = (iface: Interface, params: TransferOwnershipParams) => UnsignedEVMTx -const encodeTransferOwnership: Encoder = (iface, { newOwner, poolAddress }) => { - const data = iface.encodeFunctionData('transferOwnership', [newOwner]) - return { family: ChainFamily.EVM, transactions: [{ to: poolAddress, data }] } -} +const encodeTransferOwnership: Encoder = (iface, { newOwner, poolAddress }) => + callTx(poolAddress, iface.encodeFunctionData('transferOwnership', [newOwner])) /** Proposes a new TokenPool owner via Ownable2Step `transferOwnership`. */ export class TransferOwnership extends EVMOperation { diff --git a/ccip-sdk/src/cct/evm/token/contracts.ts b/ccip-sdk/src/cct/evm/token/contracts.ts new file mode 100644 index 00000000..cdd3aa18 --- /dev/null +++ b/ccip-sdk/src/cct/evm/token/contracts.ts @@ -0,0 +1,69 @@ +/** + * EVM token contract layer for CCT: cached {@link Interface}s per {@link TokenVersion} + * ({@link getTokenInterface}) for read/write (e.g. ownership) ops, and the deployable + * `CrossChainToken` (v2.0.0) artifact ({@link getTokenArtifact}). `2.0.0` is `CrossChainToken`; + * `1.5.1` / `1.6.2` are `FactoryBurnMintERC20`. Mirrors `token-pool/contracts.ts`. + * + * @packageDocumentation + */ + +import { Interface } from 'ethers' + +import { CCTContractVersionUnsupportedError } from '../../errors.ts' +import FACTORY_BURN_MINT_ERC20_V1_5_1_ABI from '../artifacts/abi/V1_5_1/factory-burn-mint-erc20.ts' +import FACTORY_BURN_MINT_ERC20_V1_6_2_ABI from '../artifacts/abi/V1_6_2/factory-burn-mint-erc20.ts' +import CROSS_CHAIN_TOKEN_V2_0_0_ABI from '../artifacts/abi/V2_0_0/cross-chain-token.ts' +import CROSS_CHAIN_TOKEN_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/cross-chain-token.ts' +import type { DeployArtifact } from '../operation.ts' + +/** + * Known token versions, low to high. `2.0.0` is `CrossChainToken`; `1.5.1` / `1.6.2` + * are `FactoryBurnMintERC20`. + */ +export const TokenVersion = { + V1_5_1: '1.5.1', + V1_6_2: '1.6.2', + V2_0_0: '2.0.0', +} as const + +/** A known token version. */ +export type TokenVersion = (typeof TokenVersion)[keyof typeof TokenVersion] + +/** + * Cached token {@link Interface}s per {@link TokenVersion}, built once from the vendored ABIs + * (no per-call `new Interface`) — for read/write (e.g. ownership) ops. Mirrors + * `TOKEN_POOL_INTERFACES` in `token-pool/contracts.ts`. + */ +export const TOKEN_INTERFACES: Record = { + [TokenVersion.V1_5_1]: new Interface(FACTORY_BURN_MINT_ERC20_V1_5_1_ABI), + [TokenVersion.V1_6_2]: new Interface(FACTORY_BURN_MINT_ERC20_V1_6_2_ABI), + [TokenVersion.V2_0_0]: new Interface(CROSS_CHAIN_TOKEN_V2_0_0_ABI), +} + +/** Returns the cached token {@link Interface} for `version`. */ +export function getTokenInterface(version: TokenVersion): Interface { + return TOKEN_INTERFACES[version] +} + +/** + * Deploy artifacts ({@link DeployArtifact}: contract name + ctor {@link Interface} + creation + * bytecode) keyed by {@link TokenVersion}, built once; read via {@link getTokenArtifact}. Only + * `2.0.0` (`CrossChainToken`) is deployable. + */ +export const TOKEN_ARTIFACTS: Partial> = { + [TokenVersion.V2_0_0]: { + contract: 'CrossChainToken', + iface: TOKEN_INTERFACES[TokenVersion.V2_0_0], + bytecode: CROSS_CHAIN_TOKEN_V2_0_0_BYTECODE, + }, +} + +/** + * Returns the cached deploy artifact for `version`. + * @throws {@link CCTContractVersionUnsupportedError} if `version` has no vendored deploy bytecode + */ +export function getTokenArtifact(version: TokenVersion): DeployArtifact { + const artifact = TOKEN_ARTIFACTS[version] + if (!artifact) throw new CCTContractVersionUnsupportedError('token', version) + return artifact +} diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts index e8980ca5..f24f6072 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.test.ts @@ -218,7 +218,20 @@ describe('DeployToken (cct/evm)', () => { ...INPUTS, wallet: fakeSigner({ contractAddress: DEPLOYED }), }) - assert.deepEqual(result, { hash: HASH, contractAddress: DEPLOYED }) + assert.deepEqual(result, { + hash: HASH, + contractAddress: DEPLOYED, + verification: { contract: 'CrossChainToken', encodedConstructorArgs: '0x' + CTOR_ARGS }, + }) + }) + + it('carries the verification handle recovered from the init-code', async () => { + const result = await new DeployToken().execute(stubChain(), { + ...INPUTS, + wallet: fakeSigner({ contractAddress: DEPLOYED }), + }) + assert.equal(result.verification.contract, 'CrossChainToken') + assert.equal(result.verification.encodedConstructorArgs, '0x' + CTOR_ARGS) }) it('throws CCTTxFailedError when the receipt carries no contract address', async () => { diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts index dbb0fe5e..200bca7b 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts @@ -7,23 +7,15 @@ import { type Interface, ZeroAddress } from 'ethers' -import type { EVMChain } from '../../../../evm/index.ts' -import type { UnsignedEVMTx } from '../../../../evm/types.ts' -import { CCTParamsInvalidError, CCTTxFailedError } from '../../../errors.ts' -import { - type DeployResult, - type EVMExecuteParams, - EVMOperation, - deploymentTx, -} from '../../operation.ts' -import { submit } from '../../submit.ts' +import { CCTParamsInvalidError } from '../../../errors.ts' +import { type DeployArtifact, EVMDeployOperation } from '../../operation.ts' import { validateAddress, validateNonEmptyString, validateUint256, validateUint8, } from '../../validate.ts' -import { TokenVersion, tokenArtifact } from '../version.ts' +import { TokenVersion, getTokenArtifact } from '../contracts.ts' /** Parameters for {@link DeployToken} — deploys `CrossChainToken` (v2.0.0). */ export interface DeployTokenParams { @@ -64,7 +56,7 @@ function encodeCrossChainToken(iface: Interface, p: DeployTokenParams): string { } /** Deploys a `CrossChainToken`; `execute` resolves to `{ hash, contractAddress }`. */ -export class DeployToken extends EVMOperation { +export class DeployToken extends EVMDeployOperation { readonly name = 'deployToken' /** Validates the constructor params before building init-code. */ @@ -109,32 +101,13 @@ export class DeployToken extends EVMOperation { validateAddress(this.name, 'burnMintRoleAdmin', params.burnMintRoleAdmin) } - /** Builds a deployment tx (no `to`): creation bytecode + ABI-encoded constructor args. */ - protected buildUnsigned(_chain: EVMChain, params: DeployTokenParams): UnsignedEVMTx { - // hardcoded to deploy CrossChainToken 2.0.0 - const { iface, bytecode } = tokenArtifact(TokenVersion.V2_0_0) - return deploymentTx(bytecode, encodeCrossChainToken(iface, params)) + /** Deploy artifact for `CrossChainToken` (v2.0.0). */ + protected artifact(): DeployArtifact { + return getTokenArtifact(TokenVersion.V2_0_0) } - /** - * {@link generate}, then sign and submit; resolves to the tx hash and the newly - * deployed contract address (read from the mined receipt). - * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address - */ - override async execute( - chain: EVMChain, - params: EVMExecuteParams, - ): Promise { - const { response, receipt } = await submit( - chain, - params.wallet, - await this.generate(chain, params), - this.name, - ) - if (!receipt.contractAddress) - throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { - context: { txHash: response.hash }, - }) - return { hash: response.hash, contractAddress: receipt.contractAddress } + /** ABI-encodes the `CrossChainToken` (v2.0.0) constructor args. */ + protected encode(iface: Interface, params: DeployTokenParams): string { + return encodeCrossChainToken(iface, params) } } diff --git a/ccip-sdk/src/cct/evm/token/version.ts b/ccip-sdk/src/cct/evm/token/version.ts deleted file mode 100644 index ae164bb0..00000000 --- a/ccip-sdk/src/cct/evm/token/version.ts +++ /dev/null @@ -1,74 +0,0 @@ -/** - * EVM token version axis for CCT. {@link TokenVersion} + {@link TOKEN_ABIS} cover every - * known token contract so read/write ops can resolve the right interface; - * {@link TOKEN_ARTIFACTS} / {@link tokenArtifact} add creation bytecode. `2.0.0` is - * `CrossChainToken`; `1.5.1` / `1.6.2` are `FactoryBurnMintERC20`. Mirrors - * `token-pool/version.ts`. - * - * @packageDocumentation - */ - -import { type InterfaceAbi, Interface } from 'ethers' - -import { CCTContractVersionUnsupportedError } from '../../errors.ts' -import FACTORY_BURN_MINT_ERC20_V1_5_1_ABI from '../artifacts/abi/V1_5_1/factory-burn-mint-erc20.ts' -import FACTORY_BURN_MINT_ERC20_V1_6_2_ABI from '../artifacts/abi/V1_6_2/factory-burn-mint-erc20.ts' -import CROSS_CHAIN_TOKEN_V2_0_0_ABI from '../artifacts/abi/V2_0_0/cross-chain-token.ts' -import CROSS_CHAIN_TOKEN_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/cross-chain-token.ts' - -/** - * Known token versions, low to high. `2.0.0` is `CrossChainToken`; `1.5.1` / `1.6.2` - * are `FactoryBurnMintERC20`. - */ -export const TokenVersion = { - V1_5_1: '1.5.1', - V1_6_2: '1.6.2', - V2_0_0: '2.0.0', -} as const - -/** A known token version. */ -export type TokenVersion = (typeof TokenVersion)[keyof typeof TokenVersion] - -/** Contract ABI per {@link TokenVersion} — lets read/write ops resolve the right interface. */ -export const TOKEN_ABIS: Record = { - [TokenVersion.V1_5_1]: FACTORY_BURN_MINT_ERC20_V1_5_1_ABI, - [TokenVersion.V1_6_2]: FACTORY_BURN_MINT_ERC20_V1_6_2_ABI, - [TokenVersion.V2_0_0]: CROSS_CHAIN_TOKEN_V2_0_0_ABI, -} - -/** - * Returns the contract ABI for `version`. - * @throws {@link CCTContractVersionUnsupportedError} if `version` has no vendored ABI - */ -export function tokenAbi(version: TokenVersion): InterfaceAbi { - const abi = TOKEN_ABIS[version] - if (!abi) throw new CCTContractVersionUnsupportedError('token', version) - return abi -} - -/** A token deploy artifact: the cached constructor {@link Interface} and creation bytecode. */ -export interface TokenArtifact { - iface: Interface - bytecode: `0x${string}` -} - -/** - * Deploy artifacts (ctor {@link Interface} + creation bytecode) keyed by {@link TokenVersion}, - * built once. Only versions with vendored bytecode appear; read via {@link tokenArtifact}. - */ -export const TOKEN_ARTIFACTS: Partial> = { - [TokenVersion.V2_0_0]: { - iface: new Interface(CROSS_CHAIN_TOKEN_V2_0_0_ABI), - bytecode: CROSS_CHAIN_TOKEN_V2_0_0_BYTECODE, - }, -} - -/** - * Returns the cached deploy artifact for `version`. - * @throws {@link CCTContractVersionUnsupportedError} if `version` has no vendored deploy bytecode - */ -export function tokenArtifact(version: TokenVersion): TokenArtifact { - const artifact = TOKEN_ARTIFACTS[version] - if (!artifact) throw new CCTContractVersionUnsupportedError('token', version) - return artifact -} From 224bceb961e06824728d7ea6c64605abca30ba74 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Fri, 31 Jul 2026 13:35:06 +0100 Subject: [PATCH 21/22] Address PR comments --- ccip-sdk/src/cct/evm/index.ts | 34 ++++++++---- .../operations/authorize-callers.test.ts | 15 ++++++ .../lockbox/operations/authorize-callers.ts | 10 ++-- .../evm/lockbox/operations/deploy-lockbox.ts | 2 +- ccip-sdk/src/cct/evm/operation.ts | 54 ++++++++++--------- ccip-sdk/src/cct/evm/submit.ts | 5 +- .../operations/deploy-token-pool.ts | 2 +- .../cct/evm/token/operations/deploy-token.ts | 2 +- 8 files changed, 79 insertions(+), 45 deletions(-) diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index 4edd0cc4..5d591e45 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -133,7 +133,8 @@ export class EVMTokenManager extends TokenManager { /** * Builds an unsigned `CrossChainToken` (v2.0.0) deployment tx (for multisig / offline * signing). The deployed address is only known once mined, so it is NOT returned here — - * use {@link deployToken} to deploy and receive `{ hash, contractAddress }`. + * use {@link deployToken} to deploy and receive `{ hash, contractAddress, verification }`. + * This path returns the unsigned tx only — no `verification`; see {@link deployToken}. * @remarks Same post-deploy roles caveat as {@link deployToken} — the pool needs * `grantMintAndBurnRoles` before it can bridge. * @throws {@link CCTParamsInvalidError} if any param is invalid @@ -155,7 +156,8 @@ export class EVMTokenManager extends TokenManager { /** * Deploys a `CrossChainToken` (v2.0.0), signing + submitting with `opts.wallet`; resolves - * to the tx hash and the newly deployed token address. + * to the tx hash, the newly deployed token address, and a `verification` + * ({@link ExplorerVerificationInput}) for verifying the source on a block explorer. * @remarks Mint/burn are role-gated (`MINTER_ROLE`/`BURNER_ROLE`); the token grants neither * to any pool at deploy. `preMint` mints initial supply to `preMintRecipient`, but before a * pool can bridge, `burnMintRoleAdmin` must `grantMintAndBurnRoles(pool)`. @@ -164,7 +166,7 @@ export class EVMTokenManager extends TokenManager { * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address * @example * ```typescript - * const { hash, contractAddress } = await cct.deployToken({ + * const { hash, contractAddress, verification } = await cct.deployToken({ * name: 'My Token', * symbol: 'MTK', * decimals: 18, @@ -183,7 +185,8 @@ export class EVMTokenManager extends TokenManager { * the pool contract — a `DeployableTokenPoolType` (`BurnMintTokenPool`, `BurnFromMintTokenPool`, * `BurnWithFromMintTokenPool`, or `LockReleaseTokenPool`; all v2.0.0). The deployed address is * only known once mined, so it is NOT returned here — use {@link deployTokenPool} to receive - * `{ hash, contractAddress }`. + * `{ hash, contractAddress, verification }`. This path returns the unsigned tx only, with no + * `verification`. * @remarks Same post-deploy setup caveat as {@link deployTokenPool} — a fresh pool must be * registered, role-granted, and lane-configured before it can bridge. `LockReleaseTokenPool` * additionally requires a pre-deployed `lockbox` ({@link DeployLockReleaseTokenPoolParams}) @@ -208,8 +211,9 @@ export class EVMTokenManager extends TokenManager { } /** - * Deploys a token pool, signing + submitting with `opts.wallet`; resolves to the tx hash - * and the newly deployed pool address. `type` selects the pool contract (a + * Deploys a token pool, signing + submitting with `opts.wallet`; resolves to the tx hash, the + * newly deployed pool address, and a `verification` ({@link ExplorerVerificationInput}) for + * verifying the source on a block explorer. `type` selects the pool contract (a * `DeployableTokenPoolType`, v2.0.0). * @remarks Deploying the pool alone doesn't make it usable: register it with {@link setPool}, * grant it the token's mint/burn roles (`grantMintAndBurnRoles`), and configure its remote @@ -223,7 +227,7 @@ export class EVMTokenManager extends TokenManager { * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address * @example * ```typescript - * const { hash, contractAddress } = await cct.deployTokenPool({ + * const { hash, contractAddress, verification } = await cct.deployTokenPool({ * type: 'LockReleaseTokenPool', * token: '0xToken...', * localTokenDecimals: 18, @@ -232,6 +236,12 @@ export class EVMTokenManager extends TokenManager { * lockbox: '0xLockbox...', // required for LockReleaseTokenPool; must be a non-zero address * wallet, * }) + * + * // To verify the source on a block explorer, look up `contractAddress` and supply: + * // Contract name: verification.contract ('LockReleaseTokenPool') + * // Constructor Arguments: verification.encodedConstructorArgs, WITHOUT the leading `0x` + * console.log(verification.encodedConstructorArgs.slice(2)) + * // The sources + solc settings are not vendored here; they ship in `@chainlink/contracts-ccip`. * ``` */ deployTokenPool(opts: EVMExecuteParams): Promise { @@ -242,7 +252,8 @@ export class EVMTokenManager extends TokenManager { * Builds an unsigned `ERC20LockBox` (v2.0.0) deployment tx (for multisig / offline signing). * A lockbox escrows a single `token` for `LockReleaseTokenPool`s. The deployed address is * only known once mined, so it is NOT returned here — use {@link deployLockbox} to receive - * `{ hash, contractAddress }`. + * `{ hash, contractAddress, verification }`. This path returns the unsigned tx only, with no + * `verification`. * @remarks Deploy the lockbox before its pool, then authorize the pool on it with * {@link authorizeLockboxCallers} before the pool can lock/release. * @throws {@link CCTParamsInvalidError} if any param is invalid @@ -260,7 +271,8 @@ export class EVMTokenManager extends TokenManager { /** * Deploys an `ERC20LockBox` (v2.0.0), signing + submitting with `opts.wallet`; resolves to the - * tx hash and the newly deployed lockbox address. + * tx hash, the newly deployed lockbox address, and a `verification` + * ({@link ExplorerVerificationInput}) for verifying the source on a block explorer. * @remarks Step two of the lock/release flow: {@link deployToken} → {@link deployLockbox} → * {@link deployTokenPool} (passing this lockbox) → {@link authorizeLockboxCallers} * (`addedCallers: [pool]`) → {@link setPool} → configure lanes. @@ -269,7 +281,7 @@ export class EVMTokenManager extends TokenManager { * @throws {@link CCTTxFailedError} if the tx reverts, fails, or mines without an address * @example * ```typescript - * const { hash, contractAddress } = await cct.deployLockbox({ + * const { hash, contractAddress, verification } = await cct.deployLockbox({ * token: '0xToken...', * wallet, * }) @@ -335,7 +347,7 @@ export type { AuthorizeLockboxCallersParams } from './lockbox/operations/authori export type { DeployArtifact, DeployResult, - DeployVerification, EVMExecuteParams, + ExplorerVerificationInput, } from './operation.ts' export type { TransactionResult } from '../operation.ts' diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts index 2b3d1734..fdb394b6 100644 --- a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts +++ b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts @@ -129,6 +129,21 @@ describe('AuthorizeLockboxCallers (cct/evm lockbox operation)', () => { ) }) + it('rejects a zero-address lockbox', async () => { + // a call to 0x0 hits no code, so it would mine as a successful no-op + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: ZeroAddress, + addedCallers: [POOL], + }), + (err: unknown) => + err instanceof CCTParamsInvalidError && + err.context.operation === 'authorizeLockboxCallers' && + err.context.param === 'lockbox', + ) + }) + it('rejects when no callers are supplied', async () => { await assert.rejects( () => new AuthorizeLockboxCallers().generate(stubChain(), { lockbox: LOCKBOX }), diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts index 310daab8..2c1518ab 100644 --- a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts +++ b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts @@ -10,7 +10,7 @@ import type { EVMChain } from '../../../../evm/index.ts' import type { UnsignedEVMTx } from '../../../../evm/types.ts' import { CCTParamsInvalidError } from '../../../errors.ts' import { EVMOperation, callTx } from '../../operation.ts' -import { validateAddress, validateNonZeroAddress } from '../../validate.ts' +import { validateNonZeroAddress } from '../../validate.ts' import { LOCKBOX_INTERFACE } from '../contracts.ts' /** Parameters for {@link AuthorizeLockboxCallers}. At least one caller across both arrays is required. */ @@ -29,13 +29,17 @@ export interface AuthorizeLockboxCallersParams { export class AuthorizeLockboxCallers extends EVMOperation { readonly name = 'authorizeLockboxCallers' - /** Validates the lockbox and every caller address; requires at least one caller. */ + /** + * Validates the lockbox and every caller address; requires at least one caller. + * @remarks `lockbox` must be non-zero: a call to `0x0` hits no code, so it would mine + * successfully (status 1, no logs) while authorizing nothing. + */ protected validate({ lockbox, addedCallers = [], removedCallers = [], }: AuthorizeLockboxCallersParams): void { - validateAddress(this.name, 'lockbox', lockbox) + validateNonZeroAddress(this.name, 'lockbox', lockbox) if (addedCallers.length + removedCallers.length === 0) { throw new CCTParamsInvalidError( this.name, diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts index 83fdebe8..70309fe4 100644 --- a/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts +++ b/ccip-sdk/src/cct/evm/lockbox/operations/deploy-lockbox.ts @@ -21,7 +21,7 @@ export interface DeployLockboxParams { sender?: string } -/** Deploys an `ERC20LockBox`; `execute` resolves to `{ hash, contractAddress }`. */ +/** Deploys an `ERC20LockBox`; `execute` resolves to `{ hash, contractAddress, verification }`. */ export class DeployLockbox extends EVMDeployOperation { readonly name = 'deployLockbox' diff --git a/ccip-sdk/src/cct/evm/operation.ts b/ccip-sdk/src/cct/evm/operation.ts index 94fa6eb0..79492df4 100644 --- a/ccip-sdk/src/cct/evm/operation.ts +++ b/ccip-sdk/src/cct/evm/operation.ts @@ -29,23 +29,23 @@ export function callTx(to: string, data: string): UnsignedEVMTx { return { family: ChainFamily.EVM, transactions: [{ to, data }] } } -/** Block-explorer verification handle for a deployed contract: its name and ABI-encoded ctor args. */ -export interface DeployVerification { - contract: string - encodedConstructorArgs: string -} - /** - * Recovers the verification handle from a deployment's init-code with no extra RPC. - * {@link deployTx} builds `data = bytecode + ctorArgs.slice(2)`, so slicing off - * `bytecode.length` chars recovers the (0x-prefixed) ABI-encoded constructor args. + * Inputs a block explorer needs to verify a deployed contract's source: the contract name and + * its ABI-encoded constructor args. Captured at deploy time with no extra RPC. + * + * @remarks This is a constructor-args companion, *not* proof of verification — nothing here is + * checked against the chain or submitted anywhere. Completing a verification also needs the + * source/compiler side (standard-json input + matching solc version and settings), which the + * SDK does not vendor; those ship in the `@chainlink/contracts-ccip` npm package. + * + * Etherscan's "Constructor Arguments" field expects {@link encodedConstructorArgs} *without* + * the leading `0x`. */ -export function buildDeployVerification( - contract: string, - deployData: string, - bytecode: string, -): DeployVerification { - return { contract, encodedConstructorArgs: `0x${deployData.slice(bytecode.length)}` } +export interface ExplorerVerificationInput { + /** Contract name as compiled, e.g. `BurnMintTokenPool` — matches the artifact, unqualified. */ + contract: string + /** 0x-prefixed ABI-encoded constructor args (`0x` when the constructor takes none). */ + encodedConstructorArgs: string } /** @@ -63,13 +63,13 @@ export type EVMExecuteParams

= ExecuteParams

/** * Result of a successful EVM deployment write: the tx hash plus the deployed - * contract address (token, pool, etc.). Also carries a {@link DeployVerification} - * handle (contract name + ABI-encoded ctor args) recovered from the init-code at - * deploy time — additive, so readers of `{ hash, contractAddress }` are unaffected. + * contract address (token, pool, etc.). Also carries the + * {@link ExplorerVerificationInput} needed to verify the contract's source on a + * block explorer — additive, so readers of `{ hash, contractAddress }` are unaffected. */ export type DeployResult = TransactionResult & { contractAddress: string - verification: DeployVerification + verification: ExplorerVerificationInput } /** @@ -114,7 +114,7 @@ export abstract class EVMOperation

extends Operat * EVM contract-deployment base. Subclasses supply {@link validate}, {@link artifact} (name + * ctor {@link Interface} + creation bytecode), and {@link encode}; the base wires * {@link buildUnsigned} (init-code = bytecode + encoded ctor args) and {@link execute} (submit, - * then read the deployed address and recover a {@link DeployVerification} from the init-code). + * then read the deployed address and pair it with an {@link ExplorerVerificationInput}). */ export abstract class EVMDeployOperation

extends EVMOperation

{ /** Contract name, ctor {@link Interface}, and creation bytecode for this deployment. */ @@ -131,15 +131,17 @@ export abstract class EVMDeployOperation

extends /** * {@link generate}, then sign and submit; resolves to the tx hash and the newly deployed - * contract address (read from the mined receipt), plus a {@link DeployVerification} handle - * recovered from the init-code. + * contract address (read from the mined receipt), plus the + * {@link ExplorerVerificationInput} for verifying its source on a block explorer. * @throws {@link CCTTxFailedError} if the tx mined without producing a contract address */ override async execute(chain: EVMChain, params: EVMExecuteParams

): Promise { const unsigned = await this.generate(chain, params) - const data = unsigned.transactions[0]?.data - if (data == null) throw new CCTTxFailedError(this.name, 'deployment tx has no init-code') - const { contract, bytecode } = this.artifact(params) + const { contract, iface } = this.artifact(params) + // Same value `buildUnsigned` appended to the creation bytecode. Taking it straight from + // `encode` (rather than slicing it back out of the init-code) keeps this independent of + // the tx layout. + const encodedConstructorArgs = this.encode(iface, params) const { response, receipt } = await submit(chain, params.wallet, unsigned, this.name) if (!receipt.contractAddress) throw new CCTTxFailedError(this.name, 'deployment produced no contract address', { @@ -148,7 +150,7 @@ export abstract class EVMDeployOperation

extends return { hash: response.hash, contractAddress: receipt.contractAddress, - verification: buildDeployVerification(contract, data, bytecode), + verification: { contract, encodedConstructorArgs }, } } } diff --git a/ccip-sdk/src/cct/evm/submit.ts b/ccip-sdk/src/cct/evm/submit.ts index 35eafa57..45c5dc41 100644 --- a/ccip-sdk/src/cct/evm/submit.ts +++ b/ccip-sdk/src/cct/evm/submit.ts @@ -48,11 +48,12 @@ export async function submit( const sender = await wallet.getAddress() chain.logger.debug(`${operation}: submitting...`) + const [first] = unsigned.transactions + if (!first) throw new CCTTxFailedError(operation, 'no transaction to submit') + let response: TransactionResponse let nonceConsumed = false try { - const [first] = unsigned.transactions - if (!first) throw new CCTTxFailedError(operation, 'no transaction to submit') let tx: TransactionRequest = { ...first } tx.from = undefined // drop any builder-set sender before populate, else ethers throws on a from/signer mismatch if (tx.nonce == null) { diff --git a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts index 7c7b4ee2..d35b16c9 100644 --- a/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts +++ b/ccip-sdk/src/cct/evm/token-pool/operations/deploy-token-pool.ts @@ -86,7 +86,7 @@ const encodeLockReleaseTokenPool: TokenPoolConstructorEncoder = (iface, p) => p.type === 'LockReleaseTokenPool' ? p.lockbox : ZeroAddress, ]) -/** Deploys a token pool; `execute` resolves to `{ hash, contractAddress }`. */ +/** Deploys a token pool; `execute` resolves to `{ hash, contractAddress, verification }`. */ export class DeployTokenPool extends EVMDeployOperation { readonly name = 'deployTokenPool' diff --git a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts index 200bca7b..69e2c3d5 100644 --- a/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts +++ b/ccip-sdk/src/cct/evm/token/operations/deploy-token.ts @@ -55,7 +55,7 @@ function encodeCrossChainToken(iface: Interface, p: DeployTokenParams): string { ]) } -/** Deploys a `CrossChainToken`; `execute` resolves to `{ hash, contractAddress }`. */ +/** Deploys a `CrossChainToken`; `execute` resolves to `{ hash, contractAddress, verification }`. */ export class DeployToken extends EVMDeployOperation { readonly name = 'deployToken' From b9ae03e30d83bcb5f71bdf5d7f75008b0d0a32c1 Mon Sep 17 00:00:00 2001 From: Pedro Barbosa Date: Fri, 31 Jul 2026 15:50:25 +0100 Subject: [PATCH 22/22] Review pass --- ccip-sdk/src/cct/evm/index.ts | 7 ++-- ccip-sdk/src/cct/evm/lockbox/interface.ts | 19 ----------- .../operations/authorize-callers.test.ts | 14 +++++++- .../lockbox/operations/authorize-callers.ts | 7 +++- ccip-sdk/src/cct/evm/operation.ts | 32 +++++++++++-------- ccip-sdk/src/cct/evm/validate.ts | 16 +++++++--- 6 files changed, 50 insertions(+), 45 deletions(-) delete mode 100644 ccip-sdk/src/cct/evm/lockbox/interface.ts diff --git a/ccip-sdk/src/cct/evm/index.ts b/ccip-sdk/src/cct/evm/index.ts index acc53d38..a49a0820 100644 --- a/ccip-sdk/src/cct/evm/index.ts +++ b/ccip-sdk/src/cct/evm/index.ts @@ -134,7 +134,6 @@ export class EVMTokenManager extends TokenManager { * Builds an unsigned `CrossChainToken` (v2.0.0) deployment tx (for multisig / offline * signing). The deployed address is only known once mined, so it is NOT returned here — * use {@link deployToken} to deploy and receive `{ hash, contractAddress, verification }`. - * This path returns the unsigned tx only — no `verification`; see {@link deployToken}. * @remarks Same post-deploy roles caveat as {@link deployToken} — the pool needs * `grantMintAndBurnRoles` before it can bridge. * @throws {@link CCTParamsInvalidError} if any param is invalid @@ -185,8 +184,7 @@ export class EVMTokenManager extends TokenManager { * the pool contract — a `DeployableTokenPoolType` (`BurnMintTokenPool`, `BurnFromMintTokenPool`, * `BurnWithFromMintTokenPool`, or `LockReleaseTokenPool`; all v2.0.0). The deployed address is * only known once mined, so it is NOT returned here — use {@link deployTokenPool} to receive - * `{ hash, contractAddress, verification }`. This path returns the unsigned tx only, with no - * `verification`. + * `{ hash, contractAddress, verification }`. * @remarks Same post-deploy setup caveat as {@link deployTokenPool} — a fresh pool must be * registered, role-granted, and lane-configured before it can bridge. `LockReleaseTokenPool` * additionally requires a pre-deployed `lockbox` ({@link DeployLockReleaseTokenPoolParams}) @@ -246,8 +244,7 @@ export class EVMTokenManager extends TokenManager { * Builds an unsigned `ERC20LockBox` (v2.0.0) deployment tx (for multisig / offline signing). * A lockbox escrows a single `token` for `LockReleaseTokenPool`s. The deployed address is * only known once mined, so it is NOT returned here — use {@link deployLockbox} to receive - * `{ hash, contractAddress, verification }`. This path returns the unsigned tx only, with no - * `verification`. + * `{ hash, contractAddress, verification }`. * @remarks Deploy the lockbox before its pool, then authorize the pool on it with * {@link authorizeLockboxCallers} before the pool can lock/release. * @throws {@link CCTParamsInvalidError} if any param is invalid diff --git a/ccip-sdk/src/cct/evm/lockbox/interface.ts b/ccip-sdk/src/cct/evm/lockbox/interface.ts deleted file mode 100644 index 0f0176e3..00000000 --- a/ccip-sdk/src/cct/evm/lockbox/interface.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Deploy artifacts for `ERC20LockBox`: the cached {@link Interface} (constructor + calldata - * encoding) and the creation {@link LOCKBOX_BYTECODE}, built/loaded once from the vendored - * `artifacts/`. Only one lockbox version is deployable, so there is no version framework here — - * ops import these directly. - * - * @packageDocumentation - */ - -import { Interface } from 'ethers' - -import ERC20_LOCKBOX_V2_0_0_ABI from '../artifacts/abi/V2_0_0/erc20-lockbox.ts' -import ERC20_LOCKBOX_V2_0_0_BYTECODE from '../artifacts/bytecode/V2_0_0/erc20-lockbox.ts' - -/** Shared, cached `ERC20LockBox` interface for constructor and calldata encoding. */ -export const LOCKBOX_INTERFACE = new Interface(ERC20_LOCKBOX_V2_0_0_ABI) - -/** `ERC20LockBox` creation bytecode for `deployLockbox`. */ -export const LOCKBOX_BYTECODE = ERC20_LOCKBOX_V2_0_0_BYTECODE diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts index fdb394b6..72b7a585 100644 --- a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts +++ b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict' import { describe, it } from 'node:test' -import { ZeroAddress, makeError } from 'ethers' +import { ZeroAddress, getIcapAddress, makeError } from 'ethers' import { AuthorizeLockboxCallers } from './authorize-callers.ts' import { CCIPExecTxRevertedError, CCIPWalletInvalidError } from '../../../../errors/index.ts' @@ -144,6 +144,18 @@ describe('AuthorizeLockboxCallers (cct/evm lockbox operation)', () => { ) }) + it('rejects the zero address written in ICAP form', async () => { + // isAddress() accepts ICAP, and this never equals ZeroAddress literally + await assert.rejects( + () => + new AuthorizeLockboxCallers().generate(stubChain(), { + lockbox: getIcapAddress(ZeroAddress), + addedCallers: [POOL], + }), + (err: unknown) => err instanceof CCTParamsInvalidError && err.context.param === 'lockbox', + ) + }) + it('rejects when no callers are supplied', async () => { await assert.rejects( () => new AuthorizeLockboxCallers().generate(stubChain(), { lockbox: LOCKBOX }), diff --git a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts index a511cdb6..e2650fc6 100644 --- a/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts +++ b/ccip-sdk/src/cct/evm/lockbox/operations/authorize-callers.ts @@ -13,7 +13,12 @@ import { EVMOperation, callTx } from '../../operation.ts' import { validateNonZeroAddress } from '../../validate.ts' import { LOCKBOX_INTERFACE } from '../contracts.ts' -/** Parameters for {@link AuthorizeLockboxCallers}. At least one caller across both arrays is required. */ +/** + * Parameters for {@link AuthorizeLockboxCallers}. At least one caller across both arrays is required. + * @remarks `AuthorizedCallers._applyAuthorizedCallerUpdates` applies `removedCallers` first, so an + * address in both arrays ends up authorized. The list is a set: re-adding an existing caller is a + * no-op (though `AuthorizedCallerAdded` still fires), and removing an absent one emits nothing. + */ export interface AuthorizeLockboxCallersParams { /** Address of the `ERC20LockBox` to update. */ lockbox: string diff --git a/ccip-sdk/src/cct/evm/operation.ts b/ccip-sdk/src/cct/evm/operation.ts index 79492df4..4dc0b157 100644 --- a/ccip-sdk/src/cct/evm/operation.ts +++ b/ccip-sdk/src/cct/evm/operation.ts @@ -30,21 +30,26 @@ export function callTx(to: string, data: string): UnsignedEVMTx { } /** - * Inputs a block explorer needs to verify a deployed contract's source: the contract name and - * its ABI-encoded constructor args. Captured at deploy time with no extra RPC. + * The deploy-side inputs a block explorer needs to verify a contract's source: its name and + * ABI-encoded constructor args, captured while deploying with no extra RPC. + * @remarks A constructor-args companion, *not* proof of verification — nothing here is read back + * from the chain or submitted anywhere. A full submission also needs the source/compiler side + * (standard-json input plus the matching solc version and settings), which this SDK does not + * vendor; those ship in the `@chainlink/contracts-ccip` package. * - * @remarks This is a constructor-args companion, *not* proof of verification — nothing here is - * checked against the chain or submitted anywhere. Completing a verification also needs the - * source/compiler side (standard-json input + matching solc version and settings), which the - * SDK does not vendor; those ship in the `@chainlink/contracts-ccip` npm package. - * - * Etherscan's "Constructor Arguments" field expects {@link encodedConstructorArgs} *without* - * the leading `0x`. + * Only available from `execute`, which deploys and so learns the address. The + * `generateUnsigned*` builders return the unsigned tx alone. + * @example Verifying on Etherscan, whose "Constructor Arguments" field wants the args bare: + * ```typescript + * const { contractAddress, verification } = await cct.deployTokenPool({ ...params, wallet }) + * console.log(verification.contract) // 'LockReleaseTokenPool' + * console.log(verification.encodedConstructorArgs.slice(2)) // drop the `0x` + * ``` */ export interface ExplorerVerificationInput { - /** Contract name as compiled, e.g. `BurnMintTokenPool` — matches the artifact, unqualified. */ + /** Contract name as compiled, e.g. `BurnMintTokenPool`; unqualified, matching the artifact. */ contract: string - /** 0x-prefixed ABI-encoded constructor args (`0x` when the constructor takes none). */ + /** 0x-prefixed ABI-encoded constructor args, or just `0x` when the constructor takes none. */ encodedConstructorArgs: string } @@ -138,9 +143,8 @@ export abstract class EVMDeployOperation

extends override async execute(chain: EVMChain, params: EVMExecuteParams

): Promise { const unsigned = await this.generate(chain, params) const { contract, iface } = this.artifact(params) - // Same value `buildUnsigned` appended to the creation bytecode. Taking it straight from - // `encode` (rather than slicing it back out of the init-code) keeps this independent of - // the tx layout. + // Same value `buildUnsigned` appended to the bytecode. Taken from `encode` rather than + // sliced back out of the init-code, so it stays correct regardless of the tx layout. const encodedConstructorArgs = this.encode(iface, params) const { response, receipt } = await submit(chain, params.wallet, unsigned, this.name) if (!receipt.contractAddress) diff --git a/ccip-sdk/src/cct/evm/validate.ts b/ccip-sdk/src/cct/evm/validate.ts index c47a5735..5740169a 100644 --- a/ccip-sdk/src/cct/evm/validate.ts +++ b/ccip-sdk/src/cct/evm/validate.ts @@ -5,19 +5,23 @@ * @packageDocumentation */ -import { ZeroAddress, isAddress } from 'ethers' +import { ZeroAddress, getAddress, isAddress } from 'ethers' import { CCIPAddressInvalidError } from '../../errors/index.ts' import { ChainFamily } from '../../networks.ts' import { CCTParamsInvalidError } from '../errors.ts' /** - * Asserts `value` is a valid EVM address. Links the canonical - * {@link CCIPAddressInvalidError} as the `cause`, keeping the + * Asserts `value` is a valid EVM address, narrowing it to `string` for callers. Links the + * canonical {@link CCIPAddressInvalidError} as the `cause`, keeping the * {@link operation}/{@link param} context on top. * @throws {@link CCTParamsInvalidError} if `value` is not a valid address */ -export function validateAddress(operation: string, param: string, value: unknown): void { +export function validateAddress( + operation: string, + param: string, + value: unknown, +): asserts value is string { if (typeof value === 'string' && isAddress(value)) return throw new CCTParamsInvalidError( operation, @@ -31,11 +35,13 @@ export function validateAddress(operation: string, param: string, value: unknown /** * Asserts `value` is a valid, non-zero EVM address. + * @remarks Normalises with `getAddress` first: a literal `=== ZeroAddress` misses the ICAP + * spelling, and a tx to `0x0` hits no code, so it mines as a successful no-op. * @throws {@link CCTParamsInvalidError} if `value` is not a valid address, or is the zero address */ export function validateNonZeroAddress(operation: string, param: string, value: unknown): void { validateAddress(operation, param, value) - if (value === ZeroAddress) + if (getAddress(value) === ZeroAddress) throw new CCTParamsInvalidError(operation, param, 'must not be the zero address') }