From e47ee129e7b036bbba39b6cf87e8f3cc53e7ed65 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 18 Jun 2026 08:37:59 -0400 Subject: [PATCH 1/4] remove cctp v1 --- bindings/bind/compile.go | 10 +- .../usdc_token_pool/usdc_token_pool.go | 3139 ----------------- bindings/generated/function_info.go | 124 +- bindings/mcms_encoder.go | 24 - bindings/mcms_encoder_test.go | 134 - .../usdc_token_pool/usdc_token_pool.go | 100 - .../usdc_token_pool/.gitignore | 1 - .../usdc_token_pool/Move.toml | 34 - .../usdc_token_pool/sources/ownable.move | 273 -- .../usdc_token_pool/sources/rate_limiter.move | 101 - .../usdc_token_pool/sources/token_pool.move | 523 --- .../sources/token_pool_rate_limiter.move | 177 - .../sources/usdc_token_pool.move | 1298 ------- contracts/contracts.go | 2 - .../packages/stablecoin/Move.toml | 30 - .../packages/stablecoin/sources/entry.move | 73 - .../stablecoin/sources/mint_allowance.move | 59 - .../packages/stablecoin/sources/roles.move | 212 -- .../stablecoin/sources/stablecoin.move | 38 - .../packages/stablecoin/sources/treasury.move | 779 ---- .../stablecoin/sources/version_control.move | 38 - .../packages/sui_extensions/Move.toml | 27 - .../sui_extensions/sources/two_step_role.move | 138 - .../sources/upgrade_service.move | 302 -- .../stablecoin-sui/packages/usdc/Move.toml | 33 - .../packages/usdc/sources/usdc.move | 74 - .../packages/message_transmitter/Move.toml | 31 - .../sources/admin/attester_manager.move | 484 --- .../sources/admin/message_size.move | 119 - .../sources/admin/migration.move | 384 -- .../sources/admin/pausable.move | 268 -- .../sources/admin/role_management.move | 344 -- .../sources/admin/roles.move | 108 - .../sources/admin/version_control.move | 76 - .../sources/attestation.move | 344 -- .../message_transmitter/sources/auth.move | 75 - .../sources/initialize.move | 111 - .../sources/message/deserialize.move | 102 - .../sources/message/message.move | 351 -- .../sources/message/serialize.move | 90 - .../sources/receive_message.move | 849 ----- .../sources/send_message.move | 876 ----- .../message_transmitter/sources/state.move | 293 -- .../sources/vector_utils.move | 106 - .../packages/token_messenger_minter/Move.toml | 39 - .../sources/admin/migration.move | 384 -- .../sources/admin/pausable.move | 274 -- .../sources/admin/remote_token_messenger.move | 332 -- .../sources/admin/role_management.move | 340 -- .../sources/admin/roles.move | 140 - .../sources/admin/token_controller.move | 880 ----- .../sources/admin/version_control.move | 76 - .../sources/burn_message.move | 268 -- .../sources/deposit_for_burn.move | 1554 -------- .../sources/handle_receive_message.move | 855 ----- .../sources/initialize.move | 111 - .../message_transmitter_authenticator.move | 31 - .../token_messenger_minter/sources/state.move | 285 -- .../sources/token_utils.move | 50 - .../cs_mcms_execute_ownership_transfer.go | 10 +- .../ops/ccip_usdc_token_pool/op_deploy.go | 185 - .../op_execute_ownership_transfer_to_mcms.go | 95 - .../op_usdc_token_pool.go | 328 -- .../seq_deploy_and_init.go | 155 - .../seq_execute_ownership_transfer_to_mcms.go | 16 - deployment/view/token_pool.go | 4 +- relayer/common/pointer_config.go | 8 - relayer/common/utils.go | 2 - relayer/testutils/onramp.go | 4 - scripts/generate_bindings.sh | 3 - 70 files changed, 66 insertions(+), 19117 deletions(-) delete mode 100644 bindings/generated/ccip/ccip_token_pools/usdc_token_pool/usdc_token_pool.go delete mode 100644 bindings/packages/ccip_token_pools/usdc_token_pool/usdc_token_pool.go delete mode 100644 contracts/ccip/ccip_token_pools/usdc_token_pool/.gitignore delete mode 100644 contracts/ccip/ccip_token_pools/usdc_token_pool/Move.toml delete mode 100644 contracts/ccip/ccip_token_pools/usdc_token_pool/sources/ownable.move delete mode 100644 contracts/ccip/ccip_token_pools/usdc_token_pool/sources/rate_limiter.move delete mode 100644 contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool.move delete mode 100644 contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool_rate_limiter.move delete mode 100644 contracts/ccip/ccip_token_pools/usdc_token_pool/sources/usdc_token_pool.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/Move.toml delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/entry.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/mint_allowance.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/roles.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/stablecoin.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/treasury.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/version_control.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/Move.toml delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/two_step_role.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/upgrade_service.move delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/usdc/Move.toml delete mode 100644 contracts/vendored/circlefin/stablecoin-sui/packages/usdc/sources/usdc.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/Move.toml delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/attester_manager.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/message_size.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/migration.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/pausable.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/role_management.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/roles.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/version_control.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/attestation.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/auth.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/initialize.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/deserialize.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/message.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/serialize.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/receive_message.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/send_message.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/state.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/vector_utils.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/Move.toml delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/migration.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/pausable.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/remote_token_messenger.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/role_management.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/roles.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/token_controller.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/version_control.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/burn_message.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/deposit_for_burn.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/handle_receive_message.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/initialize.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/message_transmitter_authenticator.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/state.move delete mode 100644 contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/token_utils.move delete mode 100644 deployment/ops/ccip_usdc_token_pool/op_deploy.go delete mode 100644 deployment/ops/ccip_usdc_token_pool/op_execute_ownership_transfer_to_mcms.go delete mode 100644 deployment/ops/ccip_usdc_token_pool/op_usdc_token_pool.go delete mode 100644 deployment/ops/ccip_usdc_token_pool/seq_deploy_and_init.go diff --git a/bindings/bind/compile.go b/bindings/bind/compile.go index 49ca87e77..4baf1c069 100644 --- a/bindings/bind/compile.go +++ b/bindings/bind/compile.go @@ -309,7 +309,6 @@ func compilePackageInternal(packageName contracts.Package, namedAddresses map[st filepath.Join(dstRoot, "ccip", "ccip_token_pools", "lock_release_token_pool"), filepath.Join(dstRoot, "ccip", "ccip_token_pools", "burn_mint_token_pool"), filepath.Join(dstRoot, "ccip", "ccip_token_pools", "managed_token_pool"), - filepath.Join(dstRoot, "ccip", "ccip_token_pools", "usdc_token_pool"), } for _, depDir := range commonDependencyDirs { if _, statErr := os.Stat(depDir); statErr == nil { @@ -416,7 +415,7 @@ func compilePackageInternal(packageName contracts.Package, namedAddresses map[st } } - if packageName == contracts.LockReleaseTokenPool || packageName == contracts.BurnMintTokenPool || packageName == contracts.ManagedTokenPool || packageName == contracts.USDCTokenPool { + if packageName == contracts.LockReleaseTokenPool || packageName == contracts.BurnMintTokenPool || packageName == contracts.ManagedTokenPool { mcmsAddr := namedAddresses["mcms"] if !isZeroAddress(mcmsAddr) { mcmsDir := filepath.Join(dstRoot, "mcms", "mcms") @@ -443,9 +442,6 @@ func compilePackageInternal(packageName contracts.Package, namedAddresses map[st case contracts.ManagedTokenPool: originalPkgKey = "original_managed_token_pool_pkg" packageDir = "managed_token_pool" - case contracts.USDCTokenPool: - originalPkgKey = "original_usdc_token_pool_pkg" - packageDir = "usdc_token_pool" } originalAddr := namedAddresses[originalPkgKey] @@ -839,7 +835,7 @@ func ownPackageAddressKey(packageName contracts.Package) string { case contracts.CCIP, contracts.CCIPOnramp, contracts.CCIPOfframp, contracts.CCIPRouter, contracts.CCIPDummyReceiver, contracts.CCIPBrokenReceiver, contracts.LockReleaseTokenPool, contracts.BurnMintTokenPool, - contracts.ManagedTokenPool, contracts.USDCTokenPool, + contracts.ManagedTokenPool, contracts.ManagedToken, contracts.ManagedTokenFaucet, contracts.CCIPBnM, contracts.MCMS, contracts.FastMCMS, contracts.MCMSUser, contracts.MCMSUserV2, contracts.LINK, contracts.MockLinkToken, contracts.MockEthToken, @@ -860,7 +856,7 @@ func requiredPublishDeps(packageName contracts.Package, namedAddresses map[strin case contracts.CCIPOnramp, contracts.CCIPOfframp, contracts.CCIPDummyReceiver, contracts.CCIPBrokenReceiver, contracts.LockReleaseTokenPool, contracts.BurnMintTokenPool, - contracts.ManagedTokenPool, contracts.USDCTokenPool: + contracts.ManagedTokenPool: return []string{ namedAddresses["mcms"], namedAddresses["fast_mcms"], diff --git a/bindings/generated/ccip/ccip_token_pools/usdc_token_pool/usdc_token_pool.go b/bindings/generated/ccip/ccip_token_pools/usdc_token_pool/usdc_token_pool.go deleted file mode 100644 index 67df00572..000000000 --- a/bindings/generated/ccip/ccip_token_pools/usdc_token_pool/usdc_token_pool.go +++ /dev/null @@ -1,3139 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package module_usdc_token_pool - -import ( - "context" - "fmt" - "math/big" - - "github.com/block-vision/sui-go-sdk/models" - - "github.com/smartcontractkit/chainlink-sui/bindings/bind" - "github.com/smartcontractkit/chainlink-sui/relayer/client" -) - -var ( - _ = big.NewInt -) - -const FunctionInfo = `[{"package":"usdc_token_pool","module":"usdc_token_pool","name":"accept_ownership","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"accept_ownership_from_object","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"from","type":"sui::object::UID"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"add_remote_pool","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"remote_chain_selector","type":"u64"},{"name":"remote_pool_address","type":"vector"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"apply_allowlist_updates","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"removes","type":"vector
"},{"name":"adds","type":"vector
"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"apply_chain_updates","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"remote_chain_selectors_to_remove","type":"vector"},{"name":"remote_chain_selectors_to_add","type":"vector"},{"name":"remote_pool_addresses_to_add","type":"vector>>"},{"name":"remote_token_addresses_to_add","type":"vector>"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"destroy_token_pool","parameters":[{"name":"ref","type":"CCIPObjectRef"},{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"execute_ownership_transfer","parameters":[{"name":"owner_cap","type":"OwnerCap"},{"name":"state","type":"USDCTokenPoolState"},{"name":"to","type":"address"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"execute_ownership_transfer_to_mcms","parameters":[{"name":"owner_cap","type":"OwnerCap"},{"name":"state","type":"USDCTokenPoolState"},{"name":"registry","type":"Registry"},{"name":"to","type":"address"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_allowlist","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_allowlist_enabled","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_current_inbound_rate_limiter_state","parameters":[{"name":"clock","type":"Clock"},{"name":"state","type":"USDCTokenPoolState"},{"name":"remote_chain_selector","type":"u64"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_current_outbound_rate_limiter_state","parameters":[{"name":"clock","type":"Clock"},{"name":"state","type":"USDCTokenPoolState"},{"name":"remote_chain_selector","type":"u64"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_domain","parameters":[{"name":"pool","type":"USDCTokenPoolState"},{"name":"chain_selector","type":"u64"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_package_auth_caller","parameters":null},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_remote_pools","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"remote_chain_selector","type":"u64"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_remote_token","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"remote_chain_selector","type":"u64"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_supported_chains","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_token","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"get_token_decimals","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"has_pending_transfer","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"initialize","parameters":[{"name":"owner_cap","type":"OwnerCap"},{"name":"coin_metadata","type":"CoinMetadata"},{"name":"local_domain_identifier","type":"u32"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"is_remote_pool","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"remote_chain_selector","type":"u64"},{"name":"remote_pool_address","type":"vector"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"is_supported_chain","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"remote_chain_selector","type":"u64"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"lock_or_burn","parameters":[{"name":"ref","type":"CCIPObjectRef"},{"name":"token_transfer_params","type":"onramp_sh::TokenTransferParams"},{"name":"c","type":"Coin"},{"name":"remote_chain_selector","type":"u64"},{"name":"clock","type":"Clock"},{"name":"deny_list","type":"DenyList"},{"name":"pool","type":"USDCTokenPoolState"},{"name":"state","type":"MinterState"},{"name":"message_transmitter_state","type":"MessageTransmitterState"},{"name":"treasury","type":"Treasury"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"owner","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"pending_transfer_accepted","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"pending_transfer_from","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"pending_transfer_to","parameters":[{"name":"state","type":"USDCTokenPoolState"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"release_or_mint","parameters":[{"name":"ref","type":"CCIPObjectRef"},{"name":"receiver_params","type":"offramp_sh::ReceiverParams"},{"name":"clock","type":"Clock"},{"name":"deny_list","type":"DenyList"},{"name":"pool","type":"USDCTokenPoolState"},{"name":"state","type":"MinterState"},{"name":"message_transmitter_state","type":"MessageTransmitterState"},{"name":"treasury","type":"Treasury"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"remove_remote_pool","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"remote_chain_selector","type":"u64"},{"name":"remote_pool_address","type":"vector"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"set_allowlist_enabled","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"enabled","type":"bool"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"set_chain_rate_limiter_config","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"clock","type":"Clock"},{"name":"remote_chain_selector","type":"u64"},{"name":"outbound_is_enabled","type":"bool"},{"name":"outbound_capacity","type":"u64"},{"name":"outbound_rate","type":"u64"},{"name":"inbound_is_enabled","type":"bool"},{"name":"inbound_capacity","type":"u64"},{"name":"inbound_rate","type":"u64"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"set_chain_rate_limiter_configs","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"clock","type":"Clock"},{"name":"remote_chain_selectors","type":"vector"},{"name":"outbound_is_enableds","type":"vector"},{"name":"outbound_capacities","type":"vector"},{"name":"outbound_rates","type":"vector"},{"name":"inbound_is_enableds","type":"vector"},{"name":"inbound_capacities","type":"vector"},{"name":"inbound_rates","type":"vector"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"set_domains","parameters":[{"name":"pool","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"remote_chain_selectors","type":"vector"},{"name":"remote_domain_identifiers","type":"vector"},{"name":"allowed_remote_callers","type":"vector>"},{"name":"enableds","type":"vector"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"transfer_ownership","parameters":[{"name":"state","type":"USDCTokenPoolState"},{"name":"owner_cap","type":"OwnerCap"},{"name":"new_owner","type":"address"}]},{"package":"usdc_token_pool","module":"usdc_token_pool","name":"type_and_version","parameters":null}]` - -type IUsdcTokenPool interface { - TypeAndVersion(ctx context.Context, opts *bind.CallOpts) (*models.SuiTransactionBlockResponse, error) - Initialize(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ownerCap bind.Object, coinMetadata bind.Object, localDomainIdentifier uint32) (*models.SuiTransactionBlockResponse, error) - GetToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - GetTokenDecimals(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - GetRemotePools(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) - IsRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*models.SuiTransactionBlockResponse, error) - GetRemoteToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) - AddRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*models.SuiTransactionBlockResponse, error) - RemoveRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*models.SuiTransactionBlockResponse, error) - IsSupportedChain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) - GetSupportedChains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - ApplyChainUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelectorsToRemove []uint64, remoteChainSelectorsToAdd []uint64, remotePoolAddressesToAdd [][][]byte, remoteTokenAddressesToAdd [][]byte) (*models.SuiTransactionBlockResponse, error) - GetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - GetAllowlist(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - SetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, enabled bool) (*models.SuiTransactionBlockResponse, error) - ApplyAllowlistUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, removes []string, adds []string) (*models.SuiTransactionBlockResponse, error) - GetPackageAuthCaller(ctx context.Context, opts *bind.CallOpts, typeArgs []string) (*models.SuiTransactionBlockResponse, error) - LockOrBurn(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, tokenTransferParams bind.Object, c_ bind.Object, remoteChainSelector uint64, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*models.SuiTransactionBlockResponse, error) - ReleaseOrMint(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, receiverParams bind.Object, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*models.SuiTransactionBlockResponse, error) - GetDomain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, chainSelector uint64) (*models.SuiTransactionBlockResponse, error) - SetDomains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, ownerCap bind.Object, remoteChainSelectors []uint64, remoteDomainIdentifiers []uint32, allowedRemoteCallers [][]byte, enableds []bool) (*models.SuiTransactionBlockResponse, error) - McmsSetDomains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - SetChainRateLimiterConfigs(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelectors []uint64, outboundIsEnableds []bool, outboundCapacities []uint64, outboundRates []uint64, inboundIsEnableds []bool, inboundCapacities []uint64, inboundRates []uint64) (*models.SuiTransactionBlockResponse, error) - SetChainRateLimiterConfig(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelector uint64, outboundIsEnabled bool, outboundCapacity uint64, outboundRate uint64, inboundIsEnabled bool, inboundCapacity uint64, inboundRate uint64) (*models.SuiTransactionBlockResponse, error) - GetCurrentInboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) - GetCurrentOutboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) - Owner(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - HasPendingTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - PendingTransferFrom(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - PendingTransferTo(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - PendingTransferAccepted(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - TransferOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, newOwner string) (*models.SuiTransactionBlockResponse, error) - AcceptOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) - AcceptOwnershipFromObject(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, from string) (*models.SuiTransactionBlockResponse, error) - McmsAcceptOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - ExecuteOwnershipTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ownerCap bind.Object, state bind.Object, to string) (*models.SuiTransactionBlockResponse, error) - ExecuteOwnershipTransferToMcms(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ownerCap bind.Object, state bind.Object, registry bind.Object, to string) (*models.SuiTransactionBlockResponse, error) - McmsRegisterUpgradeCap(ctx context.Context, opts *bind.CallOpts, upgradeCap bind.Object, registry bind.Object, state bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsSetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsApplyAllowlistUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsApplyChainUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsAddRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsRemoveRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsSetChainRateLimiterConfigs(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsSetChainRateLimiterConfig(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*models.SuiTransactionBlockResponse, error) - DestroyTokenPool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, state bind.Object, ownerCap bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsDestroyTokenPool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsTransferOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsExecuteOwnershipTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, deployerState bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsAddAllowedModules(ctx context.Context, opts *bind.CallOpts, typeArgs []string, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - McmsRemoveAllowedModules(ctx context.Context, opts *bind.CallOpts, typeArgs []string, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) - DevInspect() IUsdcTokenPoolDevInspect - Encoder() UsdcTokenPoolEncoder - Bound() bind.IBoundContract -} - -type IUsdcTokenPoolDevInspect interface { - TypeAndVersion(ctx context.Context, opts *bind.CallOpts) (string, error) - GetToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (string, error) - GetTokenDecimals(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (byte, error) - GetRemotePools(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) ([][]byte, error) - IsRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) - GetRemoteToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) ([]byte, error) - IsSupportedChain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (bool, error) - GetSupportedChains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) ([]uint64, error) - GetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (bool, error) - GetAllowlist(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) ([]string, error) - GetPackageAuthCaller(ctx context.Context, opts *bind.CallOpts, typeArgs []string) (string, error) - GetDomain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, chainSelector uint64) (Domain, error) - GetCurrentInboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (TokenBucketWrapper, error) - GetCurrentOutboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (TokenBucketWrapper, error) - Owner(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (string, error) - HasPendingTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (bool, error) - PendingTransferFrom(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*string, error) - PendingTransferTo(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*string, error) - PendingTransferAccepted(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*bool, error) -} - -type UsdcTokenPoolEncoder interface { - TypeAndVersion() (*bind.EncodedCall, error) - TypeAndVersionWithArgs(args ...any) (*bind.EncodedCall, error) - Initialize(typeArgs []string, ownerCap bind.Object, coinMetadata bind.Object, localDomainIdentifier uint32) (*bind.EncodedCall, error) - InitializeWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetToken(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - GetTokenWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetTokenDecimals(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - GetTokenDecimalsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetRemotePools(typeArgs []string, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) - GetRemotePoolsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - IsRemotePool(typeArgs []string, state bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*bind.EncodedCall, error) - IsRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetRemoteToken(typeArgs []string, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) - GetRemoteTokenWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - AddRemotePool(typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*bind.EncodedCall, error) - AddRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - RemoveRemotePool(typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*bind.EncodedCall, error) - RemoveRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - IsSupportedChain(typeArgs []string, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) - IsSupportedChainWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetSupportedChains(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - GetSupportedChainsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - ApplyChainUpdates(typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelectorsToRemove []uint64, remoteChainSelectorsToAdd []uint64, remotePoolAddressesToAdd [][][]byte, remoteTokenAddressesToAdd [][]byte) (*bind.EncodedCall, error) - ApplyChainUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetAllowlistEnabled(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - GetAllowlistEnabledWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetAllowlist(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - GetAllowlistWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - SetAllowlistEnabled(typeArgs []string, state bind.Object, ownerCap bind.Object, enabled bool) (*bind.EncodedCall, error) - SetAllowlistEnabledWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - ApplyAllowlistUpdates(typeArgs []string, state bind.Object, ownerCap bind.Object, removes []string, adds []string) (*bind.EncodedCall, error) - ApplyAllowlistUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetPackageAuthCaller(typeArgs []string) (*bind.EncodedCall, error) - GetPackageAuthCallerWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - LockOrBurn(typeArgs []string, ref bind.Object, tokenTransferParams bind.Object, c_ bind.Object, remoteChainSelector uint64, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*bind.EncodedCall, error) - LockOrBurnWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - ReleaseOrMint(typeArgs []string, ref bind.Object, receiverParams bind.Object, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*bind.EncodedCall, error) - ReleaseOrMintWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetDomain(typeArgs []string, pool bind.Object, chainSelector uint64) (*bind.EncodedCall, error) - GetDomainWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - SetDomains(typeArgs []string, pool bind.Object, ownerCap bind.Object, remoteChainSelectors []uint64, remoteDomainIdentifiers []uint32, allowedRemoteCallers [][]byte, enableds []bool) (*bind.EncodedCall, error) - SetDomainsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsSetDomains(typeArgs []string, pool bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsSetDomainsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - SetChainRateLimiterConfigs(typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelectors []uint64, outboundIsEnableds []bool, outboundCapacities []uint64, outboundRates []uint64, inboundIsEnableds []bool, inboundCapacities []uint64, inboundRates []uint64) (*bind.EncodedCall, error) - SetChainRateLimiterConfigsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - SetChainRateLimiterConfig(typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelector uint64, outboundIsEnabled bool, outboundCapacity uint64, outboundRate uint64, inboundIsEnabled bool, inboundCapacity uint64, inboundRate uint64) (*bind.EncodedCall, error) - SetChainRateLimiterConfigWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetCurrentInboundRateLimiterState(typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) - GetCurrentInboundRateLimiterStateWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - GetCurrentOutboundRateLimiterState(typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) - GetCurrentOutboundRateLimiterStateWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - Owner(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - OwnerWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - HasPendingTransfer(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - HasPendingTransferWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - PendingTransferFrom(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - PendingTransferFromWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - PendingTransferTo(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - PendingTransferToWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - PendingTransferAccepted(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - PendingTransferAcceptedWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - TransferOwnership(typeArgs []string, state bind.Object, ownerCap bind.Object, newOwner string) (*bind.EncodedCall, error) - TransferOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - AcceptOwnership(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) - AcceptOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - AcceptOwnershipFromObject(typeArgs []string, state bind.Object, from string) (*bind.EncodedCall, error) - AcceptOwnershipFromObjectWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsAcceptOwnership(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsAcceptOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - ExecuteOwnershipTransfer(typeArgs []string, ownerCap bind.Object, state bind.Object, to string) (*bind.EncodedCall, error) - ExecuteOwnershipTransferWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - ExecuteOwnershipTransferToMcms(typeArgs []string, ownerCap bind.Object, state bind.Object, registry bind.Object, to string) (*bind.EncodedCall, error) - ExecuteOwnershipTransferToMcmsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsRegisterUpgradeCap(upgradeCap bind.Object, registry bind.Object, state bind.Object) (*bind.EncodedCall, error) - McmsRegisterUpgradeCapWithArgs(args ...any) (*bind.EncodedCall, error) - McmsSetAllowlistEnabled(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsSetAllowlistEnabledWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsApplyAllowlistUpdates(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsApplyAllowlistUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsApplyChainUpdates(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsApplyChainUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsAddRemotePool(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsAddRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsRemoveRemotePool(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsRemoveRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsSetChainRateLimiterConfigs(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*bind.EncodedCall, error) - McmsSetChainRateLimiterConfigsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsSetChainRateLimiterConfig(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*bind.EncodedCall, error) - McmsSetChainRateLimiterConfigWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - DestroyTokenPool(typeArgs []string, ref bind.Object, state bind.Object, ownerCap bind.Object) (*bind.EncodedCall, error) - DestroyTokenPoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsDestroyTokenPool(typeArgs []string, ref bind.Object, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsDestroyTokenPoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsTransferOwnership(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsTransferOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsExecuteOwnershipTransfer(typeArgs []string, state bind.Object, registry bind.Object, deployerState bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsExecuteOwnershipTransferWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsAddAllowedModules(typeArgs []string, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsAddAllowedModulesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) - McmsRemoveAllowedModules(typeArgs []string, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) - McmsRemoveAllowedModulesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) -} - -type UsdcTokenPoolContract struct { - *bind.BoundContract - usdcTokenPoolEncoder - devInspect *UsdcTokenPoolDevInspect -} - -type UsdcTokenPoolDevInspect struct { - contract *UsdcTokenPoolContract -} - -var _ IUsdcTokenPool = (*UsdcTokenPoolContract)(nil) -var _ IUsdcTokenPoolDevInspect = (*UsdcTokenPoolDevInspect)(nil) - -func NewUsdcTokenPool(packageID string, chainClient client.BindingsClient) (IUsdcTokenPool, error) { - contract, err := bind.NewBoundContract(packageID, "usdc_token_pool", "usdc_token_pool", chainClient) - if err != nil { - return nil, err - } - - c := &UsdcTokenPoolContract{ - BoundContract: contract, - usdcTokenPoolEncoder: usdcTokenPoolEncoder{BoundContract: contract}, - } - c.devInspect = &UsdcTokenPoolDevInspect{contract: c} - return c, nil -} - -func (c *UsdcTokenPoolContract) Bound() bind.IBoundContract { - return c.BoundContract -} - -func (c *UsdcTokenPoolContract) Encoder() UsdcTokenPoolEncoder { - return c.usdcTokenPoolEncoder -} - -func (c *UsdcTokenPoolContract) DevInspect() IUsdcTokenPoolDevInspect { - return c.devInspect -} - -type USDC_TOKEN_POOL struct { -} - -type USDCTokenPoolObject struct { - Id string `move:"sui::object::UID"` -} - -type USDCTokenPoolStatePointer struct { - Id string `move:"sui::object::UID"` - UsdcTokenPoolObjectId string `move:"address"` -} - -type Domain struct { - AllowedCaller []byte `move:"vector"` - DomainIdentifier uint32 `move:"u32"` - Enabled bool `move:"bool"` -} - -type DomainsSet struct { - AllowedCaller []byte `move:"vector"` - DomainIdentifier uint32 `move:"u32"` - RemoteChainSelector uint64 `move:"u64"` - Enabled bool `move:"bool"` -} - -type USDCTokenPoolState struct { - Id string `move:"sui::object::UID"` - TokenPoolState bind.Object `move:"TokenPoolState"` - ChainToDomain bind.Object `move:"Table"` - LocalDomainIdentifier uint32 `move:"u32"` - OwnableState bind.Object `move:"OwnableState"` -} - -type TokenBucketWrapper struct { - Tokens uint64 `move:"u64"` - LastUpdated uint64 `move:"u64"` - IsEnabled bool `move:"bool"` - Capacity uint64 `move:"u64"` - Rate uint64 `move:"u64"` -} - -type TypeProof struct { -} - -type McmsCallback struct { -} - -type McmsAcceptOwnershipProof struct { -} - -// TypeAndVersion executes the type_and_version Move function. -func (c *UsdcTokenPoolContract) TypeAndVersion(ctx context.Context, opts *bind.CallOpts) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.TypeAndVersion() - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// Initialize executes the initialize Move function. -func (c *UsdcTokenPoolContract) Initialize(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ownerCap bind.Object, coinMetadata bind.Object, localDomainIdentifier uint32) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.Initialize(typeArgs, ownerCap, coinMetadata, localDomainIdentifier) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetToken executes the get_token Move function. -func (c *UsdcTokenPoolContract) GetToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetToken(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetTokenDecimals executes the get_token_decimals Move function. -func (c *UsdcTokenPoolContract) GetTokenDecimals(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetTokenDecimals(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetRemotePools executes the get_remote_pools Move function. -func (c *UsdcTokenPoolContract) GetRemotePools(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetRemotePools(typeArgs, state, remoteChainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// IsRemotePool executes the is_remote_pool Move function. -func (c *UsdcTokenPoolContract) IsRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.IsRemotePool(typeArgs, state, remoteChainSelector, remotePoolAddress) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetRemoteToken executes the get_remote_token Move function. -func (c *UsdcTokenPoolContract) GetRemoteToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetRemoteToken(typeArgs, state, remoteChainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// AddRemotePool executes the add_remote_pool Move function. -func (c *UsdcTokenPoolContract) AddRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.AddRemotePool(typeArgs, state, ownerCap, remoteChainSelector, remotePoolAddress) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// RemoveRemotePool executes the remove_remote_pool Move function. -func (c *UsdcTokenPoolContract) RemoveRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.RemoveRemotePool(typeArgs, state, ownerCap, remoteChainSelector, remotePoolAddress) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// IsSupportedChain executes the is_supported_chain Move function. -func (c *UsdcTokenPoolContract) IsSupportedChain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.IsSupportedChain(typeArgs, state, remoteChainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetSupportedChains executes the get_supported_chains Move function. -func (c *UsdcTokenPoolContract) GetSupportedChains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetSupportedChains(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// ApplyChainUpdates executes the apply_chain_updates Move function. -func (c *UsdcTokenPoolContract) ApplyChainUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelectorsToRemove []uint64, remoteChainSelectorsToAdd []uint64, remotePoolAddressesToAdd [][][]byte, remoteTokenAddressesToAdd [][]byte) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.ApplyChainUpdates(typeArgs, state, ownerCap, remoteChainSelectorsToRemove, remoteChainSelectorsToAdd, remotePoolAddressesToAdd, remoteTokenAddressesToAdd) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetAllowlistEnabled executes the get_allowlist_enabled Move function. -func (c *UsdcTokenPoolContract) GetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetAllowlistEnabled(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetAllowlist executes the get_allowlist Move function. -func (c *UsdcTokenPoolContract) GetAllowlist(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetAllowlist(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// SetAllowlistEnabled executes the set_allowlist_enabled Move function. -func (c *UsdcTokenPoolContract) SetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, enabled bool) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.SetAllowlistEnabled(typeArgs, state, ownerCap, enabled) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// ApplyAllowlistUpdates executes the apply_allowlist_updates Move function. -func (c *UsdcTokenPoolContract) ApplyAllowlistUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, removes []string, adds []string) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.ApplyAllowlistUpdates(typeArgs, state, ownerCap, removes, adds) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetPackageAuthCaller executes the get_package_auth_caller Move function. -func (c *UsdcTokenPoolContract) GetPackageAuthCaller(ctx context.Context, opts *bind.CallOpts, typeArgs []string) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetPackageAuthCaller(typeArgs) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// LockOrBurn executes the lock_or_burn Move function. -func (c *UsdcTokenPoolContract) LockOrBurn(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, tokenTransferParams bind.Object, c_ bind.Object, remoteChainSelector uint64, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.LockOrBurn(typeArgs, ref, tokenTransferParams, c_, remoteChainSelector, clock, denyList, pool, state, messageTransmitterState, treasury) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// ReleaseOrMint executes the release_or_mint Move function. -func (c *UsdcTokenPoolContract) ReleaseOrMint(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, receiverParams bind.Object, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.ReleaseOrMint(typeArgs, ref, receiverParams, clock, denyList, pool, state, messageTransmitterState, treasury) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetDomain executes the get_domain Move function. -func (c *UsdcTokenPoolContract) GetDomain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, chainSelector uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetDomain(typeArgs, pool, chainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// SetDomains executes the set_domains Move function. -func (c *UsdcTokenPoolContract) SetDomains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, ownerCap bind.Object, remoteChainSelectors []uint64, remoteDomainIdentifiers []uint32, allowedRemoteCallers [][]byte, enableds []bool) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.SetDomains(typeArgs, pool, ownerCap, remoteChainSelectors, remoteDomainIdentifiers, allowedRemoteCallers, enableds) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsSetDomains executes the mcms_set_domains Move function. -func (c *UsdcTokenPoolContract) McmsSetDomains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsSetDomains(typeArgs, pool, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// SetChainRateLimiterConfigs executes the set_chain_rate_limiter_configs Move function. -func (c *UsdcTokenPoolContract) SetChainRateLimiterConfigs(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelectors []uint64, outboundIsEnableds []bool, outboundCapacities []uint64, outboundRates []uint64, inboundIsEnableds []bool, inboundCapacities []uint64, inboundRates []uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.SetChainRateLimiterConfigs(typeArgs, state, ownerCap, clock, remoteChainSelectors, outboundIsEnableds, outboundCapacities, outboundRates, inboundIsEnableds, inboundCapacities, inboundRates) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// SetChainRateLimiterConfig executes the set_chain_rate_limiter_config Move function. -func (c *UsdcTokenPoolContract) SetChainRateLimiterConfig(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelector uint64, outboundIsEnabled bool, outboundCapacity uint64, outboundRate uint64, inboundIsEnabled bool, inboundCapacity uint64, inboundRate uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.SetChainRateLimiterConfig(typeArgs, state, ownerCap, clock, remoteChainSelector, outboundIsEnabled, outboundCapacity, outboundRate, inboundIsEnabled, inboundCapacity, inboundRate) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetCurrentInboundRateLimiterState executes the get_current_inbound_rate_limiter_state Move function. -func (c *UsdcTokenPoolContract) GetCurrentInboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetCurrentInboundRateLimiterState(typeArgs, clock, state, remoteChainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// GetCurrentOutboundRateLimiterState executes the get_current_outbound_rate_limiter_state Move function. -func (c *UsdcTokenPoolContract) GetCurrentOutboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.GetCurrentOutboundRateLimiterState(typeArgs, clock, state, remoteChainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// Owner executes the owner Move function. -func (c *UsdcTokenPoolContract) Owner(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.Owner(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// HasPendingTransfer executes the has_pending_transfer Move function. -func (c *UsdcTokenPoolContract) HasPendingTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.HasPendingTransfer(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// PendingTransferFrom executes the pending_transfer_from Move function. -func (c *UsdcTokenPoolContract) PendingTransferFrom(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.PendingTransferFrom(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// PendingTransferTo executes the pending_transfer_to Move function. -func (c *UsdcTokenPoolContract) PendingTransferTo(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.PendingTransferTo(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// PendingTransferAccepted executes the pending_transfer_accepted Move function. -func (c *UsdcTokenPoolContract) PendingTransferAccepted(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.PendingTransferAccepted(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// TransferOwnership executes the transfer_ownership Move function. -func (c *UsdcTokenPoolContract) TransferOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, ownerCap bind.Object, newOwner string) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.TransferOwnership(typeArgs, state, ownerCap, newOwner) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// AcceptOwnership executes the accept_ownership Move function. -func (c *UsdcTokenPoolContract) AcceptOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.AcceptOwnership(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// AcceptOwnershipFromObject executes the accept_ownership_from_object Move function. -func (c *UsdcTokenPoolContract) AcceptOwnershipFromObject(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, from string) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.AcceptOwnershipFromObject(typeArgs, state, from) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsAcceptOwnership executes the mcms_accept_ownership Move function. -func (c *UsdcTokenPoolContract) McmsAcceptOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsAcceptOwnership(typeArgs, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// ExecuteOwnershipTransfer executes the execute_ownership_transfer Move function. -func (c *UsdcTokenPoolContract) ExecuteOwnershipTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ownerCap bind.Object, state bind.Object, to string) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.ExecuteOwnershipTransfer(typeArgs, ownerCap, state, to) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// ExecuteOwnershipTransferToMcms executes the execute_ownership_transfer_to_mcms Move function. -func (c *UsdcTokenPoolContract) ExecuteOwnershipTransferToMcms(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ownerCap bind.Object, state bind.Object, registry bind.Object, to string) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.ExecuteOwnershipTransferToMcms(typeArgs, ownerCap, state, registry, to) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsRegisterUpgradeCap executes the mcms_register_upgrade_cap Move function. -func (c *UsdcTokenPoolContract) McmsRegisterUpgradeCap(ctx context.Context, opts *bind.CallOpts, upgradeCap bind.Object, registry bind.Object, state bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsRegisterUpgradeCap(upgradeCap, registry, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsSetAllowlistEnabled executes the mcms_set_allowlist_enabled Move function. -func (c *UsdcTokenPoolContract) McmsSetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsSetAllowlistEnabled(typeArgs, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsApplyAllowlistUpdates executes the mcms_apply_allowlist_updates Move function. -func (c *UsdcTokenPoolContract) McmsApplyAllowlistUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsApplyAllowlistUpdates(typeArgs, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsApplyChainUpdates executes the mcms_apply_chain_updates Move function. -func (c *UsdcTokenPoolContract) McmsApplyChainUpdates(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsApplyChainUpdates(typeArgs, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsAddRemotePool executes the mcms_add_remote_pool Move function. -func (c *UsdcTokenPoolContract) McmsAddRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsAddRemotePool(typeArgs, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsRemoveRemotePool executes the mcms_remove_remote_pool Move function. -func (c *UsdcTokenPoolContract) McmsRemoveRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsRemoveRemotePool(typeArgs, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsSetChainRateLimiterConfigs executes the mcms_set_chain_rate_limiter_configs Move function. -func (c *UsdcTokenPoolContract) McmsSetChainRateLimiterConfigs(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsSetChainRateLimiterConfigs(typeArgs, state, registry, params, clock) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsSetChainRateLimiterConfig executes the mcms_set_chain_rate_limiter_config Move function. -func (c *UsdcTokenPoolContract) McmsSetChainRateLimiterConfig(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsSetChainRateLimiterConfig(typeArgs, state, registry, params, clock) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// DestroyTokenPool executes the destroy_token_pool Move function. -func (c *UsdcTokenPoolContract) DestroyTokenPool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, state bind.Object, ownerCap bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.DestroyTokenPool(typeArgs, ref, state, ownerCap) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsDestroyTokenPool executes the mcms_destroy_token_pool Move function. -func (c *UsdcTokenPoolContract) McmsDestroyTokenPool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, ref bind.Object, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsDestroyTokenPool(typeArgs, ref, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsTransferOwnership executes the mcms_transfer_ownership Move function. -func (c *UsdcTokenPoolContract) McmsTransferOwnership(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsTransferOwnership(typeArgs, state, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsExecuteOwnershipTransfer executes the mcms_execute_ownership_transfer Move function. -func (c *UsdcTokenPoolContract) McmsExecuteOwnershipTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, registry bind.Object, deployerState bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsExecuteOwnershipTransfer(typeArgs, state, registry, deployerState, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsAddAllowedModules executes the mcms_add_allowed_modules Move function. -func (c *UsdcTokenPoolContract) McmsAddAllowedModules(ctx context.Context, opts *bind.CallOpts, typeArgs []string, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsAddAllowedModules(typeArgs, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// McmsRemoveAllowedModules executes the mcms_remove_allowed_modules Move function. -func (c *UsdcTokenPoolContract) McmsRemoveAllowedModules(ctx context.Context, opts *bind.CallOpts, typeArgs []string, registry bind.Object, params bind.Object) (*models.SuiTransactionBlockResponse, error) { - encoded, err := c.usdcTokenPoolEncoder.McmsRemoveAllowedModules(typeArgs, registry, params) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - - return c.ExecuteTransaction(ctx, opts, encoded) -} - -// TypeAndVersion executes the type_and_version Move function using DevInspect to get return values. -// -// Returns: 0x1::string::String -func (d *UsdcTokenPoolDevInspect) TypeAndVersion(ctx context.Context, opts *bind.CallOpts) (string, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.TypeAndVersion() - if err != nil { - return "", fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return "", err - } - if len(results) == 0 { - return "", fmt.Errorf("no return value") - } - var result string - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return "", fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetToken executes the get_token Move function using DevInspect to get return values. -// -// Returns: address -func (d *UsdcTokenPoolDevInspect) GetToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (string, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetToken(typeArgs, state) - if err != nil { - return "", fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return "", err - } - if len(results) == 0 { - return "", fmt.Errorf("no return value") - } - var result string - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return "", fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetTokenDecimals executes the get_token_decimals Move function using DevInspect to get return values. -// -// Returns: u8 -func (d *UsdcTokenPoolDevInspect) GetTokenDecimals(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (byte, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetTokenDecimals(typeArgs, state) - if err != nil { - return 0, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return 0, err - } - if len(results) == 0 { - return 0, fmt.Errorf("no return value") - } - var result byte - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return 0, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetRemotePools executes the get_remote_pools Move function using DevInspect to get return values. -// -// Returns: vector> -func (d *UsdcTokenPoolDevInspect) GetRemotePools(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) ([][]byte, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetRemotePools(typeArgs, state, remoteChainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return nil, err - } - if len(results) == 0 { - return nil, fmt.Errorf("no return value") - } - var result [][]byte - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return nil, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// IsRemotePool executes the is_remote_pool Move function using DevInspect to get return values. -// -// Returns: bool -func (d *UsdcTokenPoolDevInspect) IsRemotePool(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (bool, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.IsRemotePool(typeArgs, state, remoteChainSelector, remotePoolAddress) - if err != nil { - return false, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return false, err - } - if len(results) == 0 { - return false, fmt.Errorf("no return value") - } - var result bool - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return false, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetRemoteToken executes the get_remote_token Move function using DevInspect to get return values. -// -// Returns: vector -func (d *UsdcTokenPoolDevInspect) GetRemoteToken(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) ([]byte, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetRemoteToken(typeArgs, state, remoteChainSelector) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return nil, err - } - if len(results) == 0 { - return nil, fmt.Errorf("no return value") - } - var result []byte - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return nil, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// IsSupportedChain executes the is_supported_chain Move function using DevInspect to get return values. -// -// Returns: bool -func (d *UsdcTokenPoolDevInspect) IsSupportedChain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object, remoteChainSelector uint64) (bool, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.IsSupportedChain(typeArgs, state, remoteChainSelector) - if err != nil { - return false, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return false, err - } - if len(results) == 0 { - return false, fmt.Errorf("no return value") - } - var result bool - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return false, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetSupportedChains executes the get_supported_chains Move function using DevInspect to get return values. -// -// Returns: vector -func (d *UsdcTokenPoolDevInspect) GetSupportedChains(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) ([]uint64, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetSupportedChains(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return nil, err - } - if len(results) == 0 { - return nil, fmt.Errorf("no return value") - } - var result []uint64 - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return nil, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetAllowlistEnabled executes the get_allowlist_enabled Move function using DevInspect to get return values. -// -// Returns: bool -func (d *UsdcTokenPoolDevInspect) GetAllowlistEnabled(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (bool, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetAllowlistEnabled(typeArgs, state) - if err != nil { - return false, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return false, err - } - if len(results) == 0 { - return false, fmt.Errorf("no return value") - } - var result bool - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return false, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetAllowlist executes the get_allowlist Move function using DevInspect to get return values. -// -// Returns: vector
-func (d *UsdcTokenPoolDevInspect) GetAllowlist(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) ([]string, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetAllowlist(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return nil, err - } - if len(results) == 0 { - return nil, fmt.Errorf("no return value") - } - var result []string - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return nil, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetPackageAuthCaller executes the get_package_auth_caller Move function using DevInspect to get return values. -// -// Returns: address -func (d *UsdcTokenPoolDevInspect) GetPackageAuthCaller(ctx context.Context, opts *bind.CallOpts, typeArgs []string) (string, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetPackageAuthCaller(typeArgs) - if err != nil { - return "", fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return "", err - } - if len(results) == 0 { - return "", fmt.Errorf("no return value") - } - var result string - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return "", fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetDomain executes the get_domain Move function using DevInspect to get return values. -// -// Returns: Domain -func (d *UsdcTokenPoolDevInspect) GetDomain(ctx context.Context, opts *bind.CallOpts, typeArgs []string, pool bind.Object, chainSelector uint64) (Domain, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetDomain(typeArgs, pool, chainSelector) - if err != nil { - return Domain{}, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return Domain{}, err - } - if len(results) == 0 { - return Domain{}, fmt.Errorf("no return value") - } - var result Domain - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return Domain{}, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetCurrentInboundRateLimiterState executes the get_current_inbound_rate_limiter_state Move function using DevInspect to get return values. -// -// Returns: TokenBucketWrapper -func (d *UsdcTokenPoolDevInspect) GetCurrentInboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (TokenBucketWrapper, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetCurrentInboundRateLimiterState(typeArgs, clock, state, remoteChainSelector) - if err != nil { - return TokenBucketWrapper{}, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return TokenBucketWrapper{}, err - } - if len(results) == 0 { - return TokenBucketWrapper{}, fmt.Errorf("no return value") - } - var result TokenBucketWrapper - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return TokenBucketWrapper{}, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// GetCurrentOutboundRateLimiterState executes the get_current_outbound_rate_limiter_state Move function using DevInspect to get return values. -// -// Returns: TokenBucketWrapper -func (d *UsdcTokenPoolDevInspect) GetCurrentOutboundRateLimiterState(ctx context.Context, opts *bind.CallOpts, typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (TokenBucketWrapper, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.GetCurrentOutboundRateLimiterState(typeArgs, clock, state, remoteChainSelector) - if err != nil { - return TokenBucketWrapper{}, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return TokenBucketWrapper{}, err - } - if len(results) == 0 { - return TokenBucketWrapper{}, fmt.Errorf("no return value") - } - var result TokenBucketWrapper - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return TokenBucketWrapper{}, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// Owner executes the owner Move function using DevInspect to get return values. -// -// Returns: address -func (d *UsdcTokenPoolDevInspect) Owner(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (string, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.Owner(typeArgs, state) - if err != nil { - return "", fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return "", err - } - if len(results) == 0 { - return "", fmt.Errorf("no return value") - } - var result string - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return "", fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// HasPendingTransfer executes the has_pending_transfer Move function using DevInspect to get return values. -// -// Returns: bool -func (d *UsdcTokenPoolDevInspect) HasPendingTransfer(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (bool, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.HasPendingTransfer(typeArgs, state) - if err != nil { - return false, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return false, err - } - if len(results) == 0 { - return false, fmt.Errorf("no return value") - } - var result bool - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return false, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// PendingTransferFrom executes the pending_transfer_from Move function using DevInspect to get return values. -// -// Returns: 0x1::option::Option
-func (d *UsdcTokenPoolDevInspect) PendingTransferFrom(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*string, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.PendingTransferFrom(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return nil, err - } - if len(results) == 0 { - return nil, fmt.Errorf("no return value") - } - var result *string - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return nil, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// PendingTransferTo executes the pending_transfer_to Move function using DevInspect to get return values. -// -// Returns: 0x1::option::Option
-func (d *UsdcTokenPoolDevInspect) PendingTransferTo(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*string, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.PendingTransferTo(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return nil, err - } - if len(results) == 0 { - return nil, fmt.Errorf("no return value") - } - var result *string - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return nil, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -// PendingTransferAccepted executes the pending_transfer_accepted Move function using DevInspect to get return values. -// -// Returns: 0x1::option::Option -func (d *UsdcTokenPoolDevInspect) PendingTransferAccepted(ctx context.Context, opts *bind.CallOpts, typeArgs []string, state bind.Object) (*bool, error) { - encoded, err := d.contract.usdcTokenPoolEncoder.PendingTransferAccepted(typeArgs, state) - if err != nil { - return nil, fmt.Errorf("failed to encode function call: %w", err) - } - results, err := d.contract.Call(ctx, opts, encoded) - if err != nil { - return nil, err - } - if len(results) == 0 { - return nil, fmt.Errorf("no return value") - } - var result *bool - if err := bind.DecodeJSONReturn(results[0], &result); err != nil { - return nil, fmt.Errorf("failed to decode return value: %w", err) - } - return result, nil -} - -type usdcTokenPoolEncoder struct { - *bind.BoundContract -} - -// TypeAndVersion encodes a call to the type_and_version Move function. -func (c usdcTokenPoolEncoder) TypeAndVersion() (*bind.EncodedCall, error) { - typeArgsList := []string{} - typeParamsList := []string{} - return c.EncodeCallArgsWithGenerics("type_and_version", typeArgsList, typeParamsList, []string{}, []any{}, []string{ - "0x1::string::String", - }) -} - -// TypeAndVersionWithArgs encodes a call to the type_and_version Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) TypeAndVersionWithArgs(args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{} - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := []string{} - typeParamsList := []string{} - return c.EncodeCallArgsWithGenerics("type_and_version", typeArgsList, typeParamsList, expectedParams, args, []string{ - "0x1::string::String", - }) -} - -// Initialize encodes a call to the initialize Move function. -func (c usdcTokenPoolEncoder) Initialize(typeArgs []string, ownerCap bind.Object, coinMetadata bind.Object, localDomainIdentifier uint32) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("initialize", typeArgsList, typeParamsList, []string{ - "&mut OwnerCap", - "&CoinMetadata", - "u32", - }, []any{ - ownerCap, - coinMetadata, - localDomainIdentifier, - }, nil) -} - -// InitializeWithArgs encodes a call to the initialize Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) InitializeWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut OwnerCap", - "&CoinMetadata", - "u32", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("initialize", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// GetToken encodes a call to the get_token Move function. -func (c usdcTokenPoolEncoder) GetToken(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_token", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "address", - }) -} - -// GetTokenWithArgs encodes a call to the get_token Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetTokenWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_token", typeArgsList, typeParamsList, expectedParams, args, []string{ - "address", - }) -} - -// GetTokenDecimals encodes a call to the get_token_decimals Move function. -func (c usdcTokenPoolEncoder) GetTokenDecimals(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_token_decimals", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "u8", - }) -} - -// GetTokenDecimalsWithArgs encodes a call to the get_token_decimals Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetTokenDecimalsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_token_decimals", typeArgsList, typeParamsList, expectedParams, args, []string{ - "u8", - }) -} - -// GetRemotePools encodes a call to the get_remote_pools Move function. -func (c usdcTokenPoolEncoder) GetRemotePools(typeArgs []string, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_remote_pools", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - "u64", - }, []any{ - state, - remoteChainSelector, - }, []string{ - "vector>", - }) -} - -// GetRemotePoolsWithArgs encodes a call to the get_remote_pools Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetRemotePoolsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - "u64", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_remote_pools", typeArgsList, typeParamsList, expectedParams, args, []string{ - "vector>", - }) -} - -// IsRemotePool encodes a call to the is_remote_pool Move function. -func (c usdcTokenPoolEncoder) IsRemotePool(typeArgs []string, state bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("is_remote_pool", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - "u64", - "vector", - }, []any{ - state, - remoteChainSelector, - remotePoolAddress, - }, []string{ - "bool", - }) -} - -// IsRemotePoolWithArgs encodes a call to the is_remote_pool Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) IsRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - "u64", - "vector", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("is_remote_pool", typeArgsList, typeParamsList, expectedParams, args, []string{ - "bool", - }) -} - -// GetRemoteToken encodes a call to the get_remote_token Move function. -func (c usdcTokenPoolEncoder) GetRemoteToken(typeArgs []string, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_remote_token", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - "u64", - }, []any{ - state, - remoteChainSelector, - }, []string{ - "vector", - }) -} - -// GetRemoteTokenWithArgs encodes a call to the get_remote_token Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetRemoteTokenWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - "u64", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_remote_token", typeArgsList, typeParamsList, expectedParams, args, []string{ - "vector", - }) -} - -// AddRemotePool encodes a call to the add_remote_pool Move function. -func (c usdcTokenPoolEncoder) AddRemotePool(typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("add_remote_pool", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "u64", - "vector", - }, []any{ - state, - ownerCap, - remoteChainSelector, - remotePoolAddress, - }, nil) -} - -// AddRemotePoolWithArgs encodes a call to the add_remote_pool Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) AddRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "u64", - "vector", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("add_remote_pool", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// RemoveRemotePool encodes a call to the remove_remote_pool Move function. -func (c usdcTokenPoolEncoder) RemoveRemotePool(typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelector uint64, remotePoolAddress []byte) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("remove_remote_pool", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "u64", - "vector", - }, []any{ - state, - ownerCap, - remoteChainSelector, - remotePoolAddress, - }, nil) -} - -// RemoveRemotePoolWithArgs encodes a call to the remove_remote_pool Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) RemoveRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "u64", - "vector", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("remove_remote_pool", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// IsSupportedChain encodes a call to the is_supported_chain Move function. -func (c usdcTokenPoolEncoder) IsSupportedChain(typeArgs []string, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("is_supported_chain", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - "u64", - }, []any{ - state, - remoteChainSelector, - }, []string{ - "bool", - }) -} - -// IsSupportedChainWithArgs encodes a call to the is_supported_chain Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) IsSupportedChainWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - "u64", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("is_supported_chain", typeArgsList, typeParamsList, expectedParams, args, []string{ - "bool", - }) -} - -// GetSupportedChains encodes a call to the get_supported_chains Move function. -func (c usdcTokenPoolEncoder) GetSupportedChains(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_supported_chains", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "vector", - }) -} - -// GetSupportedChainsWithArgs encodes a call to the get_supported_chains Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetSupportedChainsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_supported_chains", typeArgsList, typeParamsList, expectedParams, args, []string{ - "vector", - }) -} - -// ApplyChainUpdates encodes a call to the apply_chain_updates Move function. -func (c usdcTokenPoolEncoder) ApplyChainUpdates(typeArgs []string, state bind.Object, ownerCap bind.Object, remoteChainSelectorsToRemove []uint64, remoteChainSelectorsToAdd []uint64, remotePoolAddressesToAdd [][][]byte, remoteTokenAddressesToAdd [][]byte) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("apply_chain_updates", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "vector", - "vector", - "vector>>", - "vector>", - }, []any{ - state, - ownerCap, - remoteChainSelectorsToRemove, - remoteChainSelectorsToAdd, - remotePoolAddressesToAdd, - remoteTokenAddressesToAdd, - }, nil) -} - -// ApplyChainUpdatesWithArgs encodes a call to the apply_chain_updates Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) ApplyChainUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "vector", - "vector", - "vector>>", - "vector>", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("apply_chain_updates", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// GetAllowlistEnabled encodes a call to the get_allowlist_enabled Move function. -func (c usdcTokenPoolEncoder) GetAllowlistEnabled(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_allowlist_enabled", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "bool", - }) -} - -// GetAllowlistEnabledWithArgs encodes a call to the get_allowlist_enabled Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetAllowlistEnabledWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_allowlist_enabled", typeArgsList, typeParamsList, expectedParams, args, []string{ - "bool", - }) -} - -// GetAllowlist encodes a call to the get_allowlist Move function. -func (c usdcTokenPoolEncoder) GetAllowlist(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_allowlist", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "vector
", - }) -} - -// GetAllowlistWithArgs encodes a call to the get_allowlist Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetAllowlistWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_allowlist", typeArgsList, typeParamsList, expectedParams, args, []string{ - "vector
", - }) -} - -// SetAllowlistEnabled encodes a call to the set_allowlist_enabled Move function. -func (c usdcTokenPoolEncoder) SetAllowlistEnabled(typeArgs []string, state bind.Object, ownerCap bind.Object, enabled bool) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_allowlist_enabled", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "bool", - }, []any{ - state, - ownerCap, - enabled, - }, nil) -} - -// SetAllowlistEnabledWithArgs encodes a call to the set_allowlist_enabled Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) SetAllowlistEnabledWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "bool", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_allowlist_enabled", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// ApplyAllowlistUpdates encodes a call to the apply_allowlist_updates Move function. -func (c usdcTokenPoolEncoder) ApplyAllowlistUpdates(typeArgs []string, state bind.Object, ownerCap bind.Object, removes []string, adds []string) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("apply_allowlist_updates", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "vector
", - "vector
", - }, []any{ - state, - ownerCap, - removes, - adds, - }, nil) -} - -// ApplyAllowlistUpdatesWithArgs encodes a call to the apply_allowlist_updates Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) ApplyAllowlistUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "vector
", - "vector
", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("apply_allowlist_updates", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// GetPackageAuthCaller encodes a call to the get_package_auth_caller Move function. -func (c usdcTokenPoolEncoder) GetPackageAuthCaller(typeArgs []string) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "TypeProof", - } - return c.EncodeCallArgsWithGenerics("get_package_auth_caller", typeArgsList, typeParamsList, []string{}, []any{}, []string{ - "address", - }) -} - -// GetPackageAuthCallerWithArgs encodes a call to the get_package_auth_caller Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetPackageAuthCallerWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{} - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "TypeProof", - } - return c.EncodeCallArgsWithGenerics("get_package_auth_caller", typeArgsList, typeParamsList, expectedParams, args, []string{ - "address", - }) -} - -// LockOrBurn encodes a call to the lock_or_burn Move function. -func (c usdcTokenPoolEncoder) LockOrBurn(typeArgs []string, ref bind.Object, tokenTransferParams bind.Object, c_ bind.Object, remoteChainSelector uint64, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("lock_or_burn", typeArgsList, typeParamsList, []string{ - "&CCIPObjectRef", - "&mut onramp_sh::TokenTransferParams", - "Coin", - "u64", - "&Clock", - "&DenyList", - "&mut USDCTokenPoolState", - "&MinterState", - "&mut MessageTransmitterState", - "&mut Treasury", - }, []any{ - ref, - tokenTransferParams, - c_, - remoteChainSelector, - clock, - denyList, - pool, - state, - messageTransmitterState, - treasury, - }, nil) -} - -// LockOrBurnWithArgs encodes a call to the lock_or_burn Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) LockOrBurnWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&CCIPObjectRef", - "&mut onramp_sh::TokenTransferParams", - "Coin", - "u64", - "&Clock", - "&DenyList", - "&mut USDCTokenPoolState", - "&MinterState", - "&mut MessageTransmitterState", - "&mut Treasury", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("lock_or_burn", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// ReleaseOrMint encodes a call to the release_or_mint Move function. -func (c usdcTokenPoolEncoder) ReleaseOrMint(typeArgs []string, ref bind.Object, receiverParams bind.Object, clock bind.Object, denyList bind.Object, pool bind.Object, state bind.Object, messageTransmitterState bind.Object, treasury bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("release_or_mint", typeArgsList, typeParamsList, []string{ - "&CCIPObjectRef", - "&mut offramp_sh::ReceiverParams", - "&Clock", - "&DenyList", - "&mut USDCTokenPoolState", - "&mut MinterState", - "&mut MessageTransmitterState", - "&mut Treasury", - }, []any{ - ref, - receiverParams, - clock, - denyList, - pool, - state, - messageTransmitterState, - treasury, - }, nil) -} - -// ReleaseOrMintWithArgs encodes a call to the release_or_mint Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) ReleaseOrMintWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&CCIPObjectRef", - "&mut offramp_sh::ReceiverParams", - "&Clock", - "&DenyList", - "&mut USDCTokenPoolState", - "&mut MinterState", - "&mut MessageTransmitterState", - "&mut Treasury", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("release_or_mint", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// GetDomain encodes a call to the get_domain Move function. -func (c usdcTokenPoolEncoder) GetDomain(typeArgs []string, pool bind.Object, chainSelector uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_domain", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - "u64", - }, []any{ - pool, - chainSelector, - }, []string{ - "usdc_token_pool::usdc_token_pool::Domain", - }) -} - -// GetDomainWithArgs encodes a call to the get_domain Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetDomainWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - "u64", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_domain", typeArgsList, typeParamsList, expectedParams, args, []string{ - "usdc_token_pool::usdc_token_pool::Domain", - }) -} - -// SetDomains encodes a call to the set_domains Move function. -func (c usdcTokenPoolEncoder) SetDomains(typeArgs []string, pool bind.Object, ownerCap bind.Object, remoteChainSelectors []uint64, remoteDomainIdentifiers []uint32, allowedRemoteCallers [][]byte, enableds []bool) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_domains", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "vector", - "vector", - "vector>", - "vector", - }, []any{ - pool, - ownerCap, - remoteChainSelectors, - remoteDomainIdentifiers, - allowedRemoteCallers, - enableds, - }, nil) -} - -// SetDomainsWithArgs encodes a call to the set_domains Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) SetDomainsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "vector", - "vector", - "vector>", - "vector", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_domains", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsSetDomains encodes a call to the mcms_set_domains Move function. -func (c usdcTokenPoolEncoder) McmsSetDomains(typeArgs []string, pool bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_domains", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - pool, - registry, - params, - }, nil) -} - -// McmsSetDomainsWithArgs encodes a call to the mcms_set_domains Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsSetDomainsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_domains", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// SetChainRateLimiterConfigs encodes a call to the set_chain_rate_limiter_configs Move function. -func (c usdcTokenPoolEncoder) SetChainRateLimiterConfigs(typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelectors []uint64, outboundIsEnableds []bool, outboundCapacities []uint64, outboundRates []uint64, inboundIsEnableds []bool, inboundCapacities []uint64, inboundRates []uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_chain_rate_limiter_configs", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "&Clock", - "vector", - "vector", - "vector", - "vector", - "vector", - "vector", - "vector", - }, []any{ - state, - ownerCap, - clock, - remoteChainSelectors, - outboundIsEnableds, - outboundCapacities, - outboundRates, - inboundIsEnableds, - inboundCapacities, - inboundRates, - }, nil) -} - -// SetChainRateLimiterConfigsWithArgs encodes a call to the set_chain_rate_limiter_configs Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) SetChainRateLimiterConfigsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "&Clock", - "vector", - "vector", - "vector", - "vector", - "vector", - "vector", - "vector", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_chain_rate_limiter_configs", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// SetChainRateLimiterConfig encodes a call to the set_chain_rate_limiter_config Move function. -func (c usdcTokenPoolEncoder) SetChainRateLimiterConfig(typeArgs []string, state bind.Object, ownerCap bind.Object, clock bind.Object, remoteChainSelector uint64, outboundIsEnabled bool, outboundCapacity uint64, outboundRate uint64, inboundIsEnabled bool, inboundCapacity uint64, inboundRate uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_chain_rate_limiter_config", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "&Clock", - "u64", - "bool", - "u64", - "u64", - "bool", - "u64", - "u64", - }, []any{ - state, - ownerCap, - clock, - remoteChainSelector, - outboundIsEnabled, - outboundCapacity, - outboundRate, - inboundIsEnabled, - inboundCapacity, - inboundRate, - }, nil) -} - -// SetChainRateLimiterConfigWithArgs encodes a call to the set_chain_rate_limiter_config Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) SetChainRateLimiterConfigWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "&Clock", - "u64", - "bool", - "u64", - "u64", - "bool", - "u64", - "u64", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("set_chain_rate_limiter_config", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// GetCurrentInboundRateLimiterState encodes a call to the get_current_inbound_rate_limiter_state Move function. -func (c usdcTokenPoolEncoder) GetCurrentInboundRateLimiterState(typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_current_inbound_rate_limiter_state", typeArgsList, typeParamsList, []string{ - "&Clock", - "&USDCTokenPoolState", - "u64", - }, []any{ - clock, - state, - remoteChainSelector, - }, []string{ - "usdc_token_pool::usdc_token_pool::TokenBucketWrapper", - }) -} - -// GetCurrentInboundRateLimiterStateWithArgs encodes a call to the get_current_inbound_rate_limiter_state Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetCurrentInboundRateLimiterStateWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&Clock", - "&USDCTokenPoolState", - "u64", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_current_inbound_rate_limiter_state", typeArgsList, typeParamsList, expectedParams, args, []string{ - "usdc_token_pool::usdc_token_pool::TokenBucketWrapper", - }) -} - -// GetCurrentOutboundRateLimiterState encodes a call to the get_current_outbound_rate_limiter_state Move function. -func (c usdcTokenPoolEncoder) GetCurrentOutboundRateLimiterState(typeArgs []string, clock bind.Object, state bind.Object, remoteChainSelector uint64) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_current_outbound_rate_limiter_state", typeArgsList, typeParamsList, []string{ - "&Clock", - "&USDCTokenPoolState", - "u64", - }, []any{ - clock, - state, - remoteChainSelector, - }, []string{ - "usdc_token_pool::usdc_token_pool::TokenBucketWrapper", - }) -} - -// GetCurrentOutboundRateLimiterStateWithArgs encodes a call to the get_current_outbound_rate_limiter_state Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) GetCurrentOutboundRateLimiterStateWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&Clock", - "&USDCTokenPoolState", - "u64", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("get_current_outbound_rate_limiter_state", typeArgsList, typeParamsList, expectedParams, args, []string{ - "usdc_token_pool::usdc_token_pool::TokenBucketWrapper", - }) -} - -// Owner encodes a call to the owner Move function. -func (c usdcTokenPoolEncoder) Owner(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("owner", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "address", - }) -} - -// OwnerWithArgs encodes a call to the owner Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) OwnerWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("owner", typeArgsList, typeParamsList, expectedParams, args, []string{ - "address", - }) -} - -// HasPendingTransfer encodes a call to the has_pending_transfer Move function. -func (c usdcTokenPoolEncoder) HasPendingTransfer(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("has_pending_transfer", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "bool", - }) -} - -// HasPendingTransferWithArgs encodes a call to the has_pending_transfer Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) HasPendingTransferWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("has_pending_transfer", typeArgsList, typeParamsList, expectedParams, args, []string{ - "bool", - }) -} - -// PendingTransferFrom encodes a call to the pending_transfer_from Move function. -func (c usdcTokenPoolEncoder) PendingTransferFrom(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("pending_transfer_from", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "0x1::option::Option
", - }) -} - -// PendingTransferFromWithArgs encodes a call to the pending_transfer_from Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) PendingTransferFromWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("pending_transfer_from", typeArgsList, typeParamsList, expectedParams, args, []string{ - "0x1::option::Option
", - }) -} - -// PendingTransferTo encodes a call to the pending_transfer_to Move function. -func (c usdcTokenPoolEncoder) PendingTransferTo(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("pending_transfer_to", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "0x1::option::Option
", - }) -} - -// PendingTransferToWithArgs encodes a call to the pending_transfer_to Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) PendingTransferToWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("pending_transfer_to", typeArgsList, typeParamsList, expectedParams, args, []string{ - "0x1::option::Option
", - }) -} - -// PendingTransferAccepted encodes a call to the pending_transfer_accepted Move function. -func (c usdcTokenPoolEncoder) PendingTransferAccepted(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("pending_transfer_accepted", typeArgsList, typeParamsList, []string{ - "&USDCTokenPoolState", - }, []any{ - state, - }, []string{ - "0x1::option::Option", - }) -} - -// PendingTransferAcceptedWithArgs encodes a call to the pending_transfer_accepted Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) PendingTransferAcceptedWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("pending_transfer_accepted", typeArgsList, typeParamsList, expectedParams, args, []string{ - "0x1::option::Option", - }) -} - -// TransferOwnership encodes a call to the transfer_ownership Move function. -func (c usdcTokenPoolEncoder) TransferOwnership(typeArgs []string, state bind.Object, ownerCap bind.Object, newOwner string) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("transfer_ownership", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "address", - }, []any{ - state, - ownerCap, - newOwner, - }, nil) -} - -// TransferOwnershipWithArgs encodes a call to the transfer_ownership Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) TransferOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&OwnerCap", - "address", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("transfer_ownership", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// AcceptOwnership encodes a call to the accept_ownership Move function. -func (c usdcTokenPoolEncoder) AcceptOwnership(typeArgs []string, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("accept_ownership", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - }, []any{ - state, - }, nil) -} - -// AcceptOwnershipWithArgs encodes a call to the accept_ownership Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) AcceptOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("accept_ownership", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// AcceptOwnershipFromObject encodes a call to the accept_ownership_from_object Move function. -func (c usdcTokenPoolEncoder) AcceptOwnershipFromObject(typeArgs []string, state bind.Object, from string) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("accept_ownership_from_object", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut UID", - }, []any{ - state, - from, - }, nil) -} - -// AcceptOwnershipFromObjectWithArgs encodes a call to the accept_ownership_from_object Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) AcceptOwnershipFromObjectWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut UID", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("accept_ownership_from_object", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsAcceptOwnership encodes a call to the mcms_accept_ownership Move function. -func (c usdcTokenPoolEncoder) McmsAcceptOwnership(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_accept_ownership", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - params, - }, nil) -} - -// McmsAcceptOwnershipWithArgs encodes a call to the mcms_accept_ownership Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsAcceptOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_accept_ownership", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// ExecuteOwnershipTransfer encodes a call to the execute_ownership_transfer Move function. -func (c usdcTokenPoolEncoder) ExecuteOwnershipTransfer(typeArgs []string, ownerCap bind.Object, state bind.Object, to string) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("execute_ownership_transfer", typeArgsList, typeParamsList, []string{ - "OwnerCap", - "&mut USDCTokenPoolState", - "address", - }, []any{ - ownerCap, - state, - to, - }, nil) -} - -// ExecuteOwnershipTransferWithArgs encodes a call to the execute_ownership_transfer Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) ExecuteOwnershipTransferWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "OwnerCap", - "&mut USDCTokenPoolState", - "address", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("execute_ownership_transfer", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// ExecuteOwnershipTransferToMcms encodes a call to the execute_ownership_transfer_to_mcms Move function. -func (c usdcTokenPoolEncoder) ExecuteOwnershipTransferToMcms(typeArgs []string, ownerCap bind.Object, state bind.Object, registry bind.Object, to string) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("execute_ownership_transfer_to_mcms", typeArgsList, typeParamsList, []string{ - "OwnerCap", - "&mut USDCTokenPoolState", - "&mut Registry", - "address", - }, []any{ - ownerCap, - state, - registry, - to, - }, nil) -} - -// ExecuteOwnershipTransferToMcmsWithArgs encodes a call to the execute_ownership_transfer_to_mcms Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) ExecuteOwnershipTransferToMcmsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "OwnerCap", - "&mut USDCTokenPoolState", - "&mut Registry", - "address", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("execute_ownership_transfer_to_mcms", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsRegisterUpgradeCap encodes a call to the mcms_register_upgrade_cap Move function. -func (c usdcTokenPoolEncoder) McmsRegisterUpgradeCap(upgradeCap bind.Object, registry bind.Object, state bind.Object) (*bind.EncodedCall, error) { - typeArgsList := []string{} - typeParamsList := []string{} - return c.EncodeCallArgsWithGenerics("mcms_register_upgrade_cap", typeArgsList, typeParamsList, []string{ - "UpgradeCap", - "&mut Registry", - "&mut DeployerState", - }, []any{ - upgradeCap, - registry, - state, - }, nil) -} - -// McmsRegisterUpgradeCapWithArgs encodes a call to the mcms_register_upgrade_cap Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsRegisterUpgradeCapWithArgs(args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "UpgradeCap", - "&mut Registry", - "&mut DeployerState", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := []string{} - typeParamsList := []string{} - return c.EncodeCallArgsWithGenerics("mcms_register_upgrade_cap", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsSetAllowlistEnabled encodes a call to the mcms_set_allowlist_enabled Move function. -func (c usdcTokenPoolEncoder) McmsSetAllowlistEnabled(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_allowlist_enabled", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - params, - }, nil) -} - -// McmsSetAllowlistEnabledWithArgs encodes a call to the mcms_set_allowlist_enabled Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsSetAllowlistEnabledWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_allowlist_enabled", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsApplyAllowlistUpdates encodes a call to the mcms_apply_allowlist_updates Move function. -func (c usdcTokenPoolEncoder) McmsApplyAllowlistUpdates(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_apply_allowlist_updates", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - params, - }, nil) -} - -// McmsApplyAllowlistUpdatesWithArgs encodes a call to the mcms_apply_allowlist_updates Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsApplyAllowlistUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_apply_allowlist_updates", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsApplyChainUpdates encodes a call to the mcms_apply_chain_updates Move function. -func (c usdcTokenPoolEncoder) McmsApplyChainUpdates(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_apply_chain_updates", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - params, - }, nil) -} - -// McmsApplyChainUpdatesWithArgs encodes a call to the mcms_apply_chain_updates Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsApplyChainUpdatesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_apply_chain_updates", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsAddRemotePool encodes a call to the mcms_add_remote_pool Move function. -func (c usdcTokenPoolEncoder) McmsAddRemotePool(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_add_remote_pool", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - params, - }, nil) -} - -// McmsAddRemotePoolWithArgs encodes a call to the mcms_add_remote_pool Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsAddRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_add_remote_pool", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsRemoveRemotePool encodes a call to the mcms_remove_remote_pool Move function. -func (c usdcTokenPoolEncoder) McmsRemoveRemotePool(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_remove_remote_pool", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - params, - }, nil) -} - -// McmsRemoveRemotePoolWithArgs encodes a call to the mcms_remove_remote_pool Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsRemoveRemotePoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_remove_remote_pool", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsSetChainRateLimiterConfigs encodes a call to the mcms_set_chain_rate_limiter_configs Move function. -func (c usdcTokenPoolEncoder) McmsSetChainRateLimiterConfigs(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_chain_rate_limiter_configs", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - "&Clock", - }, []any{ - state, - registry, - params, - clock, - }, nil) -} - -// McmsSetChainRateLimiterConfigsWithArgs encodes a call to the mcms_set_chain_rate_limiter_configs Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsSetChainRateLimiterConfigsWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - "&Clock", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_chain_rate_limiter_configs", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsSetChainRateLimiterConfig encodes a call to the mcms_set_chain_rate_limiter_config Move function. -func (c usdcTokenPoolEncoder) McmsSetChainRateLimiterConfig(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object, clock bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_chain_rate_limiter_config", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - "&Clock", - }, []any{ - state, - registry, - params, - clock, - }, nil) -} - -// McmsSetChainRateLimiterConfigWithArgs encodes a call to the mcms_set_chain_rate_limiter_config Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsSetChainRateLimiterConfigWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - "&Clock", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_set_chain_rate_limiter_config", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// DestroyTokenPool encodes a call to the destroy_token_pool Move function. -func (c usdcTokenPoolEncoder) DestroyTokenPool(typeArgs []string, ref bind.Object, state bind.Object, ownerCap bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("destroy_token_pool", typeArgsList, typeParamsList, []string{ - "&mut CCIPObjectRef", - "USDCTokenPoolState", - "OwnerCap", - }, []any{ - ref, - state, - ownerCap, - }, nil) -} - -// DestroyTokenPoolWithArgs encodes a call to the destroy_token_pool Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) DestroyTokenPoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut CCIPObjectRef", - "USDCTokenPoolState", - "OwnerCap", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("destroy_token_pool", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsDestroyTokenPool encodes a call to the mcms_destroy_token_pool Move function. -func (c usdcTokenPoolEncoder) McmsDestroyTokenPool(typeArgs []string, ref bind.Object, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_destroy_token_pool", typeArgsList, typeParamsList, []string{ - "&mut CCIPObjectRef", - "USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - ref, - state, - registry, - params, - }, nil) -} - -// McmsDestroyTokenPoolWithArgs encodes a call to the mcms_destroy_token_pool Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsDestroyTokenPoolWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut CCIPObjectRef", - "USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_destroy_token_pool", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsTransferOwnership encodes a call to the mcms_transfer_ownership Move function. -func (c usdcTokenPoolEncoder) McmsTransferOwnership(typeArgs []string, state bind.Object, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_transfer_ownership", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - params, - }, nil) -} - -// McmsTransferOwnershipWithArgs encodes a call to the mcms_transfer_ownership Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsTransferOwnershipWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_transfer_ownership", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsExecuteOwnershipTransfer encodes a call to the mcms_execute_ownership_transfer Move function. -func (c usdcTokenPoolEncoder) McmsExecuteOwnershipTransfer(typeArgs []string, state bind.Object, registry bind.Object, deployerState bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_execute_ownership_transfer", typeArgsList, typeParamsList, []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "&mut DeployerState", - "ExecutingCallbackParams", - }, []any{ - state, - registry, - deployerState, - params, - }, nil) -} - -// McmsExecuteOwnershipTransferWithArgs encodes a call to the mcms_execute_ownership_transfer Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsExecuteOwnershipTransferWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut USDCTokenPoolState", - "&mut Registry", - "&mut DeployerState", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_execute_ownership_transfer", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsAddAllowedModules encodes a call to the mcms_add_allowed_modules Move function. -func (c usdcTokenPoolEncoder) McmsAddAllowedModules(typeArgs []string, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_add_allowed_modules", typeArgsList, typeParamsList, []string{ - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - registry, - params, - }, nil) -} - -// McmsAddAllowedModulesWithArgs encodes a call to the mcms_add_allowed_modules Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsAddAllowedModulesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_add_allowed_modules", typeArgsList, typeParamsList, expectedParams, args, nil) -} - -// McmsRemoveAllowedModules encodes a call to the mcms_remove_allowed_modules Move function. -func (c usdcTokenPoolEncoder) McmsRemoveAllowedModules(typeArgs []string, registry bind.Object, params bind.Object) (*bind.EncodedCall, error) { - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_remove_allowed_modules", typeArgsList, typeParamsList, []string{ - "&mut Registry", - "ExecutingCallbackParams", - }, []any{ - registry, - params, - }, nil) -} - -// McmsRemoveAllowedModulesWithArgs encodes a call to the mcms_remove_allowed_modules Move function using arbitrary arguments. -// This method allows passing both regular values and transaction.Argument values for PTB chaining. -func (c usdcTokenPoolEncoder) McmsRemoveAllowedModulesWithArgs(typeArgs []string, args ...any) (*bind.EncodedCall, error) { - expectedParams := []string{ - "&mut Registry", - "ExecutingCallbackParams", - } - - if len(args) != len(expectedParams) { - return nil, fmt.Errorf("expected %d arguments, got %d", len(expectedParams), len(args)) - } - typeArgsList := typeArgs - typeParamsList := []string{ - "T", - } - return c.EncodeCallArgsWithGenerics("mcms_remove_allowed_modules", typeArgsList, typeParamsList, expectedParams, args, nil) -} diff --git a/bindings/generated/function_info.go b/bindings/generated/function_info.go index 6d6cf36e0..c1f3561b5 100644 --- a/bindings/generated/function_info.go +++ b/bindings/generated/function_info.go @@ -3,69 +3,67 @@ package generated import ( - module_fee_quoter "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/fee_quoter" - module_nonce_manager "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/nonce_manager" - module_offramp_state_helper "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/offramp_state_helper" - module_receiver_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/receiver_registry" - module_rmn_remote "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/rmn_remote" - module_state_object "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/state_object" - module_token_admin_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/token_admin_registry" - module_upgrade_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/upgrade_registry" - module_ccip_burn_mint_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_burn_mint_token/ccip_burn_mint_token" - module_dummy_receiver "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_dummy_receiver/ccip_dummy_receiver" - module_offramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_offramp/offramp" - module_onramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/onramp" - module_ownable "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/ownable" - module_router "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_router" - module_burn_mint_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/burn_mint_token_pool" - module_lock_release_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/lock_release_token_pool" - module_managed_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/managed_token_pool" - module_usdc_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/usdc_token_pool" - module_managed_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token/managed_token" - module_faucet "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token_faucet/managed_token_faucet" - module_mock_eth_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_eth_token/mock_eth_token" - module_mock_link_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_link_token/mock_link_token" - module_link "github.com/smartcontractkit/chainlink-sui/bindings/generated/link/link" - module_mcms "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms" - module_mcms_account "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_account" - module_mcms_deployer "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_deployer" - module_mcms_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_registry" - module_mcms_user "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_user" - module_complex "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/complex" - module_counter "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/counter" - module_generics "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/generics" + module_fee_quoter "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/fee_quoter" + module_nonce_manager "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/nonce_manager" + module_offramp_state_helper "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/offramp_state_helper" + module_receiver_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/receiver_registry" + module_rmn_remote "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/rmn_remote" + module_state_object "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/state_object" + module_token_admin_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/token_admin_registry" + module_upgrade_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/upgrade_registry" + module_ccip_burn_mint_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_burn_mint_token/ccip_burn_mint_token" + module_dummy_receiver "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_dummy_receiver/ccip_dummy_receiver" + module_offramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_offramp/offramp" + module_onramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/onramp" + module_ownable "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/ownable" + module_router "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_router" + module_burn_mint_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/burn_mint_token_pool" + module_lock_release_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/lock_release_token_pool" + module_managed_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/managed_token_pool" + module_managed_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token/managed_token" + module_faucet "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token_faucet/managed_token_faucet" + module_mock_eth_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_eth_token/mock_eth_token" + module_mock_link_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_link_token/mock_link_token" + module_link "github.com/smartcontractkit/chainlink-sui/bindings/generated/link/link" + module_mcms "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms" + module_mcms_account "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_account" + module_mcms_deployer "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_deployer" + module_mcms_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_registry" + module_mcms_user "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_user" + module_complex "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/complex" + module_counter "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/counter" + module_generics "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/generics" ) var FunctionInfoByModule = map[string]string{ - "fee_quoter": module_fee_quoter.FunctionInfo, - "nonce_manager": module_nonce_manager.FunctionInfo, - "offramp_state_helper": module_offramp_state_helper.FunctionInfo, - "receiver_registry": module_receiver_registry.FunctionInfo, - "rmn_remote": module_rmn_remote.FunctionInfo, - "state_object": module_state_object.FunctionInfo, - "token_admin_registry": module_token_admin_registry.FunctionInfo, - "upgrade_registry": module_upgrade_registry.FunctionInfo, - "ccip_burn_mint_token": module_ccip_burn_mint_token.FunctionInfo, - "dummy_receiver": module_dummy_receiver.FunctionInfo, - "offramp": module_offramp.FunctionInfo, - "onramp": module_onramp.FunctionInfo, - "ownable": module_ownable.FunctionInfo, - "router": module_router.FunctionInfo, - "burn_mint_token_pool": module_burn_mint_token_pool.FunctionInfo, - "lock_release_token_pool": module_lock_release_token_pool.FunctionInfo, - "managed_token_pool": module_managed_token_pool.FunctionInfo, - "usdc_token_pool": module_usdc_token_pool.FunctionInfo, - "managed_token": module_managed_token.FunctionInfo, - "faucet": module_faucet.FunctionInfo, - "mock_eth_token": module_mock_eth_token.FunctionInfo, - "mock_link_token": module_mock_link_token.FunctionInfo, - "link": module_link.FunctionInfo, - "mcms": module_mcms.FunctionInfo, - "mcms_account": module_mcms_account.FunctionInfo, - "mcms_deployer": module_mcms_deployer.FunctionInfo, - "mcms_registry": module_mcms_registry.FunctionInfo, - "mcms_user": module_mcms_user.FunctionInfo, - "complex": module_complex.FunctionInfo, - "counter": module_counter.FunctionInfo, - "generics": module_generics.FunctionInfo, -} \ No newline at end of file + "fee_quoter": module_fee_quoter.FunctionInfo, + "nonce_manager": module_nonce_manager.FunctionInfo, + "offramp_state_helper": module_offramp_state_helper.FunctionInfo, + "receiver_registry": module_receiver_registry.FunctionInfo, + "rmn_remote": module_rmn_remote.FunctionInfo, + "state_object": module_state_object.FunctionInfo, + "token_admin_registry": module_token_admin_registry.FunctionInfo, + "upgrade_registry": module_upgrade_registry.FunctionInfo, + "ccip_burn_mint_token": module_ccip_burn_mint_token.FunctionInfo, + "dummy_receiver": module_dummy_receiver.FunctionInfo, + "offramp": module_offramp.FunctionInfo, + "onramp": module_onramp.FunctionInfo, + "ownable": module_ownable.FunctionInfo, + "router": module_router.FunctionInfo, + "burn_mint_token_pool": module_burn_mint_token_pool.FunctionInfo, + "lock_release_token_pool": module_lock_release_token_pool.FunctionInfo, + "managed_token_pool": module_managed_token_pool.FunctionInfo, + "managed_token": module_managed_token.FunctionInfo, + "faucet": module_faucet.FunctionInfo, + "mock_eth_token": module_mock_eth_token.FunctionInfo, + "mock_link_token": module_mock_link_token.FunctionInfo, + "link": module_link.FunctionInfo, + "mcms": module_mcms.FunctionInfo, + "mcms_account": module_mcms_account.FunctionInfo, + "mcms_deployer": module_mcms_deployer.FunctionInfo, + "mcms_registry": module_mcms_registry.FunctionInfo, + "mcms_user": module_mcms_user.FunctionInfo, + "complex": module_complex.FunctionInfo, + "counter": module_counter.FunctionInfo, + "generics": module_generics.FunctionInfo, +} diff --git a/bindings/mcms_encoder.go b/bindings/mcms_encoder.go index ef170ce75..02efc575c 100644 --- a/bindings/mcms_encoder.go +++ b/bindings/mcms_encoder.go @@ -18,7 +18,6 @@ import ( module_burn_mint_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/burn_mint_token_pool" module_lock_release_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/lock_release_token_pool" module_managed_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/managed_token_pool" - module_usdc_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/usdc_token_pool" module_managed_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token/managed_token" ) @@ -292,29 +291,6 @@ func (e *CCIPEntrypointArgEncoder) EncodeEntryPointArg(executingCallbackParams * return encodeDefaultWithTypeArgsAndClock() } - // USDC TOKEN POOL - case "usdc_token_pool": - usdcTokenPool, err := module_usdc_token_pool.NewUsdcTokenPool(target, nil) - if err != nil { - return nil, err - } - switch function { - case "accept_ownership": - - return usdcTokenPool.Encoder().McmsAcceptOwnershipWithArgs(typeArgs, stateObj, registryObj, executingCallbackParams) - case "set_allowlist_enabled", - "apply_allowlist_updates", - "apply_chain_updates", - "add_remote_pool", - "remove_remote_pool", - "transfer_ownership": - return encodeDefaultWithTypeArgs() - case "execute_ownership_transfer": - return encodeExecuteOwnershipTransferWithTypeArgs() - case "set_chain_rate_limiter_configs", "set_chain_rate_limiter_config": - return encodeDefaultWithTypeArgsAndClock() - } - // RMN REMOTE case "rmn_remote": rmnRemote, err := module_rmn_remote.NewRmnRemote(target, nil) diff --git a/bindings/mcms_encoder_test.go b/bindings/mcms_encoder_test.go index 7e343bb96..3406d9c9d 100644 --- a/bindings/mcms_encoder_test.go +++ b/bindings/mcms_encoder_test.go @@ -722,140 +722,6 @@ func TestEncodeEntryPointArg_ManagedTokenPool(t *testing.T) { } } -func TestEncodeEntryPointArg_UsdcTokenPool(t *testing.T) { - encoder := &CCIPEntrypointArgEncoder{ - registryObjID: "0x1234567890123456789012345678901234567890123456789012345678901234", - deployerStateObjID: "0x8888888888888888888888888888888888888888888888888888888888888888", - } - - target := "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" - stateObjID := "0x9999999999999999999999999999999999999999999999999999999999999999" - executingCallbackParams := &transaction.Argument{} - - t.Run("accept_ownership", func(t *testing.T) { - data := []byte{} - - result, err := encoder.EncodeEntryPointArg( - executingCallbackParams, - target, - "usdc_token_pool", - "accept_ownership", - stateObjID, - data, - []string{"0x1::sui::SUI"}, - ) - - require.NoError(t, err) - assert.NotNil(t, result) - assert.Equal(t, "usdc_token_pool", result.Module.ModuleName) - assert.Equal(t, "mcms_accept_ownership", result.Function) - }) - - typeArgTestCases := []string{ - "set_allowlist_enabled", - "apply_allowlist_updates", - "apply_chain_updates", - "add_remote_pool", - "remove_remote_pool", - "transfer_ownership", - } - - for _, fn := range typeArgTestCases { - t.Run(fn, func(t *testing.T) { - data := []byte{} - - result, err := encoder.EncodeEntryPointArg( - executingCallbackParams, - target, - "usdc_token_pool", - fn, - stateObjID, - data, - []string{"0x1::sui::SUI"}, - ) - - require.NoError(t, err) - assert.NotNil(t, result) - assert.Equal(t, "usdc_token_pool", result.Module.ModuleName) - assert.Equal(t, "mcms_"+fn, result.Function) - - require.Len(t, result.TypeArgs, 1, "Expected 1 type argument") - require.Len(t, result.CallArgs, 3, "Expected 3 arguments: state, registry, executingCallbackParams") - - // Verify the state was deserialized correctly - stateFromResult, err := extractObjectID(result.CallArgs[0]) - require.NoError(t, err, "Failed to extract state object ID") - assert.Equal(t, stateObjID, stateFromResult, "State should match stateObjID (from BCS data)") - }) - } - - t.Run("execute_ownership_transfer", func(t *testing.T) { - data := []byte{} - - result, err := encoder.EncodeEntryPointArg( - executingCallbackParams, - target, - "usdc_token_pool", - "execute_ownership_transfer", - stateObjID, - data, - []string{"0x1::sui::SUI"}, - ) - - require.NoError(t, err) - assert.NotNil(t, result) - assert.Equal(t, "usdc_token_pool", result.Module.ModuleName) - assert.Equal(t, "mcms_execute_ownership_transfer", result.Function) - - require.Len(t, result.TypeArgs, 1, "Expected 1 type argument") - require.Len(t, result.CallArgs, 4, "Expected 4 arguments: state, registry, deployer_state, executingCallbackParams") - - // Verify the state was deserialized correctly - stateFromResult, err := extractObjectID(result.CallArgs[0]) - require.NoError(t, err, "Failed to extract state object ID") - assert.Equal(t, stateObjID, stateFromResult, "State should match stateObjID") - - // Verify the deployer state was set correctly - deployerStateFromResult, err := extractObjectID(result.CallArgs[2]) - require.NoError(t, err, "Failed to extract deployer state object ID") - assert.Equal(t, encoder.deployerStateObjID, deployerStateFromResult, "Deployer state should match deployerStateObjID") - }) - - rateLimiterTestCases := []string{ - "set_chain_rate_limiter_configs", - "set_chain_rate_limiter_config", - } - - for _, fn := range rateLimiterTestCases { - t.Run(fn, func(t *testing.T) { - data := []byte{} - - result, err := encoder.EncodeEntryPointArg( - executingCallbackParams, - target, - "usdc_token_pool", - fn, - stateObjID, - data, - []string{"0x1::sui::SUI"}, - ) - - require.NoError(t, err) - assert.NotNil(t, result) - assert.Equal(t, "usdc_token_pool", result.Module.ModuleName) - assert.Equal(t, "mcms_"+fn, result.Function) - - require.Len(t, result.TypeArgs, 1, "Expected 1 type argument") - require.Len(t, result.CallArgs, 4, "Expected 4 arguments: state, clock, registry, executingCallbackParams") - - // Verify the state was deserialized correctly - stateFromResult, err := extractObjectID(result.CallArgs[0]) - require.NoError(t, err, "Failed to extract state object ID") - assert.Equal(t, stateObjID, stateFromResult, "State should match stateObjID (from BCS data)") - }) - } -} - func TestEncodeEntryPointArg_ManagedToken(t *testing.T) { encoder := &CCIPEntrypointArgEncoder{ registryObjID: "0x1234567890123456789012345678901234567890123456789012345678901234", diff --git a/bindings/packages/ccip_token_pools/usdc_token_pool/usdc_token_pool.go b/bindings/packages/ccip_token_pools/usdc_token_pool/usdc_token_pool.go deleted file mode 100644 index 27563184e..000000000 --- a/bindings/packages/ccip_token_pools/usdc_token_pool/usdc_token_pool.go +++ /dev/null @@ -1,100 +0,0 @@ -package usdctokenpool - -import ( - "context" - - "github.com/block-vision/sui-go-sdk/models" - "github.com/smartcontractkit/chainlink-sui/relayer/client" - - "github.com/smartcontractkit/chainlink-sui/bindings/bind" - module_usdc_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/usdc_token_pool" - "github.com/smartcontractkit/chainlink-sui/contracts" -) - -type USDCTokenPool interface { - Address() string -} - -var _ USDCTokenPool = CCIPUSDCTokenPoolPackage{} - -type CCIPUSDCTokenPoolPackage struct { - address string - - usdcTokenPool module_usdc_token_pool.IUsdcTokenPool -} - -func (p CCIPUSDCTokenPoolPackage) Address() string { - return p.address -} - -func NewCCIPUSDCTokenPool(address string, chainClient client.BindingsClient) (USDCTokenPool, error) { - usdcTokenPoolContract, err := module_usdc_token_pool.NewUsdcTokenPool(address, chainClient) - if err != nil { - return nil, err - } - - packageId, err := bind.ToSuiAddress(address) - if err != nil { - return nil, err - } - - return CCIPUSDCTokenPoolPackage{ - address: packageId, - usdcTokenPool: usdcTokenPoolContract, - }, nil -} - -func PublishCCIPUSDCTokenPool( - ctx context.Context, - opts *bind.CallOpts, - chainClient client.BindingsClient, - ccipAddress, - usdcCoinMetadataObjectId, - tokenMessengerMinterPackageId, - tokenMessengerMinterStateObjectId, - messageTransmitterPackageId, - messageTransmitterStateObjectId, - treasuryObjectId, - mcmsAddress, - fastMcmsAddress, - mcmsOwnerAddress, suiRPC string) (USDCTokenPool, *models.SuiTransactionBlockResponse, error) { - signerAddr, err := opts.Signer.GetAddress() - if err != nil { - return nil, nil, err - } - - artifact, err := bind.CompilePackage(contracts.USDCTokenPool, map[string]string{ - "ccip": ccipAddress, - "usdc_token_pool": "0x0", - "usdc_coin_metadata_object_id": usdcCoinMetadataObjectId, - "token_messenger_minter_package_id": tokenMessengerMinterPackageId, - "token_messenger_minter_state": tokenMessengerMinterStateObjectId, - "message_transmitter_package_id": messageTransmitterPackageId, - "message_transmitter_state": messageTransmitterStateObjectId, - "treasury": treasuryObjectId, - "mcms": mcmsAddress, - "fast_mcms": fastMcmsAddress, - "mcms_owner": mcmsOwnerAddress, - - "signer": signerAddr, - }, false, suiRPC) - if err != nil { - return nil, nil, err - } - - //nolint:revive // var-naming: generated bindings keep packageId naming - packageId, tx, err := bind.PublishPackage(ctx, opts, chainClient, bind.PublishRequest{ - CompiledModules: artifact.Modules, - Dependencies: artifact.Dependencies, - }) - if err != nil { - return nil, nil, err - } - - contract, err := NewCCIPUSDCTokenPool(packageId, chainClient) - if err != nil { - return nil, nil, err - } - - return contract, tx, nil -} diff --git a/contracts/ccip/ccip_token_pools/usdc_token_pool/.gitignore b/contracts/ccip/ccip_token_pools/usdc_token_pool/.gitignore deleted file mode 100644 index a007feab0..000000000 --- a/contracts/ccip/ccip_token_pools/usdc_token_pool/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/* diff --git a/contracts/ccip/ccip_token_pools/usdc_token_pool/Move.toml b/contracts/ccip/ccip_token_pools/usdc_token_pool/Move.toml deleted file mode 100644 index dd4084b18..000000000 --- a/contracts/ccip/ccip_token_pools/usdc_token_pool/Move.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "usdc_token_pool" -edition = "2024" - -[dependencies] -ccip = { local = "../../ccip" } -mcms = { local = "../../../mcms/mcms" } -# Circle CCTP Imports -message_transmitter = { local = "../../../vendored/circlefin/sui-cctp/packages/message_transmitter" } -token_messenger_minter = { local = "../../../vendored/circlefin/sui-cctp/packages/token_messenger_minter" } - -# [addresses] -# ccip = "_" -# usdc_token_pool = "0x0" -# usdc_coin_metadata_object_id = "_" -# token_messenger_minter = "_" -# token_messenger_minter_state = "_" -# message_transmitter = "_" -# message_transmitter_state = "_" -# treasury = "_" -# mcms = "_" -# mcms_owner = "_" - -# [dev-addresses] -# ccip = "0x1000" -# usdc_token_pool = "0x2003" -# usdc_coin_metadata_object_id = "0x9000" -# token_messenger_minter = "0x31cc14d80c175ae39777c0238f20594c6d4869cfab199f40b69f3319956b8beb" -# token_messenger_minter_state = "0x5252abd1137094ed1db3e0d75bc36abcd287aee4bc310f8e047727ef5682e7c2" -# message_transmitter = "0x4931e06dce648b3931f890035bd196920770e913e43e45990b383f6486fdd0a5" -# message_transmitter_state = "0x98234bd0fa9ac12cc0a20a144a22e36d6a32f7e0a97baaeaf9c76cdc6d122d2e" -# treasury = "0x7170137d4a6431bf83351ac025baf462909bffe2877d87716374fb42b9629ebe" -# mcms = "0x4000" -# mcms_owner = "0x4010" diff --git a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/ownable.move b/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/ownable.move deleted file mode 100644 index 6dd3d59f4..000000000 --- a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/ownable.move +++ /dev/null @@ -1,273 +0,0 @@ -module usdc_token_pool::ownable; - -use mcms::mcms_registry::{Self, Registry, PublisherWrapper}; -use sui::dynamic_field as df; -use sui::event; -use sui::package::Publisher; - -public struct OwnerCap has key, store { - id: UID, -} - -public struct OwnableState has store { - owner: address, - pending_transfer: Option, - owner_cap_id: ID, -} - -public struct PendingTransfer has drop, store { - from: address, - to: address, - accepted: bool, -} - -public struct OwnableStateKey has copy, drop, store {} - -public struct PublisherKey has copy, drop, store {} - -// =================== Events =================== // - -public struct NewOwnableStateEvent has copy, drop, store { - owner_cap_id: ID, - owner: address, -} - -public struct OwnershipTransferRequested has copy, drop { - from: address, - to: address, -} - -public struct OwnershipTransferAccepted has copy, drop { - from: address, - to: address, -} - -public struct OwnershipTransferred has copy, drop { - from: address, - to: address, -} - -const EInvalidOwnerCap: u64 = 1; -const ECannotTransferToSelf: u64 = 2; -const EMustBeProposedOwner: u64 = 3; -const ENoPendingTransfer: u64 = 4; -const ETransferAlreadyAccepted: u64 = 5; -const EOwnerChanged: u64 = 6; -const EProposedOwnerMismatch: u64 = 7; -const ETransferNotAccepted: u64 = 8; -const ECannotTransferToMcms: u64 = 9; -const EMustTransferToMcms: u64 = 10; - -public(package) fun new(ctx: &mut TxContext): (OwnableState, OwnerCap) { - let owner = ctx.sender(); - - let owner_cap = OwnerCap { - id: object::new(ctx), - }; - - let state = OwnableState { - owner, - pending_transfer: option::none(), - owner_cap_id: object::id(&owner_cap), - }; - - event::emit(NewOwnableStateEvent { - owner_cap_id: object::id(&owner_cap), - owner, - }); - - (state, owner_cap) -} - -public fun owner_cap_id(state: &OwnableState): ID { - state.owner_cap_id -} - -public fun owner(state: &OwnableState): address { - state.owner -} - -public fun has_pending_transfer(state: &OwnableState): bool { - state.pending_transfer.is_some() -} - -public fun pending_transfer_from(state: &OwnableState): Option
{ - state.pending_transfer.map_ref!(|pending_transfer| pending_transfer.from) -} - -public fun pending_transfer_to(state: &OwnableState): Option
{ - state.pending_transfer.map_ref!(|pending_transfer| pending_transfer.to) -} - -public fun pending_transfer_accepted(state: &OwnableState): Option { - state.pending_transfer.map_ref!(|pending_transfer| pending_transfer.accepted) -} - -public(package) fun attach_ownable_state(owner_cap: &mut OwnerCap, ownable_state: OwnableState) { - df::add(&mut owner_cap.id, OwnableStateKey {}, ownable_state); -} - -public(package) fun detach_ownable_state(owner_cap: &mut OwnerCap): OwnableState { - df::remove(&mut owner_cap.id, OwnableStateKey {}) -} - -public(package) fun attach_publisher(owner_cap: &mut OwnerCap, publisher: Publisher) { - df::add(&mut owner_cap.id, PublisherKey {}, publisher); -} - -public(package) fun borrow_publisher(owner_cap: &OwnerCap): &Publisher { - df::borrow(&owner_cap.id, PublisherKey {}) -} - -public(package) fun transfer_ownership( - owner_cap: &OwnerCap, - state: &mut OwnableState, - to: address, - _ctx: &TxContext, -) { - assert!(object::id(owner_cap) == state.owner_cap_id, EInvalidOwnerCap); - assert!(state.owner != to, ECannotTransferToSelf); - - state.pending_transfer = - option::some(PendingTransfer { - from: state.owner, - to, - accepted: false, - }); - - event::emit(OwnershipTransferRequested { from: state.owner, to }); -} - -public(package) fun accept_ownership(state: &mut OwnableState, ctx: &TxContext) { - accept_ownership_internal(state, ctx.sender()); -} - -/// UID is a privileged type that is only accessible by the object owner. -public(package) fun accept_ownership_from_object( - state: &mut OwnableState, - from: &UID, - _ctx: &TxContext, -) { - accept_ownership_internal(state, from.to_address()); -} - -public(package) fun mcms_accept_ownership( - state: &mut OwnableState, - mcms: address, - _ctx: &mut TxContext, -) { - accept_ownership_internal(state, mcms); -} - -fun accept_ownership_internal(state: &mut OwnableState, caller: address) { - assert!(state.pending_transfer.is_some(), ENoPendingTransfer); - - let pending_transfer = state.pending_transfer.borrow_mut(); - let current_owner = state.owner; - - // check that the owner has not changed from a direct call to 0x1::transfer::public_transfer, - // in which case the transfer flow should be restarted. - assert!(current_owner == pending_transfer.from, EOwnerChanged); - assert!(caller == pending_transfer.to, EMustBeProposedOwner); - assert!(!pending_transfer.accepted, ETransferAlreadyAccepted); - - pending_transfer.accepted = true; - - event::emit(OwnershipTransferAccepted { from: pending_transfer.from, to: caller }); -} - -#[allow(lint(custom_state_change))] -public(package) fun execute_ownership_transfer( - owner_cap: OwnerCap, - state: &mut OwnableState, - to: address, - _ctx: &TxContext, -) { - assert!(object::id(&owner_cap) == state.owner_cap_id, EInvalidOwnerCap); - assert!(state.pending_transfer.is_some(), ENoPendingTransfer); - - let pending_transfer = state.pending_transfer.extract(); - let current_owner = state.owner; - let new_owner = pending_transfer.to; - - // check that the owner has not changed from a direct call to 0x1::transfer::public_transfer, - // in which case the transfer flow should be restarted. - assert!(pending_transfer.from == current_owner, EOwnerChanged); - assert!(new_owner == to, EProposedOwnerMismatch); - assert!(pending_transfer.accepted, ETransferNotAccepted); - - // Must call `execute_ownership_transfer_to_mcms` instead - assert!(new_owner != mcms_registry::get_multisig_address(), ECannotTransferToMcms); - - state.owner = to; - - transfer::transfer(owner_cap, to); - - event::emit(OwnershipTransferred { from: current_owner, to: new_owner }); -} - -#[allow(lint(custom_state_change))] -public(package) fun execute_ownership_transfer_to_mcms( - owner_cap: OwnerCap, - state: &mut OwnableState, - registry: &mut Registry, - to: address, - publisher_wrapper: PublisherWrapper

, - proof: P, - allowed_modules: vector>, - ctx: &mut TxContext, -) { - assert!(object::id(&owner_cap) == state.owner_cap_id, EInvalidOwnerCap); - assert!(state.pending_transfer.is_some(), ENoPendingTransfer); - - let pending_transfer = state.pending_transfer.extract(); - let current_owner = state.owner; - let new_owner = pending_transfer.to; - - // check that the owner has not changed from a direct call to 0x1::transfer::public_transfer, - // in which case the transfer flow should be restarted. - assert!(pending_transfer.from == current_owner, EOwnerChanged); - assert!(new_owner == to, EProposedOwnerMismatch); - assert!(pending_transfer.accepted, ETransferNotAccepted); - assert!(to == mcms_registry::get_multisig_address(), EMustTransferToMcms); - - state.owner = to; - - mcms_registry::register_entrypoint( - registry, - publisher_wrapper, - proof, - owner_cap, - allowed_modules, - ctx, - ); - - event::emit(OwnershipTransferred { from: current_owner, to: new_owner }); -} - -public fun destroy(state: OwnableState, owner_cap: OwnerCap, _ctx: &TxContext) { - let OwnableState { - owner: _, - pending_transfer: _, - owner_cap_id: state_owner_cap_id, - } = state; - - let OwnerCap { id: owner_cap_id } = owner_cap; - - assert!(owner_cap_id.uid_to_inner() == state_owner_cap_id, EInvalidOwnerCap); - - object::delete(owner_cap_id); -} - -// =================== Test-only functions =================== // - -#[test_only] -public fun create_test_owner_cap(ctx: &mut TxContext): OwnerCap { - OwnerCap { id: object::new(ctx) } -} - -#[test_only] -public fun test_destroy_owner_cap(cap: OwnerCap) { - let OwnerCap { id } = cap; - object::delete(id); -} diff --git a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/rate_limiter.move b/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/rate_limiter.move deleted file mode 100644 index df982743d..000000000 --- a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/rate_limiter.move +++ /dev/null @@ -1,101 +0,0 @@ -module usdc_token_pool::rate_limiter; - -use sui::clock::Clock; - -public struct TokenBucket has drop, store { - tokens: u64, - last_updated: u64, - is_enabled: bool, - capacity: u64, - rate: u64, -} - -const TIME_CONVERSION_TO_SECONDS: u64 = 1000; - -const ETokenMaxCapacityExceeded: u64 = 1; -const ETokenRateLimitReached: u64 = 2; - -public(package) fun new(clock: &Clock, is_enabled: bool, capacity: u64, rate: u64): TokenBucket { - TokenBucket { - tokens: 0, - last_updated: clock.timestamp_ms() / TIME_CONVERSION_TO_SECONDS, - is_enabled, - capacity, - rate, - } -} - -public(package) fun get_current_token_bucket_state( - clock: &Clock, - state: &TokenBucket, -): TokenBucket { - TokenBucket { - tokens: calculate_refill( - state, - clock.timestamp_ms() / TIME_CONVERSION_TO_SECONDS - state.last_updated, - ), - last_updated: clock.timestamp_ms() / TIME_CONVERSION_TO_SECONDS, - is_enabled: state.is_enabled, - capacity: state.capacity, - rate: state.rate, - } -} - -public(package) fun consume(clock: &Clock, bucket: &mut TokenBucket, requested_tokens: u64) { - if (!bucket.is_enabled || requested_tokens == 0) { return }; - - update_bucket(clock, bucket); - - assert!(requested_tokens <= bucket.capacity, ETokenMaxCapacityExceeded); - - assert!(requested_tokens <= bucket.tokens, ETokenRateLimitReached); - - bucket.tokens = bucket.tokens - requested_tokens; -} - -/// We allow 0 rate and/or 0 capacity rate limits to effectively disable value transfer. -public(package) fun set_token_bucket_config( - clock: &Clock, - bucket: &mut TokenBucket, - is_enabled: bool, - capacity: u64, - rate: u64, -) { - update_bucket(clock, bucket); - - bucket.tokens = min(bucket.tokens, capacity); - bucket.capacity = capacity; - bucket.rate = rate; - bucket.is_enabled = is_enabled; -} - -fun update_bucket(clock: &Clock, bucket: &mut TokenBucket) { - let time_now_seconds = clock.timestamp_ms() / TIME_CONVERSION_TO_SECONDS; - let time_diff = time_now_seconds - bucket.last_updated; - - if (time_diff > 0) { - bucket.tokens = calculate_refill(bucket, time_diff); - bucket.last_updated = time_now_seconds; - }; -} - -fun calculate_refill(bucket: &TokenBucket, time_diff: u64): u64 { - if (bucket.tokens >= bucket.capacity) { return bucket.capacity }; - if (bucket.rate == 0) { return bucket.tokens }; - - let remaining = bucket.capacity - bucket.tokens; - // If time_diff * rate would exceed remaining, saturate to capacity - if (time_diff > remaining / bucket.rate) { - bucket.capacity - } else { - bucket.tokens + time_diff * bucket.rate - } -} - -fun min(a: u64, b: u64): u64 { - if (a > b) b else a -} - -public fun get_token_bucket_fields(bucket: &TokenBucket): (u64, u64, bool, u64, u64) { - (bucket.tokens, bucket.last_updated, bucket.is_enabled, bucket.capacity, bucket.rate) -} diff --git a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool.move b/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool.move deleted file mode 100644 index e6bb2b03c..000000000 --- a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool.move +++ /dev/null @@ -1,523 +0,0 @@ -module usdc_token_pool::token_pool; - -use ccip::address; -use ccip::allowlist; -use ccip::eth_abi; -use ccip::rmn_remote; -use ccip::state_object::CCIPObjectRef; -use std::ascii; -use sui::clock::Clock; -use sui::coin::CoinMetadata; -use sui::event; -use sui::vec_map::{Self, VecMap}; -use usdc_token_pool::rate_limiter; -use usdc_token_pool::token_pool_rate_limiter; - -const MAX_U256: u256 = - 115792089237316195423570985008687907853269984665640564039457584007913129639935; -const MAX_U64: u256 = 18446744073709551615; - -public struct TokenPoolState has store { - allowlist_state: allowlist::AllowlistState, - coin_metadata: address, - local_decimals: u8, - symbol: ascii::String, - remote_chain_configs: VecMap, - rate_limiter_config: token_pool_rate_limiter::RateLimitState, -} - -public struct RemoteChainConfig has copy, drop, store { - remote_token_address: vector, - remote_pools: vector>, -} - -public struct LockedOrBurned has copy, drop { - remote_chain_selector: u64, - local_token: address, - amount: u64, -} - -public struct ReleasedOrMinted has copy, drop { - remote_chain_selector: u64, - local_token: address, - recipient: address, - amount: u64, -} - -public struct RemotePoolAdded has copy, drop { - remote_chain_selector: u64, - remote_pool_address: vector, -} - -public struct RemotePoolRemoved has copy, drop { - remote_chain_selector: u64, - remote_pool_address: vector, -} - -public struct ChainAdded has copy, drop { - remote_chain_selector: u64, - remote_token_address: vector, -} - -public struct ChainRemoved has copy, drop { - remote_chain_selector: u64, -} - -const ENotPublisher: u64 = 1; -const EUnknownRemoteChainSelector: u64 = 2; -const ECursedChain: u64 = 3; -const ERemotePoolAlreadyAdded: u64 = 4; -const EUnknownRemotePool: u64 = 5; -const ERemoteChainToAddMismatch: u64 = 6; -const ERemoteChainAlreadyExists: u64 = 7; -const EInvalidRemoteChainDecimals: u64 = 8; -const EInvalidEncodedAmount: u64 = 9; -const EUnknownToken: u64 = 10; -const EDecimalOverflow: u64 = 11; - -// ================================================================ -// | Initialize and state | -// ================================================================ - -public(package) fun initialize( - coin_metadata_address: address, - local_decimals: u8, - symbol: ascii::String, - allowlist: vector

, - ctx: &mut TxContext, -): TokenPoolState { - TokenPoolState { - allowlist_state: allowlist::new(allowlist, ctx), - coin_metadata: coin_metadata_address, - local_decimals, - symbol, - remote_chain_configs: vec_map::empty(), - rate_limiter_config: token_pool_rate_limiter::new(ctx), - } -} - -public fun get_token(state: &TokenPoolState): address { - state.coin_metadata -} - -public fun get_symbol(state: &TokenPoolState): ascii::String { - state.symbol -} - -public fun get_current_inbound_rate_limiter_state( - state: &TokenPoolState, - clock: &Clock, - remote_chain_selector: u64, -): rate_limiter::TokenBucket { - token_pool_rate_limiter::get_current_inbound_rate_limiter_state( - &state.rate_limiter_config, - clock, - remote_chain_selector, - ) -} - -public fun get_current_outbound_rate_limiter_state( - state: &TokenPoolState, - clock: &Clock, - remote_chain_selector: u64, -): rate_limiter::TokenBucket { - token_pool_rate_limiter::get_current_outbound_rate_limiter_state( - &state.rate_limiter_config, - clock, - remote_chain_selector, - ) -} - -// ================================================================ -// | Remote Chains | -// ================================================================ - -public fun get_supported_chains(state: &TokenPoolState): vector { - state.remote_chain_configs.keys() -} - -public fun is_supported_chain(state: &TokenPoolState, remote_chain_selector: u64): bool { - state.remote_chain_configs.contains(&remote_chain_selector) -} - -public(package) fun apply_chain_updates( - state: &mut TokenPoolState, - remote_chain_selectors_to_remove: vector, - remote_chain_selectors_to_add: vector, - remote_pool_addresses_to_add: vector>>, - remote_token_addresses_to_add: vector>, -) { - remote_chain_selectors_to_remove.do_ref!(|remote_chain_selector| { - assert!( - state.remote_chain_configs.contains(remote_chain_selector), - EUnknownRemoteChainSelector, - ); - state.remote_chain_configs.remove(remote_chain_selector); - event::emit(ChainRemoved { - remote_chain_selector: *remote_chain_selector, - }); - }); - - let add_len = remote_chain_selectors_to_add.length(); - assert!(add_len == remote_pool_addresses_to_add.length(), ERemoteChainToAddMismatch); - assert!(add_len == remote_token_addresses_to_add.length(), ERemoteChainToAddMismatch); - - let mut i = 0; - while (i < add_len) { - let remote_chain_selector = remote_chain_selectors_to_add[i]; - assert!( - !state.remote_chain_configs.contains(&remote_chain_selector), - ERemoteChainAlreadyExists, - ); - let remote_pool_addresses = remote_pool_addresses_to_add[i]; - let remote_token_address = remote_token_addresses_to_add[i]; - address::assert_non_zero_address_vector(&remote_token_address); - - let mut remote_chain_config = RemoteChainConfig { - remote_token_address, - remote_pools: vector[], - }; - - remote_pool_addresses.do_ref!(|remote_pool_address| { - let remote_pool_address: vector = *remote_pool_address; - address::assert_non_zero_address_vector(&remote_pool_address); - - let (found, _) = remote_chain_config.remote_pools.index_of(&remote_pool_address); - assert!(!found, ERemotePoolAlreadyAdded); - - remote_chain_config.remote_pools.push_back(remote_pool_address); - - event::emit(RemotePoolAdded { remote_chain_selector, remote_pool_address }); - }); - - state.remote_chain_configs.insert(remote_chain_selector, remote_chain_config); - - event::emit(ChainAdded { remote_chain_selector, remote_token_address }); - i = i + 1; - }; -} - -// ================================================================ -// | Remote Pools | -// ================================================================ - -public fun get_remote_pools( - state: &TokenPoolState, - remote_chain_selector: u64, -): vector> { - assert!( - state.remote_chain_configs.contains(&remote_chain_selector), - EUnknownRemoteChainSelector, - ); - let remote_chain_config = state.remote_chain_configs.get(&remote_chain_selector); - remote_chain_config.remote_pools -} - -public fun is_remote_pool( - state: &TokenPoolState, - remote_chain_selector: u64, - remote_pool_address: vector, -): bool { - let remote_pools = get_remote_pools(state, remote_chain_selector); - let (found, _) = remote_pools.index_of(&remote_pool_address); - found -} - -public fun get_remote_token(state: &TokenPoolState, remote_chain_selector: u64): vector { - assert!( - state.remote_chain_configs.contains(&remote_chain_selector), - EUnknownRemoteChainSelector, - ); - let remote_chain_config = state.remote_chain_configs.get(&remote_chain_selector); - remote_chain_config.remote_token_address -} - -public(package) fun add_remote_pool( - state: &mut TokenPoolState, - remote_chain_selector: u64, - remote_pool_address: vector, -) { - address::assert_non_zero_address_vector(&remote_pool_address); - - assert!( - state.remote_chain_configs.contains(&remote_chain_selector), - EUnknownRemoteChainSelector, - ); - let remote_chain_config = state.remote_chain_configs.get_mut(&remote_chain_selector); - - let (found, _) = remote_chain_config.remote_pools.index_of(&remote_pool_address); - assert!(!found, ERemotePoolAlreadyAdded); - - remote_chain_config.remote_pools.push_back(remote_pool_address); - - event::emit(RemotePoolAdded { remote_chain_selector, remote_pool_address }); -} - -public(package) fun remove_remote_pool( - state: &mut TokenPoolState, - remote_chain_selector: u64, - remote_pool_address: vector, -) { - assert!( - state.remote_chain_configs.contains(&remote_chain_selector), - EUnknownRemoteChainSelector, - ); - let remote_chain_config = state.remote_chain_configs.get_mut(&remote_chain_selector); - - let (found, i) = remote_chain_config.remote_pools.index_of(&remote_pool_address); - assert!(found, EUnknownRemotePool); - - // remove instead of swap_remove for readability, so the newest added pool is always at the end. - remote_chain_config.remote_pools.remove(i); - - event::emit(RemotePoolRemoved { remote_chain_selector, remote_pool_address }); -} - -// ================================================================ -// | Validation | -// ================================================================ - -/// Returns the remote token as bytes -public(package) fun validate_lock_or_burn( - ref: &CCIPObjectRef, - clock: &Clock, - state: &mut TokenPoolState, - sender: address, - remote_chain_selector: u64, // the destination chain selector - local_amount: u64, -): vector { - assert!(!rmn_remote::is_cursed_u128(ref, (remote_chain_selector as u128)), ECursedChain); - - // Allowlist check - if (allowlist::get_allowlist_enabled(&state.allowlist_state)) { - assert!(allowlist::is_allowed(&state.allowlist_state, sender), ENotPublisher); - }; - - if (!is_supported_chain(state, remote_chain_selector)) { - abort EUnknownRemoteChainSelector - }; - - token_pool_rate_limiter::consume_outbound( - clock, - &mut state.rate_limiter_config, - remote_chain_selector, - local_amount, - ); - - get_remote_token(state, remote_chain_selector) -} - -public(package) fun validate_release_or_mint( - ref: &CCIPObjectRef, - clock: &Clock, - state: &mut TokenPoolState, - remote_chain_selector: u64, // the source chain selector - dest_token_address: address, // the token's coin metadata object id - source_pool_address: vector, // the source pool's address - local_amount: u64, -) { - let configured_token = get_token(state); - - assert!(configured_token == dest_token_address, EUnknownToken); - - // Check RMN curse status - assert!(!rmn_remote::is_cursed_u128(ref, (remote_chain_selector as u128)), ECursedChain); - - // This checks if the remote chain selector and the source pool are valid. - assert!(is_remote_pool(state, remote_chain_selector, source_pool_address), EUnknownRemotePool); - - token_pool_rate_limiter::consume_inbound( - clock, - &mut state.rate_limiter_config, - remote_chain_selector, - local_amount, - ); -} - -// ================================================================ -// | Events | -// ================================================================ - -public(package) fun emit_released_or_minted( - state: &TokenPoolState, - recipient: address, - amount: u64, - remote_chain_selector: u64, -) { - event::emit(ReleasedOrMinted { - remote_chain_selector, - local_token: state.coin_metadata, - recipient, - amount, - }); -} - -public(package) fun emit_locked_or_burned( - state: &TokenPoolState, - amount: u64, - remote_chain_selector: u64, -) { - event::emit(LockedOrBurned { remote_chain_selector, local_token: state.coin_metadata, amount }); -} - -// ================================================================ -// | Decimals | -// ================================================================ - -public fun get_local_decimals(pool: &TokenPoolState): u8 { - pool.local_decimals -} - -/// for a token, CoinMetadata is supposed to be shared -public fun encode_local_decimals(coin_metadata: &CoinMetadata): vector { - let decimals = coin_metadata.get_decimals(); - let mut ret = vector[]; - eth_abi::encode_u8(&mut ret, decimals); - ret -} - -public fun parse_remote_decimals(source_pool_data: vector, local_decimals: u8): u8 { - let data_len = source_pool_data.length(); - if (data_len == 0) { - // Fallback to the local value. - return local_decimals - }; - - assert!(data_len == 32, EInvalidRemoteChainDecimals); - - let remote_decimals = eth_abi::decode_u256_value(source_pool_data); - assert!(remote_decimals <= 255, EInvalidRemoteChainDecimals); - - remote_decimals as u8 -} - -public fun calculate_local_amount( - remote_amount: u256, - remote_decimals: u8, - local_decimals: u8, -): u64 { - let local_amount = calculate_local_amount_internal( - remote_amount, - remote_decimals, - local_decimals, - ); - assert!(local_amount <= MAX_U64, EInvalidEncodedAmount); - local_amount as u64 -} - -fun calculate_local_amount_internal( - remote_amount: u256, - remote_decimals: u8, - local_decimals: u8, -): u256 { - if (remote_decimals == local_decimals) { - remote_amount - } else if (remote_decimals > local_decimals) { - let decimals_diff = remote_decimals - local_decimals; - let mut current_amount = remote_amount; - let mut i = 0; - while (i < decimals_diff) { - current_amount = current_amount / 10; - i = i + 1; - }; - current_amount - } else { - let decimals_diff = local_decimals - remote_decimals; - // This is a safety check to prevent overflow in the next calculation. - // More than 77 would never fit in a uint256 and would cause an overflow. We also check if the resulting amount - // would overflow. - assert!(decimals_diff <= 77, EDecimalOverflow); - - let mut multiplier: u256 = 1; - let base: u256 = 10; - let mut i = 0; - while (i < decimals_diff) { - multiplier = multiplier * base; - i = i + 1; - }; - assert!(remote_amount <= (MAX_U256 / multiplier), EDecimalOverflow); - - remote_amount * multiplier - } -} - -public fun calculate_release_or_mint_amount( - state: &TokenPoolState, - source_pool_data: vector, - source_amount: u256, -): u64 { - let local_decimals = state.get_local_decimals(); - let remote_decimals = parse_remote_decimals(source_pool_data, local_decimals); - - calculate_local_amount(source_amount, remote_decimals, local_decimals) -} - -// ================================================================ -// | Rate limit config | -// ================================================================ - -public(package) fun set_chain_rate_limiter_config( - clock: &Clock, - state: &mut TokenPoolState, - remote_chain_selector: u64, - outbound_is_enabled: bool, - outbound_capacity: u64, - outbound_rate: u64, - inbound_is_enabled: bool, - inbound_capacity: u64, - inbound_rate: u64, -) { - token_pool_rate_limiter::set_chain_rate_limiter_config( - clock, - &mut state.rate_limiter_config, - remote_chain_selector, - outbound_is_enabled, - outbound_capacity, - outbound_rate, - inbound_is_enabled, - inbound_capacity, - inbound_rate, - ); -} - -// ================================================================ -// | Allowlist | -// ================================================================ - -public fun get_allowlist_enabled(state: &TokenPoolState): bool { - allowlist::get_allowlist_enabled(&state.allowlist_state) -} - -public(package) fun set_allowlist_enabled(state: &mut TokenPoolState, enabled: bool) { - allowlist::set_allowlist_enabled(&mut state.allowlist_state, enabled); -} - -public fun get_allowlist(state: &TokenPoolState): vector
{ - allowlist::get_allowlist(&state.allowlist_state) -} - -public(package) fun apply_allowlist_updates( - state: &mut TokenPoolState, - removes: vector
, - adds: vector
, -) { - allowlist::apply_allowlist_updates(&mut state.allowlist_state, removes, adds); -} - -// ================================================================ -// | Deconstruction | -// ================================================================ - -public(package) fun destroy_token_pool(state: TokenPoolState) { - let TokenPoolState { - allowlist_state, - coin_metadata: _coin_metadata, - local_decimals: _local_decimals, - symbol: _symbol, - remote_chain_configs: _remote_chain_configs, - rate_limiter_config, - } = state; - - allowlist::destroy_allowlist(allowlist_state); - token_pool_rate_limiter::destroy_rate_limiter(rate_limiter_config); -} diff --git a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool_rate_limiter.move b/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool_rate_limiter.move deleted file mode 100644 index 4c08b0670..000000000 --- a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/token_pool_rate_limiter.move +++ /dev/null @@ -1,177 +0,0 @@ -module usdc_token_pool::token_pool_rate_limiter; - -use sui::clock::Clock; -use sui::event; -use sui::table::{Self, Table}; -use usdc_token_pool::rate_limiter::{Self, TokenBucket}; - -public struct RateLimitState has store { - outbound_rate_limiter_config: Table, - inbound_rate_limiter_config: Table, -} - -public struct TokensConsumed has copy, drop { - remote_chain_selector: u64, - tokens: u64, -} - -public struct ConfigChanged has copy, drop { - remote_chain_selector: u64, - outbound_is_enabled: bool, - outbound_capacity: u64, - outbound_rate: u64, - inbound_is_enabled: bool, - inbound_capacity: u64, - inbound_rate: u64, -} - -const EBucketNotFound: u64 = 1; -const ERateLimiterConfigNotFound: u64 = 2; - -public(package) fun new(ctx: &mut TxContext): RateLimitState { - RateLimitState { - outbound_rate_limiter_config: table::new(ctx), - inbound_rate_limiter_config: table::new(ctx), - } -} - -public(package) fun consume_inbound( - clock: &Clock, - state: &mut RateLimitState, - dest_chain_selector: u64, - requested_tokens: u64, -) { - consume_from_bucket( - clock, - &mut state.inbound_rate_limiter_config, - dest_chain_selector, - requested_tokens, - ); -} - -public(package) fun consume_outbound( - clock: &Clock, - state: &mut RateLimitState, - dest_chain_selector: u64, - requested_tokens: u64, -) { - consume_from_bucket( - clock, - &mut state.outbound_rate_limiter_config, - dest_chain_selector, - requested_tokens, - ); -} - -fun consume_from_bucket( - clock: &Clock, - rate_limiter: &mut Table, - dest_chain_selector: u64, - requested_tokens: u64, -) { - assert!(rate_limiter.contains(dest_chain_selector), EBucketNotFound); - - let bucket = rate_limiter.borrow_mut(dest_chain_selector); - rate_limiter::consume(clock, bucket, requested_tokens); - - event::emit(TokensConsumed { - remote_chain_selector: dest_chain_selector, - tokens: requested_tokens, - }); -} - -public(package) fun set_chain_rate_limiter_config( - clock: &Clock, - state: &mut RateLimitState, - remote_chain_selector: u64, - outbound_is_enabled: bool, - outbound_capacity: u64, - outbound_rate: u64, - inbound_is_enabled: bool, - inbound_capacity: u64, - inbound_rate: u64, -) { - if (!state.outbound_rate_limiter_config.contains(remote_chain_selector)) { - state - .outbound_rate_limiter_config - .add( - remote_chain_selector, - rate_limiter::new(clock, false, 0, 0), - ); - }; - let outbound_config = state.outbound_rate_limiter_config.borrow_mut(remote_chain_selector); - rate_limiter::set_token_bucket_config( - clock, - outbound_config, - outbound_is_enabled, - outbound_capacity, - outbound_rate, - ); - - if (!state.inbound_rate_limiter_config.contains(remote_chain_selector)) { - state - .inbound_rate_limiter_config - .add( - remote_chain_selector, - rate_limiter::new(clock, false, 0, 0), - ); - }; - let inbound_config = state.inbound_rate_limiter_config.borrow_mut(remote_chain_selector); - rate_limiter::set_token_bucket_config( - clock, - inbound_config, - inbound_is_enabled, - inbound_capacity, - inbound_rate, - ); - - event::emit(ConfigChanged { - remote_chain_selector, - outbound_is_enabled, - outbound_capacity, - outbound_rate, - inbound_is_enabled, - inbound_capacity, - inbound_rate, - }); -} - -public(package) fun get_current_inbound_rate_limiter_state( - state: &RateLimitState, - clock: &Clock, - remote_chain_selector: u64, -): rate_limiter::TokenBucket { - assert!( - state.inbound_rate_limiter_config.contains(remote_chain_selector), - ERateLimiterConfigNotFound, - ); - rate_limiter::get_current_token_bucket_state( - clock, - state.inbound_rate_limiter_config.borrow(remote_chain_selector), - ) -} - -public(package) fun get_current_outbound_rate_limiter_state( - state: &RateLimitState, - clock: &Clock, - remote_chain_selector: u64, -): rate_limiter::TokenBucket { - assert!( - state.outbound_rate_limiter_config.contains(remote_chain_selector), - ERateLimiterConfigNotFound, - ); - rate_limiter::get_current_token_bucket_state( - clock, - state.outbound_rate_limiter_config.borrow(remote_chain_selector), - ) -} - -public(package) fun destroy_rate_limiter(state: RateLimitState) { - let RateLimitState { - outbound_rate_limiter_config, - inbound_rate_limiter_config, - } = state; - - outbound_rate_limiter_config.drop(); - inbound_rate_limiter_config.drop(); -} diff --git a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/usdc_token_pool.move b/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/usdc_token_pool.move deleted file mode 100644 index 8e3bc76d2..000000000 --- a/contracts/ccip/ccip_token_pools/usdc_token_pool/sources/usdc_token_pool.move +++ /dev/null @@ -1,1298 +0,0 @@ -module usdc_token_pool::usdc_token_pool; - -use ccip::eth_abi; -use ccip::offramp_state_helper as offramp_sh; -use ccip::onramp_state_helper as onramp_sh; -use ccip::state_object::CCIPObjectRef; -use ccip::token_admin_registry; -use mcms::bcs_stream; -use mcms::mcms_deployer::{Self, DeployerState}; -use mcms::mcms_registry::{Self, Registry, ExecutingCallbackParams}; -use message_transmitter::auth::auth_caller_identifier; -use message_transmitter::message; -use message_transmitter::receive_message::{Self, Receipt, ReceiveMessageTicket}; -use message_transmitter::state::State as MessageTransmitterState; -use stablecoin::treasury::Treasury; -use std::ascii; -use std::string::{Self, String}; -use std::type_name; -use sui::address; -use sui::clock::Clock; -use sui::coin::{Coin, CoinMetadata}; -use sui::deny_list::DenyList; -use sui::derived_object; -use sui::event; -use sui::package::{Self, UpgradeCap}; -use sui::table::{Self, Table}; -use token_messenger_minter::burn_message; -use token_messenger_minter::deposit_for_burn::{Self, DepositForBurnWithCallerTicket}; -use token_messenger_minter::handle_receive_message; -use token_messenger_minter::state::State as MinterState; -use usdc_token_pool::ownable::{Self, OwnerCap, OwnableState}; -use usdc_token_pool::rate_limiter; -use usdc_token_pool::token_pool::{Self, TokenPoolState}; - -public struct USDC_TOKEN_POOL has drop {} - -public struct USDCTokenPoolObject has key { - id: UID, -} - -public struct USDCTokenPoolStatePointer has key, store { - id: UID, - usdc_token_pool_object_id: address, -} - -fun init(otw: USDC_TOKEN_POOL, ctx: &mut TxContext) { - let (ownable_state, mut owner_cap) = ownable::new(ctx); - ownable::attach_ownable_state(&mut owner_cap, ownable_state); - - let publisher = package::claim(otw, ctx); - ownable::attach_publisher(&mut owner_cap, publisher); - - transfer::public_transfer(owner_cap, ctx.sender()); -} - -/// A domain is a USDC representation of a destination chain. -/// @dev Zero is a valid domain identifier. -/// @dev The address to mint on the destination chain is the corresponding USDC pool. -/// @dev The allowedCaller represents the contract authorized to call receiveMessage on the destination CCTP message transmitter. -/// For EVM dest pool version 1.6.1, this is the MessageTransmitterProxy of the destination chain. -/// For EVM dest pool version 1.5.1, this is the destination chain's token pool. -public struct Domain has copy, drop, store { - allowed_caller: vector, // Address allowed to mint on the domain - domain_identifier: u32, // Unique domain ID - enabled: bool, -} - -public struct DomainsSet has copy, drop { - allowed_caller: vector, - domain_identifier: u32, - remote_chain_selector: u64, - enabled: bool, -} - -public struct USDCTokenPoolState has key { - id: UID, - token_pool_state: TokenPoolState, - chain_to_domain: Table, - local_domain_identifier: u32, - ownable_state: OwnableState, -} - -public struct TokenBucketWrapper has drop, store { - tokens: u64, - last_updated: u64, - is_enabled: bool, - capacity: u64, - rate: u64, -} - -const EInvalidCoinMetadata: u64 = 1; -const EInvalidArguments: u64 = 2; -const EInvalidOwnerCap: u64 = 3; -const EZeroChainSelector: u64 = 4; -const EEmptyAllowedCaller: u64 = 5; -const EDomainMismatch: u64 = 6; -const ENonceMismatch: u64 = 7; -const EDomainNotFound: u64 = 8; -const EDomainDisabled: u64 = 9; -const ETokenAmountOverflow: u64 = 10; -const EInvalidMintRecipient: u64 = 11; -const EInvalidFunction: u64 = 12; -const EPoolStillRegistered: u64 = 13; - -// ================================================================ -// | Init | -// ================================================================ - -public fun type_and_version(): String { - string::utf8(b"USDCTokenPool 1.6.0") -} - -#[allow(lint(self_transfer))] -/// USDC token pool must be registered with CCIP Token Admin Registry separately. -/// This is because CCIP does not have access to the `TreasuryCap` for USDC. -public fun initialize( - owner_cap: &mut OwnerCap, - coin_metadata: &CoinMetadata, // this can be provided as an address or in Move.toml - local_domain_identifier: u32, - ctx: &mut TxContext, -) { - let coin_metadata_address = object::id_address(coin_metadata); - assert!(coin_metadata_address == @usdc_coin_metadata_object_id, EInvalidCoinMetadata); - - let ownable_state = ownable::detach_ownable_state(owner_cap); - let mut usdc_token_pool_object = USDCTokenPoolObject { id: object::new(ctx) }; - let usdc_token_pool_state_pointer = USDCTokenPoolStatePointer { - id: object::new(ctx), - usdc_token_pool_object_id: object::id_address(&usdc_token_pool_object), - }; - - let tn = type_name::with_original_ids(); - let package_bytes = ascii::into_bytes(tn.address_string()); - let package_id = address::from_ascii_bytes(&package_bytes); - - let usdc_token_pool = USDCTokenPoolState { - id: derived_object::claim(&mut usdc_token_pool_object.id, b"USDCTokenPoolState"), - token_pool_state: token_pool::initialize( - coin_metadata_address, - coin_metadata.get_decimals(), - coin_metadata.get_symbol(), - vector[], - ctx, - ), - chain_to_domain: table::new(ctx), - local_domain_identifier, - ownable_state, - }; - - transfer::share_object(usdc_token_pool); - transfer::share_object(usdc_token_pool_object); - transfer::transfer(usdc_token_pool_state_pointer, package_id); -} - -// ================================================================ -// | Exposing token_pool functions | -// ================================================================ - -// this now returns the address of coin metadata -public fun get_token(state: &USDCTokenPoolState): address { - token_pool::get_token(&state.token_pool_state) -} - -public fun get_token_decimals(state: &USDCTokenPoolState): u8 { - state.token_pool_state.get_local_decimals() -} - -public fun get_remote_pools( - state: &USDCTokenPoolState, - remote_chain_selector: u64, -): vector> { - token_pool::get_remote_pools(&state.token_pool_state, remote_chain_selector) -} - -public fun is_remote_pool( - state: &USDCTokenPoolState, - remote_chain_selector: u64, - remote_pool_address: vector, -): bool { - token_pool::is_remote_pool( - &state.token_pool_state, - remote_chain_selector, - remote_pool_address, - ) -} - -public fun get_remote_token( - state: &USDCTokenPoolState, - remote_chain_selector: u64, -): vector { - token_pool::get_remote_token(&state.token_pool_state, remote_chain_selector) -} - -public fun add_remote_pool( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - remote_chain_selector: u64, - remote_pool_address: vector, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&state.ownable_state), EInvalidOwnerCap); - token_pool::add_remote_pool( - &mut state.token_pool_state, - remote_chain_selector, - remote_pool_address, - ); -} - -public fun remove_remote_pool( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - remote_chain_selector: u64, - remote_pool_address: vector, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&state.ownable_state), EInvalidOwnerCap); - token_pool::remove_remote_pool( - &mut state.token_pool_state, - remote_chain_selector, - remote_pool_address, - ); -} - -public fun is_supported_chain(state: &USDCTokenPoolState, remote_chain_selector: u64): bool { - token_pool::is_supported_chain(&state.token_pool_state, remote_chain_selector) -} - -public fun get_supported_chains(state: &USDCTokenPoolState): vector { - token_pool::get_supported_chains(&state.token_pool_state) -} - -public fun apply_chain_updates( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - remote_chain_selectors_to_remove: vector, - remote_chain_selectors_to_add: vector, - remote_pool_addresses_to_add: vector>>, - remote_token_addresses_to_add: vector>, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&state.ownable_state), EInvalidOwnerCap); - token_pool::apply_chain_updates( - &mut state.token_pool_state, - remote_chain_selectors_to_remove, - remote_chain_selectors_to_add, - remote_pool_addresses_to_add, - remote_token_addresses_to_add, - ); -} - -public fun get_allowlist_enabled(state: &USDCTokenPoolState): bool { - token_pool::get_allowlist_enabled(&state.token_pool_state) -} - -public fun get_allowlist(state: &USDCTokenPoolState): vector
{ - token_pool::get_allowlist(&state.token_pool_state) -} - -public fun set_allowlist_enabled( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - enabled: bool, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&state.ownable_state), EInvalidOwnerCap); - token_pool::set_allowlist_enabled(&mut state.token_pool_state, enabled); -} - -public fun apply_allowlist_updates( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - removes: vector
, - adds: vector
, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&state.ownable_state), EInvalidOwnerCap); - token_pool::apply_allowlist_updates(&mut state.token_pool_state, removes, adds); -} - -// ================================================================ -// | Burn/Mint | -// ================================================================ - -public struct TypeProof has drop {} - -// This function calculates the package auth caller based on the TypeProof defined in the pool. -// When sending USDC to Sui chain, the destination caller needs to be set to the package auth caller. -// CCTP will validate that the destination caller set by the source chain matches the package auth caller. -// See https://github.com/circlefin/sui-cctp/blob/70290f70d7c3d6caf23a91b379cac08a20f0d762/packages/message_transmitter/sources/receive_message.move#L118-L150 -// and https://developers.circle.com/cctp/sui-packages#destination-callers-for-sui-as-destination-chain for more details. -// This is critical for Sui because we cannot set destination caller to a single CL node. -public fun get_package_auth_caller(): address { - auth_caller_identifier() -} - -public fun lock_or_burn( - ref: &CCIPObjectRef, - token_transfer_params: &mut onramp_sh::TokenTransferParams, - c: Coin, - remote_chain_selector: u64, - clock: &Clock, - deny_list: &DenyList, - pool: &mut USDCTokenPoolState, - state: &MinterState, - message_transmitter_state: &mut MessageTransmitterState, - treasury: &mut Treasury, - ctx: &mut TxContext, -) { - let amount = c.value(); - let sender = ctx.sender(); - let mint_recipient = address::from_bytes(onramp_sh::get_token_receiver(token_transfer_params)); - - assert!(pool.chain_to_domain.contains(remote_chain_selector), EDomainNotFound); - let remote_domain_info = pool.chain_to_domain.borrow(remote_chain_selector); - assert!(remote_domain_info.enabled, EDomainDisabled); - - // This metod validates various aspects of the lock or burn operation. If any of the - // validations fail, the transaction will abort. - let dest_token_address = token_pool::validate_lock_or_burn( - ref, - clock, - &mut pool.token_pool_state, - sender, - remote_chain_selector, - amount, - ); - - let ticket: DepositForBurnWithCallerTicket< - T, - TypeProof, - > = deposit_for_burn::create_deposit_for_burn_with_caller_ticket( - TypeProof {}, - c, - remote_domain_info.domain_identifier, - mint_recipient, - address::from_bytes(remote_domain_info.allowed_caller), - ); - - let (_, msg) = deposit_for_burn::deposit_for_burn_with_caller_with_package_auth( - ticket, - state, - message_transmitter_state, - deny_list, - treasury, - ctx, - ); - - let nonce = message::nonce(&msg); - let source_pool_data = encode_source_pool_data(pool.local_domain_identifier, nonce); - - token_pool::emit_locked_or_burned(&pool.token_pool_state, amount, remote_chain_selector); - - onramp_sh::add_token_transfer_param( - ref, - token_transfer_params, - remote_chain_selector, - amount, - get_token(pool), - dest_token_address, - source_pool_data, - TypeProof {}, - ) -} - -public fun release_or_mint( - ref: &CCIPObjectRef, - receiver_params: &mut offramp_sh::ReceiverParams, - clock: &Clock, - deny_list: &DenyList, - pool: &mut USDCTokenPoolState, - state: &mut MinterState, - message_transmitter_state: &mut MessageTransmitterState, - treasury: &mut Treasury, - ctx: &mut TxContext, -) { - let ( - token_receiver, - remote_chain_selector, - _, - dest_token_address, - _, - source_pool_address, - source_pool_data, - offchain_token_data, - ) = offramp_sh::get_dest_token_transfer_data(receiver_params); - let (message_bytes, attestation) = parse_message_and_attestation(offchain_token_data); - - // Prepare the ReceiveMessageTicket by calling create_receive_message_ticket() from within your package. - let ticket: ReceiveMessageTicket = receive_message::create_receive_message_ticket( - TypeProof {}, - message_bytes, - attestation, - ); - - // Receive the message on MessageTransmitter. - let receipt: Receipt = receive_message::receive_message_with_package_auth( - ticket, - message_transmitter_state, - ); - let (source_domain_identifier, nonce) = decode_source_pool_data(source_pool_data); - // local domain identifier is checked in receive_message_with_package_auth - validate_receipt(&receipt, source_domain_identifier, nonce); - - // Pass the Receipt into TokenMessengerMinter to mint the USDC. - let ticket_with_burn_message = handle_receive_message::handle_receive_message( - receipt, - state, - deny_list, - treasury, - ctx, - ); - - let ( - stamp_receipt_ticket, - burn_message, - ) = handle_receive_message::deconstruct_stamp_receipt_ticket_with_burn_message( - ticket_with_burn_message, - ); - - // Stamp the receipt - let stamped_receipt = receive_message::stamp_receipt( - stamp_receipt_ticket, - message_transmitter_state, - ); - - // Complete the message and destroy the StampedReceipt - receive_message::complete_receive_message(stamped_receipt, message_transmitter_state); - - let mint_recipient = burn_message::mint_recipient(&burn_message); - assert!(mint_recipient == token_receiver, EInvalidMintRecipient); - let local_amount = burn_message::amount(&burn_message); - // local_amount is u64 because the token balance in SUI is u64. - let mut amount_op = local_amount.try_as_u64(); - assert!(amount_op.is_some(), ETokenAmountOverflow); - let amount = amount_op.extract(); - - token_pool::validate_release_or_mint( - ref, - clock, - &mut pool.token_pool_state, - remote_chain_selector, - dest_token_address, - source_pool_address, - amount, - ); - - token_pool::emit_released_or_minted( - &pool.token_pool_state, - token_receiver, - amount, - remote_chain_selector, - ); - - offramp_sh::complete_token_transfer( - ref, - receiver_params, - TypeProof {}, - ); -} - -fun parse_message_and_attestation(payload: vector): (vector, vector) { - let mut stream = eth_abi::new_stream(payload); - - let message = eth_abi::decode_bytes(&mut stream); - let attestation = eth_abi::decode_bytes(&mut stream); - - (message, attestation) -} - -fun encode_source_pool_data(local_domain_identifier: u32, nonce: u64): vector { - let mut source_pool_data = vector[]; - eth_abi::encode_u64(&mut source_pool_data, nonce); - eth_abi::encode_u32(&mut source_pool_data, local_domain_identifier); - source_pool_data -} - -fun decode_source_pool_data(source_pool_data: vector): (u32, u64) { - let mut stream = eth_abi::new_stream(source_pool_data); - let nonce = eth_abi::decode_u64(&mut stream); - let local_domain_identifier = eth_abi::decode_u32(&mut stream); - - (local_domain_identifier, nonce) -} - -fun validate_receipt(receipt: &Receipt, expected_source_domain: u32, expected_nonce: u64) { - let source_domain = receive_message::source_domain(receipt); - let nonce = receive_message::nonce(receipt); - - assert!(source_domain == expected_source_domain, EDomainMismatch); - - assert!(nonce == expected_nonce, ENonceMismatch); -} - -// ================================================================ -// | USDC Domains | -// ================================================================ - -public fun get_domain(pool: &USDCTokenPoolState, chain_selector: u64): Domain { - assert!(pool.chain_to_domain.contains(chain_selector), EDomainNotFound); - *pool.chain_to_domain.borrow(chain_selector) -} - -public fun set_domains( - pool: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - remote_chain_selectors: vector, - remote_domain_identifiers: vector, - allowed_remote_callers: vector>, - enableds: vector, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&pool.ownable_state), EInvalidOwnerCap); - - let number_of_chains = remote_chain_selectors.length(); - - assert!( - number_of_chains == remote_domain_identifiers.length() - && number_of_chains == allowed_remote_callers.length() - && number_of_chains == enableds.length(), - EInvalidArguments, - ); - - let mut i = 0; - while (i < number_of_chains) { - let allowed_caller = allowed_remote_callers[i]; - let domain_identifier = remote_domain_identifiers[i]; - let remote_chain_selector = remote_chain_selectors[i]; - let enabled = enableds[i]; - - assert!(remote_chain_selector != 0, EZeroChainSelector); - - assert!(allowed_caller.length() != 0, EEmptyAllowedCaller); - ccip::address::assert_non_zero_address_vector(&allowed_caller); - - if (pool.chain_to_domain.contains(remote_chain_selector)) { - pool.chain_to_domain.remove(remote_chain_selector); - }; - pool - .chain_to_domain - .add( - remote_chain_selector, - Domain { allowed_caller, domain_identifier, enabled }, - ); - - event::emit(DomainsSet { - allowed_caller, - domain_identifier, - remote_chain_selector, - enabled, - }); - i = i + 1; - }; -} - -public fun mcms_set_domains( - pool: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"set_domains"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(pool), object::id_address(owner_cap)], - &mut stream, - ); - - let remote_chain_selectors = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - let remote_domain_identifiers = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u32(stream), - ); - let allowed_remote_callers = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_vector_u8(stream), - ); - let enableds = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_bool(stream), - ); - bcs_stream::assert_is_consumed(&stream); - - set_domains( - pool, - owner_cap, - remote_chain_selectors, - remote_domain_identifiers, - allowed_remote_callers, - enableds, - ) -} - -// ================================================================ -// | Rate limit config | -// ================================================================ - -public fun set_chain_rate_limiter_configs( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - clock: &Clock, - remote_chain_selectors: vector, - outbound_is_enableds: vector, - outbound_capacities: vector, - outbound_rates: vector, - inbound_is_enableds: vector, - inbound_capacities: vector, - inbound_rates: vector, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&state.ownable_state), EInvalidOwnerCap); - let number_of_chains = remote_chain_selectors.length(); - - assert!( - number_of_chains == outbound_is_enableds.length() - && number_of_chains == outbound_capacities.length() - && number_of_chains == outbound_rates.length() - && number_of_chains == inbound_is_enableds.length() - && number_of_chains == inbound_capacities.length() - && number_of_chains == inbound_rates.length(), - EInvalidArguments, - ); - - let mut i = 0; - while (i < number_of_chains) { - token_pool::set_chain_rate_limiter_config( - clock, - &mut state.token_pool_state, - remote_chain_selectors[i], - outbound_is_enableds[i], - outbound_capacities[i], - outbound_rates[i], - inbound_is_enableds[i], - inbound_capacities[i], - inbound_rates[i], - ); - i = i + 1; - }; -} - -public fun set_chain_rate_limiter_config( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - clock: &Clock, - remote_chain_selector: u64, - outbound_is_enabled: bool, - outbound_capacity: u64, - outbound_rate: u64, - inbound_is_enabled: bool, - inbound_capacity: u64, - inbound_rate: u64, -) { - assert!(object::id(owner_cap) == ownable::owner_cap_id(&state.ownable_state), EInvalidOwnerCap); - token_pool::set_chain_rate_limiter_config( - clock, - &mut state.token_pool_state, - remote_chain_selector, - outbound_is_enabled, - outbound_capacity, - outbound_rate, - inbound_is_enabled, - inbound_capacity, - inbound_rate, - ); -} - -public fun get_current_inbound_rate_limiter_state( - clock: &Clock, - state: &USDCTokenPoolState, - remote_chain_selector: u64, -): TokenBucketWrapper { - let token_bucket = token_pool::get_current_inbound_rate_limiter_state( - &state.token_pool_state, - clock, - remote_chain_selector, - ); - let (tokens, last_updated, is_enabled, capacity, rate) = rate_limiter::get_token_bucket_fields( - &token_bucket, - ); - TokenBucketWrapper { tokens, last_updated, is_enabled, capacity, rate } -} - -public fun get_current_outbound_rate_limiter_state( - clock: &Clock, - state: &USDCTokenPoolState, - remote_chain_selector: u64, -): TokenBucketWrapper { - let token_bucket = token_pool::get_current_outbound_rate_limiter_state( - &state.token_pool_state, - clock, - remote_chain_selector, - ); - let (tokens, last_updated, is_enabled, capacity, rate) = rate_limiter::get_token_bucket_fields( - &token_bucket, - ); - TokenBucketWrapper { tokens, last_updated, is_enabled, capacity, rate } -} - -// ================================================================ -// | Ownable Functions | -// ================================================================ - -public fun owner(state: &USDCTokenPoolState): address { - ownable::owner(&state.ownable_state) -} - -public fun has_pending_transfer(state: &USDCTokenPoolState): bool { - ownable::has_pending_transfer(&state.ownable_state) -} - -public fun pending_transfer_from(state: &USDCTokenPoolState): Option
{ - ownable::pending_transfer_from(&state.ownable_state) -} - -public fun pending_transfer_to(state: &USDCTokenPoolState): Option
{ - ownable::pending_transfer_to(&state.ownable_state) -} - -public fun pending_transfer_accepted(state: &USDCTokenPoolState): Option { - ownable::pending_transfer_accepted(&state.ownable_state) -} - -public fun transfer_ownership( - state: &mut USDCTokenPoolState, - owner_cap: &OwnerCap, - new_owner: address, - ctx: &mut TxContext, -) { - ownable::transfer_ownership(owner_cap, &mut state.ownable_state, new_owner, ctx); -} - -public fun accept_ownership(state: &mut USDCTokenPoolState, ctx: &mut TxContext) { - ownable::accept_ownership(&mut state.ownable_state, ctx); -} - -public fun accept_ownership_from_object( - state: &mut USDCTokenPoolState, - from: &mut UID, - ctx: &mut TxContext, -) { - ownable::accept_ownership_from_object(&mut state.ownable_state, from, ctx); -} - -public fun mcms_accept_ownership( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, - ctx: &mut TxContext, -) { - let data = mcms_registry::get_accept_ownership_data( - registry, - params, - McmsAcceptOwnershipProof {}, - ); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addr(object::id_address(state), &mut stream); - bcs_stream::assert_is_consumed(&stream); - - let mcms = mcms_registry::get_multisig_address(); - ownable::mcms_accept_ownership(&mut state.ownable_state, mcms, ctx); -} - -public fun execute_ownership_transfer( - owner_cap: OwnerCap, - state: &mut USDCTokenPoolState, - to: address, - ctx: &mut TxContext, -) { - ownable::execute_ownership_transfer(owner_cap, &mut state.ownable_state, to, ctx); -} - -public fun execute_ownership_transfer_to_mcms( - owner_cap: OwnerCap, - state: &mut USDCTokenPoolState, - registry: &mut Registry, - to: address, - ctx: &mut TxContext, -) { - let publisher_wrapper = mcms_registry::create_publisher_wrapper( - ownable::borrow_publisher(&owner_cap), - McmsCallback {}, - ); - - ownable::execute_ownership_transfer_to_mcms( - owner_cap, - &mut state.ownable_state, - registry, - to, - publisher_wrapper, - McmsCallback {}, - vector[b"usdc_token_pool"], - ctx, - ); -} - -public fun mcms_register_upgrade_cap( - upgrade_cap: UpgradeCap, - registry: &mut Registry, - state: &mut DeployerState, - ctx: &mut TxContext, -) { - mcms_deployer::register_upgrade_cap( - state, - registry, - upgrade_cap, - ctx, - ); -} - -// ================================================================ -// | MCMS Entrypoint | -// ================================================================ - -public struct McmsCallback has drop {} - -/// Proof for MCMS Accept Ownership -public struct McmsAcceptOwnershipProof has drop {} - -public fun mcms_set_allowlist_enabled( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"set_allowlist_enabled"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap)], - &mut stream, - ); - - let enabled = bcs_stream::deserialize_bool(&mut stream); - bcs_stream::assert_is_consumed(&stream); - - set_allowlist_enabled(state, owner_cap, enabled); -} - -public fun mcms_apply_allowlist_updates( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"apply_allowlist_updates"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap)], - &mut stream, - ); - - let removes = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_address(stream), - ); - let adds = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_address(stream), - ); - bcs_stream::assert_is_consumed(&stream); - - apply_allowlist_updates(state, owner_cap, removes, adds); -} - -public fun mcms_apply_chain_updates( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"apply_chain_updates"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap)], - &mut stream, - ); - - let remote_chain_selectors_to_remove = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - let remote_chain_selectors_to_add = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - let remote_pool_addresses_to_add = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_vector!( - stream, - |stream| bcs_stream::deserialize_vector_u8(stream), - ), - ); - let remote_token_addresses_to_add = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_vector_u8(stream), - ); - bcs_stream::assert_is_consumed(&stream); - - apply_chain_updates( - state, - owner_cap, - remote_chain_selectors_to_remove, - remote_chain_selectors_to_add, - remote_pool_addresses_to_add, - remote_token_addresses_to_add, - ); -} - -public fun mcms_add_remote_pool( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"add_remote_pool"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap)], - &mut stream, - ); - - let remote_chain_selector = bcs_stream::deserialize_u64(&mut stream); - let remote_pool_address = bcs_stream::deserialize_vector_u8(&mut stream); - bcs_stream::assert_is_consumed(&stream); - - add_remote_pool(state, owner_cap, remote_chain_selector, remote_pool_address); -} - -public fun mcms_remove_remote_pool( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"remove_remote_pool"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap)], - &mut stream, - ); - let remote_chain_selector = bcs_stream::deserialize_u64(&mut stream); - let remote_pool_address = bcs_stream::deserialize_vector_u8(&mut stream); - bcs_stream::assert_is_consumed(&stream); - - remove_remote_pool(state, owner_cap, remote_chain_selector, remote_pool_address); -} - -public fun mcms_set_chain_rate_limiter_configs( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, - clock: &Clock, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"set_chain_rate_limiter_configs"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap), object::id_address(clock)], - &mut stream, - ); - - let remote_chain_selectors = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - let outbound_is_enableds = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_bool(stream), - ); - let outbound_capacities = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - let outbound_rates = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - let inbound_is_enableds = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_bool(stream), - ); - let inbound_capacities = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - let inbound_rates = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_u64(stream), - ); - bcs_stream::assert_is_consumed(&stream); - - set_chain_rate_limiter_configs( - state, - owner_cap, - clock, - remote_chain_selectors, - outbound_is_enableds, - outbound_capacities, - outbound_rates, - inbound_is_enableds, - inbound_capacities, - inbound_rates, - ); -} - -public fun mcms_set_chain_rate_limiter_config( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, - clock: &Clock, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"set_chain_rate_limiter_config"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap), object::id_address(clock)], - &mut stream, - ); - - let remote_chain_selector = bcs_stream::deserialize_u64(&mut stream); - let outbound_is_enabled = bcs_stream::deserialize_bool(&mut stream); - let outbound_capacity = bcs_stream::deserialize_u64(&mut stream); - let outbound_rate = bcs_stream::deserialize_u64(&mut stream); - let inbound_is_enabled = bcs_stream::deserialize_bool(&mut stream); - let inbound_capacity = bcs_stream::deserialize_u64(&mut stream); - let inbound_rate = bcs_stream::deserialize_u64(&mut stream); - bcs_stream::assert_is_consumed(&stream); - - set_chain_rate_limiter_config( - state, - owner_cap, - clock, - remote_chain_selector, - outbound_is_enabled, - outbound_capacity, - outbound_rate, - inbound_is_enabled, - inbound_capacity, - inbound_rate, - ); -} - -/// destroy the USDC token pool state and the owner cap -/// this should only be called after unregistering the pool from the token admin registry -public fun destroy_token_pool( - ref: &mut CCIPObjectRef, - state: USDCTokenPoolState, - owner_cap: OwnerCap, - ctx: &mut TxContext, -) { - assert!( - object::id(&owner_cap) == ownable::owner_cap_id(&state.ownable_state), - EInvalidOwnerCap, - ); - assert!( - !token_admin_registry::is_pool_registered(ref, get_token(&state)), - EPoolStillRegistered, - ); - - let USDCTokenPoolState { - id: state_id, - token_pool_state, - chain_to_domain, - local_domain_identifier: _, - ownable_state, - } = state; - token_pool::destroy_token_pool(token_pool_state); - table::drop(chain_to_domain); - object::delete(state_id); - - // Destroy ownable state and owner cap using helper functions - ownable::destroy(ownable_state, owner_cap, ctx); -} - -public fun mcms_destroy_token_pool( - ref: &mut CCIPObjectRef, - state: USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, - ctx: &mut TxContext, -) { - let (_owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"destroy_token_pool"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(ref), object::id_address(&state)], - &mut stream, - ); - - let _to = bcs_stream::deserialize_address(&mut stream); - bcs_stream::assert_is_consumed(&stream); - - let owner_cap = mcms_registry::release_cap, OwnerCap>( - registry, - McmsCallback {}, - ); - - destroy_token_pool(ref, state, owner_cap, ctx); - // Note: USDC token pool destroy_token_pool doesn't return anything -} - -public fun mcms_transfer_ownership( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - params: ExecutingCallbackParams, - ctx: &mut TxContext, -) { - let (owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"transfer_ownership"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(state), object::id_address(owner_cap)], - &mut stream, - ); - - let to = bcs_stream::deserialize_address(&mut stream); - bcs_stream::assert_is_consumed(&stream); - - transfer_ownership(state, owner_cap, to, ctx); -} - -public fun mcms_execute_ownership_transfer( - state: &mut USDCTokenPoolState, - registry: &mut Registry, - deployer_state: &mut DeployerState, - params: ExecutingCallbackParams, - ctx: &mut TxContext, -) { - let (_owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"execute_ownership_transfer"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addrs( - vector[object::id_address(_owner_cap), object::id_address(state)], - &mut stream, - ); - - let to = bcs_stream::deserialize_address(&mut stream); - let package_address = bcs_stream::deserialize_address(&mut stream); - bcs_stream::assert_is_consumed(&stream); - - let owner_cap = mcms_registry::release_cap, OwnerCap>( - registry, - McmsCallback {}, - ); - - if (mcms_deployer::has_upgrade_cap(deployer_state, package_address)) { - let upgrade_cap = mcms_deployer::release_upgrade_cap( - deployer_state, - registry, - McmsCallback {}, - ); - transfer::public_transfer(upgrade_cap, to); - }; - - execute_ownership_transfer(owner_cap, state, to, ctx); -} - -public fun mcms_add_allowed_modules( - registry: &mut Registry, - params: ExecutingCallbackParams, - ctx: &mut TxContext, -) { - let (_owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"add_allowed_modules"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addr(object::id_address(registry), &mut stream); - - let new_module_names = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_vector_u8(stream), - ); - bcs_stream::assert_is_consumed(&stream); - - mcms_registry::add_allowed_modules(registry, McmsCallback {}, new_module_names, ctx); -} - -public fun mcms_remove_allowed_modules( - registry: &mut Registry, - params: ExecutingCallbackParams, - ctx: &mut TxContext, -) { - let (_owner_cap, function, data) = mcms_registry::get_callback_params_with_caps< - McmsCallback, - OwnerCap, - >( - registry, - McmsCallback {}, - params, - ); - assert!(function == string::utf8(b"remove_allowed_modules"), EInvalidFunction); - - let mut stream = bcs_stream::new(data); - bcs_stream::validate_obj_addr(object::id_address(registry), &mut stream); - - let module_names = bcs_stream::deserialize_vector!( - &mut stream, - |stream| bcs_stream::deserialize_vector_u8(stream), - ); - bcs_stream::assert_is_consumed(&stream); - - mcms_registry::remove_allowed_modules(registry, McmsCallback {}, module_names, ctx); -} - -#[test_only] -public fun test_init(ctx: &mut TxContext) { - init(USDC_TOKEN_POOL {}, ctx); -} diff --git a/contracts/contracts.go b/contracts/contracts.go index 16d222224..89f187873 100644 --- a/contracts/contracts.go +++ b/contracts/contracts.go @@ -20,7 +20,6 @@ const ( CCIPRouter = Package("ccip_router") LockReleaseTokenPool = Package("lock_release_token_pool") BurnMintTokenPool = Package("burn_mint_token_pool") - USDCTokenPool = Package("usdc_token_pool") ManagedTokenPool = Package("managed_token_pool") ManagedToken = Package("managed_token") ManagedTokenFaucet = Package("managed_token_faucet") @@ -51,7 +50,6 @@ var Contracts map[Package]string = map[Package]string{ CCIPRouter: filepath.Join("ccip", "ccip_router"), LockReleaseTokenPool: filepath.Join("ccip", "ccip_token_pools", "lock_release_token_pool"), BurnMintTokenPool: filepath.Join("ccip", "ccip_token_pools", "burn_mint_token_pool"), - USDCTokenPool: filepath.Join("ccip", "ccip_token_pools", "usdc_token_pool"), ManagedTokenPool: filepath.Join("ccip", "ccip_token_pools", "managed_token_pool"), ManagedToken: filepath.Join("ccip", "managed_token"), ManagedTokenFaucet: filepath.Join("ccip", "managed_token_faucet"), diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/Move.toml b/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/Move.toml deleted file mode 100644 index 064cff987..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/Move.toml +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2024 Circle Internet Group, Inc. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[package] -name = "stablecoin" -edition = "2024.beta" -license = "Apache 2.0" - -[dependencies.sui_extensions] -local = "../sui_extensions" - -[addresses] -stablecoin = "0x0" - -[dev-dependencies] - -[dev-addresses] diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/entry.move b/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/entry.move deleted file mode 100644 index cc2400d64..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/entry.move +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// This module exposes entry functions for the stablecoin module to support calling functions on -/// wrapped objects from PTBs. Currently PTBs are unable to chain a reference from the output of one -/// function to the input of another, making it difficult to call functions on wrapped objects. -/// This module exposes those functions directly using entry functions. -module stablecoin::entry { - use stablecoin::treasury::Treasury; - - // === Entry Functions === - - /// Start owner role transfer process. - /// - Only callable by the owner. - /// - Only callable if the Treasury object is compatible with this package. - entry fun transfer_ownership(treasury: &mut Treasury, new_owner: address, ctx: &TxContext) { - treasury.assert_is_compatible(); - treasury.roles_mut().owner_role_mut().begin_role_transfer(new_owner, ctx) - } - - /// Finalize owner role transfer process. - /// - Only callable by the pending owner. - /// - Only callable if the Treasury object is compatible with this package. - entry fun accept_ownership(treasury: &mut Treasury, ctx: &TxContext) { - treasury.assert_is_compatible(); - treasury.roles_mut().owner_role_mut().accept_role(ctx) - } - - /// Change the master minter address. - /// - Only callable by the owner. - /// - Only callable if the Treasury object is compatible with this package. - entry fun update_master_minter(treasury: &mut Treasury, new_master_minter: address, ctx: &TxContext) { - treasury.assert_is_compatible(); - treasury.roles_mut().update_master_minter(new_master_minter, ctx) - } - - /// Change the blocklister address. - /// - Only callable by the owner. - /// - Only callable if the Treasury object is compatible with this package. - entry fun update_blocklister(treasury: &mut Treasury, new_blocklister: address, ctx: &TxContext) { - treasury.assert_is_compatible(); - treasury.roles_mut().update_blocklister(new_blocklister, ctx) - } - - /// Change the pauser address. - /// - Only callable by the owner. - /// - Only callable if the Treasury object is compatible with this package. - entry fun update_pauser(treasury: &mut Treasury, new_pauser: address, ctx: &TxContext) { - treasury.assert_is_compatible(); - treasury.roles_mut().update_pauser(new_pauser, ctx) - } - - /// Change the metadata updater address. - /// - Only callable by the owner. - /// - Only callable if the Treasury object is compatible with this package. - entry fun update_metadata_updater(treasury: &mut Treasury, new_metadata_updater: address, ctx: &TxContext) { - treasury.assert_is_compatible(); - treasury.roles_mut().update_metadata_updater(new_metadata_updater, ctx) - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/mint_allowance.move b/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/mint_allowance.move deleted file mode 100644 index 0a9e1f71b..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/mint_allowance.move +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -module stablecoin::mint_allowance { - - const EOverflow: u64 = 0; - const EInsufficientAllowance: u64 = 1; - - /// A MintAllowance for a coin of type T. - /// Used for minting and burning. - public struct MintAllowance has store { - value: u64 - } - - /// [Package private] Gets the current allowance of the MintAllowance object. - public(package) fun value(self: &MintAllowance): u64 { - self.value - } - - /// [Package private] Create a new MintAllowance for type T. - public(package) fun new(): MintAllowance { - MintAllowance { value: 0 } - } - - /// [Package private] Set allowance to `value` - public(package) fun set(self: &mut MintAllowance, value: u64) { - self.value = value; - } - - /// [Package private] Increase the allowance by `value` - public(package) fun increase(self: &mut MintAllowance, value: u64) { - assert!(value < (18446744073709551615u64 - self.value), EOverflow); - self.value = self.value + value; - } - - /// [Package private] Decrease the allowance by `value` - public(package) fun decrease(self: &mut MintAllowance, value: u64) { - assert!(self.value >= value, EInsufficientAllowance); - self.value = self.value - value; - } - - /// [Package private] Destroy object - public(package) fun destroy(self: MintAllowance) { - let MintAllowance { value: _ } = self; - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/roles.move b/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/roles.move deleted file mode 100644 index 533d08deb..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/roles.move +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -module stablecoin::roles { - use sui::bag::{Self, Bag}; - use sui::event; - use sui_extensions::two_step_role::{Self, TwoStepRole}; - - // === Structs === - - public struct Roles has store { - /// A bag that maintains the mapping of privileged roles and their addresses. - /// Keys are structs that are suffixed with _Key. - /// Values are either addresses or objects containing more complex logic. - data: Bag - } - - /// Type used to specify which TwoStepRole the owner role corresponds to. - public struct OwnerRole has drop {} - - /// Key used to map to the mutable TwoStepRole of the owner EOA - public struct OwnerKey {} has copy, store, drop; - /// Key used to map to the mutable address of the master minter EOA, controlled by owner - public struct MasterMinterKey {} has copy, store, drop; - /// Key used to map to the address of the blocklister EOA, controlled by owner - public struct BlocklisterKey {} has copy, store, drop; - /// Key used to map to the address of the pauser EOA, controlled by owner - public struct PauserKey {} has copy, store, drop; - /// Key used to map to the address of the metadata updater EOA, controlled by owner - public struct MetadataUpdaterKey {} has copy, store, drop; - - // === Events === - - public struct MasterMinterChanged has copy, drop { - old_master_minter: address, - new_master_minter: address, - } - - public struct BlocklisterChanged has copy, drop { - old_blocklister: address, - new_blocklister: address, - } - - public struct PauserChanged has copy, drop { - old_pauser: address, - new_pauser: address, - } - - public struct MetadataUpdaterChanged has copy, drop { - old_metadata_updater: address, - new_metadata_updater: address, - } - - // === View-only functions === - - /// [Package private] Gets a mutable reference to the owner's TwoStepRole object. - public(package) fun owner_role_mut(roles: &mut Roles): &mut TwoStepRole> { - roles.data.borrow_mut(OwnerKey {}) - } - - /// [Package private] Gets an immutable reference to the owner's TwoStepRole object. - public(package) fun owner_role(roles: &Roles): &TwoStepRole> { - roles.data.borrow(OwnerKey {}) - } - - /// Gets the current owner address. - public fun owner(roles: &Roles): address { - roles.owner_role().active_address() - } - - /// Gets the pending owner address. - public fun pending_owner(roles: &Roles): Option
{ - roles.owner_role().pending_address() - } - - /// Gets the master minter address. - public fun master_minter(roles: &Roles): address { - *roles.data.borrow(MasterMinterKey {}) - } - - /// Gets the blocklister address. - public fun blocklister(roles: &Roles): address { - *roles.data.borrow(BlocklisterKey {}) - } - - /// Gets the pauser address. - public fun pauser(roles: &Roles): address { - *roles.data.borrow(PauserKey {}) - } - - /// Gets the metadata updater address. - public fun metadata_updater(roles: &Roles): address { - *roles.data.borrow(MetadataUpdaterKey {}) - } - - // === Write functions === - - /// [Package private] Creates and initializes a Roles object. - public(package) fun new( - owner: address, - master_minter: address, - blocklister: address, - pauser: address, - metadata_updater: address, - ctx: &mut TxContext, - ): Roles { - let mut data = bag::new(ctx); - data.add(OwnerKey {}, two_step_role::new(OwnerRole {}, owner)); - data.add(MasterMinterKey {}, master_minter); - data.add(BlocklisterKey {}, blocklister); - data.add(PauserKey {}, pauser); - data.add(MetadataUpdaterKey {}, metadata_updater); - Roles { - data - } - } - - /// [Package private] Change the master minter address. - /// - Only callable by the owner. - public(package) fun update_master_minter(roles: &mut Roles, new_master_minter: address, ctx: &TxContext) { - roles.owner_role().assert_sender_is_active_role(ctx); - - let old_master_minter = roles.update_address(MasterMinterKey {}, new_master_minter); - - event::emit(MasterMinterChanged { - old_master_minter, - new_master_minter - }); - } - - /// [Package private] Change the blocklister address. - /// - Only callable by the owner. - public(package) fun update_blocklister(roles: &mut Roles, new_blocklister: address, ctx: &TxContext) { - roles.owner_role().assert_sender_is_active_role(ctx); - - let old_blocklister = roles.update_address(BlocklisterKey {}, new_blocklister); - - event::emit(BlocklisterChanged { - old_blocklister, - new_blocklister - }); - } - - /// [Package private] Change the pauser address. - /// - Only callable by the owner. - public(package) fun update_pauser(roles: &mut Roles, new_pauser: address, ctx: &TxContext) { - roles.owner_role().assert_sender_is_active_role(ctx); - - let old_pauser = roles.update_address(PauserKey {}, new_pauser); - - event::emit(PauserChanged { - old_pauser, - new_pauser - }); - } - - /// [Package private] Change the metadata updater address. - /// - Only callable by the owner. - public(package) fun update_metadata_updater(roles: &mut Roles, new_metadata_updater: address, ctx: &TxContext) { - roles.owner_role().assert_sender_is_active_role(ctx); - - let old_metadata_updater = roles.update_address(MetadataUpdaterKey {}, new_metadata_updater); - - event::emit(MetadataUpdaterChanged { - old_metadata_updater, - new_metadata_updater - }); - } - - /// Updates an existing simple address role and returns the previously set address. - /// Fails if the key does not exist, or if the previously set value is not an address. - fun update_address(roles: &mut Roles, key: K, new_address: address): address { - let old_address = roles.data.remove(key); - roles.data.add(key, new_address); - old_address - } - - // === Test Only === - - #[test_only] - public(package) fun create_master_minter_changed_event(old_master_minter: address, new_master_minter: address): MasterMinterChanged { - MasterMinterChanged { old_master_minter, new_master_minter } - } - - #[test_only] - public(package) fun create_blocklister_changed_event(old_blocklister: address, new_blocklister: address): BlocklisterChanged { - BlocklisterChanged { old_blocklister, new_blocklister } - } - - #[test_only] - public(package) fun create_pauser_changed_event(old_pauser: address, new_pauser: address): PauserChanged { - PauserChanged { old_pauser, new_pauser } - } - - #[test_only] - public(package) fun create_metadata_updater_changed_event(old_metadata_updater: address, new_metadata_updater: address): MetadataUpdaterChanged { - MetadataUpdaterChanged { old_metadata_updater, new_metadata_updater } - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/stablecoin.move b/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/stablecoin.move deleted file mode 100644 index 67c3c19fd..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/stablecoin.move +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -module stablecoin::stablecoin { - use sui_extensions::upgrade_service; - - public struct STABLECOIN has drop {} - - #[allow(lint(share_owned))] - /// Initializes a shared UpgradeService and sets the - /// transaction's sender as the initial admin. - fun init(witness: STABLECOIN, ctx: &mut TxContext) { - let (upgrade_service, _) = upgrade_service::new( - witness, - ctx.sender() /* admin */, - ctx - ); - transfer::public_share_object(upgrade_service); - } - - #[test_only] - public(package) fun init_for_testing(ctx: &mut TxContext) { - init(STABLECOIN {}, ctx) - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/treasury.move b/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/treasury.move deleted file mode 100644 index 2552dd9d4..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/treasury.move +++ /dev/null @@ -1,779 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -module stablecoin::treasury { - use std::string; - use std::ascii; - use std::u64::{min, max}; - use sui::{ - coin::{ - Self, Coin, CoinMetadata, DenyCapV2, TreasuryCap, - - // returns if address is on the deny list based on the most recent update - deny_list_v2_contains_next_epoch as is_blocklisted, - // returns if the global pause is effective based on the most recent update - deny_list_v2_is_global_pause_enabled_next_epoch as is_paused, - }, - deny_list::{DenyList}, - event, - table::{Self, Table}, - dynamic_object_field as dof, - vec_set::{Self, VecSet} - }; - use stablecoin::mint_allowance::{Self, MintAllowance}; - use stablecoin::roles::{Self, Roles}; - use stablecoin::version_control::{Self, assert_object_version_is_compatible_with_package}; - - // === Errors === - - const EControllerAlreadyConfigured: u64 = 0; - const EDeniedAddress: u64 = 1; - const EDenyCapNotFound: u64 = 2; - const EInsufficientAllowance: u64 = 3; - const ENotBlocklister: u64 = 4; - const ENotController: u64 = 5; - const ENotMasterMinter: u64 = 6; - const ENotMetadataUpdater: u64 = 7; - const ENotPauser: u64 = 8; - const EPaused: u64 = 9; - const ETreasuryCapNotFound: u64 = 10; - const EUnauthorizedMintCap: u64 = 11; - const EZeroAmount: u64 = 12; - - /// Migration related error codes, starting at 100. - const EMigrationStarted: u64 = 100; - const EMigrationNotStarted: u64 = 101; - const EObjectMigrated: u64 = 102; - const ENotPendingVersion: u64 = 103; - - // === Structs === - - /// A versioned Treasury of type `T` that stores: - /// - a TreasuryCap object - /// - a DenyCap object - /// - a set of privileged roles that manages different parts of this object's data - /// - additional configurations related to minting and burning - public struct Treasury has key, store { - id: UID, - /// A map of { controller address => MintCap ID that it controls }. - controllers: Table, - /// A map of { authorized MintCap ID => its MintAllowance }. - mint_allowances: Table>, - /// Mutable privileged role addresses. - roles: Roles, - /// The set of package version numbers that object is compatible with. - compatible_versions: VecSet - } - - /// An object representing the ability to mint up to an allowance - /// specified in the Treasury. - /// The privilege can be revoked by the master minter. - public struct MintCap has key, store { - id: UID, - } - - /// Key for retrieving the `TreasuryCap` stored in a `Treasury` dynamic object field - public struct TreasuryCapKey has copy, store, drop {} - /// Key for retrieving `DenyCap` stored in a `Treasury` dynamic object field - public struct DenyCapKey has copy, store, drop {} - - // === Events === - - public struct MintCapCreated has copy, drop { - mint_cap: ID, - } - - public struct ControllerConfigured has copy, drop { - controller: address, - mint_cap: ID, - } - - public struct ControllerRemoved has copy, drop { - controller: address, - } - - public struct MinterConfigured has copy, drop { - controller: address, - mint_cap: ID, - allowance: u64, - } - - public struct MinterRemoved has copy, drop { - controller: address, - mint_cap: ID, - } - - public struct MinterAllowanceIncremented has copy, drop { - controller: address, - mint_cap: ID, - allowance_increment: u64, - new_allowance: u64, - } - - public struct Mint has copy, drop { - mint_cap: ID, - recipient: address, - amount: u64, - } - - public struct Burn has copy, drop { - mint_cap: ID, - amount: u64, - } - - public struct Blocklisted has copy, drop { - `address`: address - } - - public struct Unblocklisted has copy, drop { - `address`: address - } - - public struct Pause has copy, drop {} - - public struct Unpause has copy, drop {} - - public struct MetadataUpdated has copy, drop { - name: string::String, - symbol: ascii::String, - description: string::String, - icon_url: ascii::String - } - - public struct MigrationStarted has copy, drop { - compatible_versions: vector - } - - public struct MigrationAborted has copy, drop { - compatible_versions: vector - } - - public struct MigrationCompleted has copy, drop { - compatible_versions: vector - } - - // === View-only functions === - - /// Gets an immutable reference to the Roles object. - public fun roles(treasury: &Treasury): &Roles { - &treasury.roles - } - - /// [Package private] Gets a mutable reference to the Roles object. - public(package) fun roles_mut(treasury: &mut Treasury): &mut Roles { - &mut treasury.roles - } - - /// Gets the corresponding MintCap ID attached to a controller address. - /// Returns option::none() when input is not a valid controller - public fun get_mint_cap_id(treasury: &Treasury, controller: address): Option { - if (!treasury.controllers.contains(controller)) return option::none(); - option::some(*treasury.controllers.borrow(controller)) - } - - /// Gets the allowance of a MintCap object. - /// Returns 0 if the MintCap object is unauthorized. - public fun mint_allowance(treasury: &Treasury, mint_cap: ID): u64 { - if (!treasury.is_authorized_mint_cap(mint_cap)) return 0; - treasury.mint_allowances.borrow(mint_cap).value() - } - - /// Returns the total amount of Coin in circulation. - public fun total_supply(treasury: &Treasury): u64 { - treasury.borrow_treasury_cap().total_supply() - } - - /// Checks if a MintCap object is authorized to mint. - public fun is_authorized_mint_cap(treasury: &Treasury, id: ID): bool { - treasury.mint_allowances.contains(id) - } - - /// [Package private] Ensures that TreasuryCap exists. - public(package) fun assert_treasury_cap_exists(treasury: &Treasury) { - assert!(dof::exists_with_type<_, TreasuryCap>(&treasury.id, TreasuryCapKey {}), ETreasuryCapNotFound); - } - - /// [Package private] Ensures that DenyCap exists. - public(package) fun assert_deny_cap_exists(treasury: &Treasury) { - assert!(dof::exists_with_type<_, DenyCapV2>(&treasury.id, DenyCapKey {}), EDenyCapNotFound); - } - - /// Gets the set of package versions that the Treasury object is compatible with. - public fun compatible_versions(treasury: &Treasury): vector { - *treasury.compatible_versions.keys() - } - - /// Checks if an address is a mint controller. - fun is_controller(treasury: &Treasury, controller_addr: address): bool { - treasury.controllers.contains(controller_addr) - } - - // === Write functions === - - /// Creates and initializes a Treasury object of type T, wrapping a - /// TreasuryCap and DenyCapV2 of the same type into it. - public fun new( - treasury_cap: TreasuryCap, - deny_cap: DenyCapV2, - owner: address, - master_minter: address, - blocklister: address, - pauser: address, - metadata_updater: address, - ctx: &mut TxContext - ): Treasury { - let roles = roles::new(owner, master_minter, blocklister, pauser, metadata_updater, ctx); - let mut treasury = Treasury { - id: object::new(ctx), - controllers: table::new(ctx), - mint_allowances: table::new(ctx), - roles, - compatible_versions: vec_set::singleton(version_control::current_version()) - }; - dof::add(&mut treasury.id, TreasuryCapKey {}, treasury_cap); - dof::add(&mut treasury.id, DenyCapKey {}, deny_cap); - treasury - } - - /// Configures a controller of a MintCap object. - /// - Only callable by the master minter. - /// - Only callable if the Treasury object is compatible with this package. - entry fun configure_controller( - treasury: &mut Treasury, - controller: address, - mint_cap_id: ID, - ctx: &TxContext - ) { - treasury.assert_is_compatible(); - assert!(treasury.roles.master_minter() == ctx.sender(), ENotMasterMinter); - assert!(!treasury.is_controller(controller), EControllerAlreadyConfigured); - - treasury.controllers.add(controller, mint_cap_id); - event::emit(ControllerConfigured { - controller, - mint_cap: mint_cap_id - }); - } - - /// Creates a MintCap object. - /// - Only callable by the master minter. - /// - Only callable if the Treasury object is compatible with this package. - fun create_mint_cap( - treasury: &Treasury, - ctx: &mut TxContext - ): MintCap { - treasury.assert_is_compatible(); - assert!(treasury.roles.master_minter() == ctx.sender(), ENotMasterMinter); - let mint_cap = MintCap { id: object::new(ctx) }; - event::emit(MintCapCreated { - mint_cap: object::id(&mint_cap) - }); - mint_cap - } - - /// Convenience function that - /// 1. creates a MintCap - /// 2. configures the controller for this MintCap object - /// 3. transfers the MintCap object to a minter - /// - /// - Only callable by the master minter. - /// - Only callable if the Treasury object is compatible with this package. - entry fun configure_new_controller( - treasury: &mut Treasury, - controller: address, - minter: address, - ctx: &mut TxContext - ) { - let mint_cap = create_mint_cap(treasury, ctx); - configure_controller(treasury, controller, object::id(&mint_cap), ctx); - transfer::transfer(mint_cap, minter) - } - - /// Removes a controller. - /// - Only callable by the master minter. - /// - Only callable if the Treasury object is compatible with this package. - entry fun remove_controller( - treasury: &mut Treasury, - controller: address, - ctx: &TxContext - ) { - treasury.assert_is_compatible(); - assert!(treasury.roles.master_minter() == ctx.sender(), ENotMasterMinter); - assert!(treasury.is_controller(controller), ENotController); - - treasury.controllers.remove(controller); - - event::emit(ControllerRemoved { - controller - }); - } - - /// Authorizes a MintCap object to mint and burn, and sets its allowance. - /// - Only callable by the MintCap's controller. - /// - Only callable when not paused. - /// - Only callable if the Treasury object is compatible with this package. - entry fun configure_minter( - treasury: &mut Treasury, - deny_list: &DenyList, - new_allowance: u64, - ctx: &TxContext - ) { - treasury.assert_is_compatible(); - - assert!(!is_paused(deny_list), EPaused); - - let controller = ctx.sender(); - assert!(treasury.is_controller(controller), ENotController); - - let mint_cap_id = *get_mint_cap_id(treasury, controller).borrow(); - if (!treasury.mint_allowances.contains(mint_cap_id)) { - let mut allowance = mint_allowance::new(); - allowance.set(new_allowance); - treasury.mint_allowances.add(mint_cap_id, allowance); - } else { - treasury.mint_allowances.borrow_mut(mint_cap_id).set(new_allowance); - }; - event::emit(MinterConfigured { - controller, - mint_cap: mint_cap_id, - allowance: new_allowance - }); - } - - /// Increment allowance for a MintCap - /// - Only callable by the MintCap's controller. - /// - Only callable when not paused. - /// - Only callable if the Treasury object is compatible with this package. - entry fun increment_mint_allowance( - treasury: &mut Treasury, - deny_list: &DenyList, - allowance_increment: u64, - ctx: &TxContext - ) { - treasury.assert_is_compatible(); - - assert!(!is_paused(deny_list), EPaused); - assert!(allowance_increment > 0, EZeroAmount); - - let controller = ctx.sender(); - assert!(treasury.is_controller(controller), ENotController); - - let mint_cap_id = *get_mint_cap_id(treasury, controller).borrow(); - assert!(treasury.is_authorized_mint_cap(mint_cap_id), EUnauthorizedMintCap); - - treasury.mint_allowances.borrow_mut(mint_cap_id).increase(allowance_increment); - let new_allowance = treasury.mint_allowances.borrow(mint_cap_id).value(); - - event::emit(MinterAllowanceIncremented { - controller, - mint_cap: mint_cap_id, - allowance_increment, - new_allowance, - }); - } - - /// Deauthorizes a MintCap object. - /// - Only callable by the MintCap's controller. - /// - Only callable if the Treasury object is compatible with this package. - entry fun remove_minter( - treasury: &mut Treasury, - ctx: &TxContext - ) { - treasury.assert_is_compatible(); - - let controller = ctx.sender(); - assert!(treasury.is_controller(controller), ENotController); - - let mint_cap_id = *get_mint_cap_id(treasury, controller).borrow(); - let mint_allowance = treasury.mint_allowances.remove(mint_cap_id); - mint_allowance.destroy(); - event::emit(MinterRemoved { - controller, - mint_cap: mint_cap_id - }); - } - - /// Mints a Coin object with a specified amount (limited to the MintCap's allowance) - /// to a recipient address, increasing the total supply. - /// - Only callable by a minter. - /// - Only callable when not paused. - /// - Only callable if minter is not blocklisted. - /// - Only callable if recipient is not blocklisted. - /// - Only callable if the Treasury object is compatible with this package. - public fun mint( - treasury: &mut Treasury, - mint_cap: &MintCap, - deny_list: &DenyList, - amount: u64, - recipient: address, - ctx: &mut TxContext - ) { - treasury.assert_is_compatible(); - - assert!(!is_paused(deny_list), EPaused); - assert!(!is_blocklisted(deny_list, ctx.sender()), EDeniedAddress); - assert!(!is_blocklisted(deny_list, recipient), EDeniedAddress); - let mint_cap_id = object::id(mint_cap); - assert!(treasury.is_authorized_mint_cap(mint_cap_id), EUnauthorizedMintCap); - assert!(amount > 0, EZeroAmount); - - let mint_allowance = treasury.mint_allowances.borrow_mut(mint_cap_id); - assert!(mint_allowance.value() >= amount, EInsufficientAllowance); - - mint_allowance.decrease(amount); - - treasury.borrow_treasury_cap_mut().mint_and_transfer(amount, recipient, ctx); - - event::emit(Mint { - mint_cap: mint_cap_id, - recipient, - amount, - }); - } - - /// Burns a Coin object, decreasing the total supply. - /// - Only callable by a minter. - /// - Only callable when not paused. - /// - Only callable if minter is not blocklisted. - /// - Only callable if the Treasury object is compatible with this package. - public fun burn( - treasury: &mut Treasury, - mint_cap: &MintCap, - deny_list: &DenyList, - coin: Coin, - ctx: &TxContext - ) { - treasury.assert_is_compatible(); - - assert!(!is_paused(deny_list), EPaused); - assert!(!is_blocklisted(deny_list, ctx.sender()), EDeniedAddress); - let mint_cap_id = object::id(mint_cap); - assert!(treasury.is_authorized_mint_cap(mint_cap_id), EUnauthorizedMintCap); - - let amount = coin.value(); - assert!(amount > 0, EZeroAmount); - - treasury.borrow_treasury_cap_mut().burn(coin); - event::emit(Burn { - mint_cap: mint_cap_id, - amount - }); - } - - /// Blocklists an address. - /// - Only callable by the blocklister. - /// - Only callable if the Treasury object is compatible with this package. - entry fun blocklist( - treasury: &mut Treasury, - deny_list: &mut DenyList, - addr: address, - ctx: &mut TxContext - ) { - treasury.assert_is_compatible(); - assert!(treasury.roles.blocklister() == ctx.sender(), ENotBlocklister); - - if (!is_blocklisted(deny_list, addr)) { - coin::deny_list_v2_add(deny_list, treasury.borrow_deny_cap_mut(), addr, ctx); - }; - event::emit(Blocklisted { - `address`: addr - }) - } - - /// Unblocklists an address. - /// - Only callable by the blocklister. - /// - Only callable if the Treasury object is compatible with this package. - entry fun unblocklist( - treasury: &mut Treasury, - deny_list: &mut DenyList, - addr: address, - ctx: &mut TxContext - ) { - treasury.assert_is_compatible(); - assert!(treasury.roles.blocklister() == ctx.sender(), ENotBlocklister); - - if (is_blocklisted(deny_list, addr)) { - coin::deny_list_v2_remove(deny_list, treasury.borrow_deny_cap_mut(), addr, ctx); - }; - event::emit(Unblocklisted { - `address`: addr - }) - } - - /// Triggers stopped state; pause all transfers. - /// - Only callable by the pauser. - /// - Only callable if the Treasury object is compatible with this package. - entry fun pause( - treasury: &mut Treasury, - deny_list: &mut DenyList, - ctx: &mut TxContext - ) { - treasury.assert_is_compatible(); - - assert!(treasury.roles.pauser() == ctx.sender(), ENotPauser); - let deny_cap = treasury.borrow_deny_cap_mut(); - - if (!is_paused(deny_list)) { - coin::deny_list_v2_enable_global_pause(deny_list, deny_cap, ctx); - }; - event::emit(Pause {}); - } - - /// Restores normal state; unpause all transfers. - /// - Only callable by the pauser. - /// - Only callable if the Treasury object is compatible with this package. - entry fun unpause( - treasury: &mut Treasury, - deny_list: &mut DenyList, - ctx: &mut TxContext - ) { - treasury.assert_is_compatible(); - assert!(treasury.roles().pauser() == ctx.sender(), ENotPauser); - let deny_cap = treasury.borrow_deny_cap_mut(); - - if (is_paused(deny_list)) { - coin::deny_list_v2_disable_global_pause(deny_list, deny_cap, ctx); - }; - event::emit(Unpause {}); - } - - /// Returns an immutable reference of the TreasuryCap. - fun borrow_treasury_cap(treasury: &Treasury): &TreasuryCap { - treasury.assert_treasury_cap_exists(); - dof::borrow(&treasury.id, TreasuryCapKey {}) - } - - /// Returns a mutable reference of the TreasuryCap. - fun borrow_treasury_cap_mut(treasury: &mut Treasury): &mut TreasuryCap { - treasury.assert_treasury_cap_exists(); - dof::borrow_mut(&mut treasury.id, TreasuryCapKey {}) - } - - /// Returns a mutable reference of the DenyCap. - fun borrow_deny_cap_mut(treasury: &mut Treasury): &mut DenyCapV2 { - treasury.assert_deny_cap_exists(); - dof::borrow_mut(&mut treasury.id, DenyCapKey {}) - } - - /// Updates the CoinMetadata object of the same type as the Treasury. - /// - Only callable by the metadata updater. - /// - Only callable if the Treasury object is compatible with this package. - entry fun update_metadata( - treasury: &Treasury, - metadata: &mut CoinMetadata, - name: string::String, - symbol: ascii::String, - description: string::String, - icon_url: ascii::String, - ctx: &TxContext - ) { - treasury.assert_is_compatible(); - assert!(treasury.roles.metadata_updater() == ctx.sender(), ENotMetadataUpdater); - treasury.borrow_treasury_cap().update_name(metadata, name); - treasury.borrow_treasury_cap().update_symbol(metadata, symbol); - treasury.borrow_treasury_cap().update_description(metadata, description); - treasury.borrow_treasury_cap().update_icon_url(metadata, icon_url); - event::emit(MetadataUpdated { - name, - symbol, - description, - icon_url - }) - } - - /// Starts the migration process, making the Treasury object be - /// additionally compatible with this package's version. - entry fun start_migration(treasury: &mut Treasury, ctx: &TxContext) { - treasury.roles.owner_role().assert_sender_is_active_role(ctx); - assert!(treasury.compatible_versions.size() == 1, EMigrationStarted); - - let active_version = treasury.compatible_versions.keys()[0]; - assert!(active_version < version_control::current_version(), EObjectMigrated); - - treasury.compatible_versions.insert(version_control::current_version()); - - event::emit(MigrationStarted { - compatible_versions: *treasury.compatible_versions.keys() - }); - } - - /// Aborts the migration process, reverting the Treasury object's compatibility - /// to the previous version. - entry fun abort_migration(treasury: &mut Treasury, ctx: &TxContext) { - treasury.roles.owner_role().assert_sender_is_active_role(ctx); - assert!(treasury.compatible_versions.size() == 2, EMigrationNotStarted); - - let pending_version = max( - treasury.compatible_versions.keys()[0], - treasury.compatible_versions.keys()[1] - ); - assert!(pending_version == version_control::current_version(), ENotPendingVersion); - - treasury.compatible_versions.remove(&pending_version); - - event::emit(MigrationAborted { - compatible_versions: *treasury.compatible_versions.keys() - }); - } - - /// Completes the migration process, making the Treasury object be - /// only compatible with this package's version. - entry fun complete_migration(treasury: &mut Treasury, ctx: &TxContext) { - treasury.roles.owner_role().assert_sender_is_active_role(ctx); - assert!(treasury.compatible_versions.size() == 2, EMigrationNotStarted); - - let (version_a, version_b) = (treasury.compatible_versions.keys()[0], treasury.compatible_versions.keys()[1]); - let (active_version, pending_version) = (min(version_a, version_b), max(version_a, version_b)); - - assert!(pending_version == version_control::current_version(), ENotPendingVersion); - - treasury.compatible_versions.remove(&active_version); - - event::emit(MigrationCompleted { - compatible_versions: *treasury.compatible_versions.keys() - }); - } - - // === Assertions === - - /// [Package private] Asserts that the Treasury object - /// is compatible with the package's version. - public(package) fun assert_is_compatible(treasury: &Treasury) { - assert_object_version_is_compatible_with_package(treasury.compatible_versions); - } - - // === Test Only === - - #[test_only] - public(package) fun get_controllers_for_testing(treasury: &Treasury): &Table { - &treasury.controllers - } - - #[test_only] - public(package) fun get_mint_allowances_for_testing(treasury: &Treasury): &Table> { - &treasury.mint_allowances - } - - #[test_only] - public(package) fun get_deny_cap_for_testing(treasury: &mut Treasury): &mut DenyCapV2 { - treasury.borrow_deny_cap_mut() - } - - #[test_only] - public(package) fun remove_treasury_cap_for_testing(treasury: &mut Treasury): TreasuryCap { - dof::remove(&mut treasury.id, TreasuryCapKey {}) - } - - #[test_only] - public(package) fun remove_deny_cap_for_testing(treasury: &mut Treasury): DenyCapV2 { - dof::remove(&mut treasury.id, DenyCapKey {}) - } - - #[test_only] - public(package) fun create_mint_cap_for_testing(ctx: &mut TxContext): MintCap { - MintCap { id: object::new(ctx) } - } - - #[test_only] - public(package) fun set_compatible_versions_for_testing(treasury: &mut Treasury, compatible_versions: VecSet) { - treasury.compatible_versions = compatible_versions; - } - - #[test_only] - public(package) fun create_mint_cap_created_event(mint_cap: ID): MintCapCreated { - MintCapCreated { mint_cap } - } - - #[test_only] - public(package) fun create_controller_configured_event(controller: address, mint_cap: ID): ControllerConfigured { - ControllerConfigured { controller, mint_cap } - } - - #[test_only] - public(package) fun create_controller_removed_event(controller: address): ControllerRemoved { - ControllerRemoved { controller } - } - - #[test_only] - public(package) fun create_minter_configured_event(controller: address, mint_cap: ID, allowance: u64): MinterConfigured { - MinterConfigured { controller, mint_cap, allowance } - } - - #[test_only] - public(package) fun create_minter_allowance_incremented_event( - controller: address, - mint_cap: ID, - allowance_increment: u64, - new_allowance: u64 - ): MinterAllowanceIncremented { - MinterAllowanceIncremented { controller, mint_cap, allowance_increment, new_allowance } - } - - #[test_only] - public(package) fun create_minter_removed_event(controller: address, mint_cap: ID): MinterRemoved { - MinterRemoved { controller, mint_cap } - } - - #[test_only] - public(package) fun create_mint_event(mint_cap: ID, recipient: address, amount: u64): Mint { - Mint { mint_cap, recipient, amount } - } - - #[test_only] - public(package) fun create_burn_event(mint_cap: ID, amount: u64): Burn { - Burn { mint_cap, amount } - } - - #[test_only] - public(package) fun create_blocklisted_event(`address`: address): Blocklisted { - Blocklisted { `address` } - } - - #[test_only] - public(package) fun create_unblocklisted_event(`address`: address): Unblocklisted { - Unblocklisted { `address` } - } - - #[test_only] - public(package) fun create_migration_started_event(compatible_versions: vector): MigrationStarted { - MigrationStarted { compatible_versions } - } - - #[test_only] - public(package) fun create_migration_aborted_event(compatible_versions: vector): MigrationAborted { - MigrationAborted { compatible_versions } - } - - #[test_only] - public(package) fun create_migration_completed_event(compatible_versions: vector): MigrationCompleted { - MigrationCompleted { compatible_versions } - } - - #[test_only] - public(package) fun create_metadata_updated_event( - name: string::String, - symbol: ascii::String, - description: string::String, - icon_url: ascii::String - ): MetadataUpdated { - MetadataUpdated { - name, - symbol, - description, - icon_url - } - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/version_control.move b/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/version_control.move deleted file mode 100644 index 41b4f6e33..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/stablecoin/sources/version_control.move +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -module stablecoin::version_control { - use sui::vec_set::VecSet; - - /// The current version of the package. - const VERSION: u64 = 1; - - // === Errors === - const EIncompatibleVersion: u64 = 0; - - // === Methods === - - /// Gets the current package's version. - public fun current_version(): u64 { - VERSION - } - - /// [Package private] Asserts that an object's compatible version set is - /// compatible with the current package's version. - public(package) fun assert_object_version_is_compatible_with_package(compatible_versions: VecSet) { - assert!(compatible_versions.contains(¤t_version()), EIncompatibleVersion); - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/Move.toml b/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/Move.toml deleted file mode 100644 index 9413b8d22..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/Move.toml +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2024 Circle Internet Group, Inc. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[package] -name = "sui_extensions" -edition = "2024.beta" -license = "Apache 2.0" - -[addresses] -sui_extensions = "0x0" - -[dev-dependencies] - -[dev-addresses] diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/two_step_role.move b/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/two_step_role.move deleted file mode 100644 index a62862668..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/two_step_role.move +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// Module containing basic role management functionality, -/// including a two-step transfer process. -/// This module controls the role via address storage (as opposed -/// to using Capabilities) for cases when using Capabilities are not desired. -/// The two-step transfer process ensures the role is never transferred to an -/// inaccesible address. -/// If access to the active_address EOA is lost, this role can not be transferred. -/// -/// Inspired by OpenZeppelin's Ownable2Step in Solidity: -/// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable2Step.sol. -module sui_extensions::two_step_role { - use sui::event; - - // === Errors === - - const ESenderNotActiveRole: u64 = 0; - const EPendingAddressNotSet: u64 = 1; - const ESenderNotPendingAddress: u64 = 2; - - // === Structs === - - public struct TwoStepRole has store { - active_address: address, - pending_address: Option
- } - - // === Events === - - public struct RoleTransferStarted has copy, drop { - old_address: address, - new_address: address, - } - - public struct RoleTransferred has copy, drop { - old_address: address, - new_address: address, - } - - // === View-only functions === - - /// Gets the active address of the TwoStepRole. - public fun active_address(role: &TwoStepRole): address { - role.active_address - } - - /// Gets the optional, pending address of the TwoStepRole. May be - /// empty if there is no ongoing role transfer. - public fun pending_address(role: &TwoStepRole): Option
{ - role.pending_address - } - - /// Asserts that the transaction sender EOA is the active_address stored on the Role. - /// Aborts with error otherwise. - public fun assert_sender_is_active_role(role: &TwoStepRole, ctx: &TxContext) { - assert!(role.active_address == ctx.sender(), ESenderNotActiveRole); - } - - // === Write functions === - - /// Creates and initializes a TwoStepRole object. - public fun new(_witness: T, active_address: address): TwoStepRole { - TwoStepRole { - active_address, - pending_address: option::none(), - } - } - - /// Start the role transfer. Must be followed by an accept_role call by the new_address EOA. - /// A transfer can be aborted by starting another role transfer process - /// to the current active address and accepting the role. - /// - /// - Only callable by the active address. - public fun begin_role_transfer( - role: &mut TwoStepRole, - new_address: address, - ctx: &TxContext - ) { - role.assert_sender_is_active_role(ctx); - - role.pending_address = option::some(new_address); - - event::emit(RoleTransferStarted { - old_address: role.active_address, - new_address, - }); - } - - /// Complete the role transfer by accepting the role. - /// - Only callable by the pending address. - public fun accept_role( - role: &mut TwoStepRole, - ctx: &TxContext - ) { - assert!(role.pending_address.is_some(), EPendingAddressNotSet); - assert!(role.pending_address.contains(&ctx.sender()), ESenderNotPendingAddress); - - let old_address = role.active_address; - role.active_address = role.pending_address.extract(); - - event::emit(RoleTransferred { - old_address, - new_address: role.active_address - }); - } - - /// Destroys a TwoStepRole object. - public fun destroy(role: TwoStepRole) { - let TwoStepRole { active_address: _, pending_address: _ } = role; - } - - // === Test Only === - - #[test_only] - public fun create_role_transfer_started_event(old_address: address, new_address: address): RoleTransferStarted { - RoleTransferStarted { old_address, new_address } - } - - #[test_only] - public fun create_role_transferred_event(old_address: address, new_address: address): RoleTransferred { - RoleTransferred { old_address, new_address } - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/upgrade_service.move b/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/upgrade_service.move deleted file mode 100644 index cc1a3c217..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/sui_extensions/sources/upgrade_service.move +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -module sui_extensions::upgrade_service { - use sui::{ - address, - dynamic_object_field as dof, - event, - package::{ - UpgradeTicket, - UpgradeReceipt, - UpgradeCap - }, - types::is_one_time_witness - }; - use sui_extensions::two_step_role::{Self, TwoStepRole}; - use std::type_name; - - // === Errors === - - const ENotOneTimeWitness: u64 = 0; - const ETypeNotFromPackage: u64 = 1; - const EUpgradeCapDoesNotExist: u64 = 2; - const EUpgradeCapExists: u64 = 3; - - // === Structs === - - /// An `UpgradeService` that stores an `UpgradeCap` and delegates access of - /// the capability object to an `admin` address. - /// - /// The type must be a One-Time Witness type that comes - /// from the package that the `UpgradeCap` controls. - public struct UpgradeService has key, store { - id: UID, - /// A mutable `TwoStepRole` representing the admin address that is - /// able to perform upgrades using the `UpgradeCap` that this service custodies. - admin: TwoStepRole> - } - - /// Key for retrieving the `UpgradeCap` stored in an `UpgradeService` dynamic object field. - public struct UpgradeCapKey has copy, store, drop {} - - /// Type used to specify which `TwoStepRole` the admin role corresponds to. - public struct AdminRole has drop {} - - // === Events === - - public struct UpgradeCapDeposited has copy, drop { - upgrade_cap_id: ID - } - - public struct UpgradeCapExtracted has copy, drop { - upgrade_cap_id: ID - } - - public struct UpgradeServiceDestroyed has copy, drop {} - - public struct AuthorizeUpgrade has copy, drop { - package_id: ID, - policy: u8 - } - - public struct CommitUpgrade has copy, drop { - package_id: ID - } - - // === View-only functions === - - /// The ID of the package that the stored `UpgradeCap` authorizes upgrades for. - /// Can be `0x0` if the cap cannot currently authorize an upgrade because there is - /// already a pending upgrade in the transaction. Otherwise guaranteed to be the - /// latest version of any given package. - public fun upgrade_cap_package(upgrade_service: &UpgradeService): ID { - upgrade_service.assert_upgrade_cap_exists(); - upgrade_service.borrow_upgrade_cap().package() - } - - /// The most recent version of the package that the stored `UpgradeCap` manages, - /// increments by one for each successfully applied upgrade. - public fun upgrade_cap_version(upgrade_service: &UpgradeService): u64 { - upgrade_service.assert_upgrade_cap_exists(); - upgrade_service.borrow_upgrade_cap().version() - } - - /// The most permissive kind of upgrade currently supported by the stored `UpgradeCap`. - public fun upgrade_cap_policy(upgrade_service: &UpgradeService): u8 { - upgrade_service.assert_upgrade_cap_exists(); - upgrade_service.borrow_upgrade_cap().policy() - } - - /// Gets the current admin address. - public fun admin(upgrade_service: &UpgradeService): address { - upgrade_service.admin.active_address() - } - - /// Gets the pending admin address. - public fun pending_admin(upgrade_service: &UpgradeService): Option
{ - upgrade_service.admin.pending_address() - } - - // === Write functions === - - /// Creates an `UpgradeService` object, initializing the admin role to - /// the predefined admin address. - public fun new(witness: T, admin: address, ctx: &mut TxContext): (UpgradeService, T) { - assert!(is_one_time_witness(&witness), ENotOneTimeWitness); - let upgrade_service = UpgradeService { - id: object::new(ctx), - admin: two_step_role::new(AdminRole {}, admin) - }; - (upgrade_service, witness) - } - - /// Performs a one-time deposit of an `UpgradeCap` into an `UpgradeService`. - /// `UpgradeCap` must control the package that `T` is defined in. - /// - Only callable if the `UpgradeCap` has not been used for an upgrade. - entry fun deposit(upgrade_service: &mut UpgradeService, upgrade_cap: UpgradeCap) { - let package_address_of_type = address::from_ascii_bytes( - type_name::get_with_original_ids().get_address().as_bytes() - ); - let package_address_of_upgrade_cap = &upgrade_cap.package().to_address(); - assert!(package_address_of_type == package_address_of_upgrade_cap, ETypeNotFromPackage); - - upgrade_service.assert_upgrade_cap_does_not_exist(); - let upgrade_cap_id = object::id(&upgrade_cap); - upgrade_service.add_upgrade_cap(upgrade_cap); - - event::emit(UpgradeCapDeposited { - upgrade_cap_id - }); - } - - /// Extracts the stored `UpgradeCap` and transfers it to a recipient address. - /// - Only callable by the admin. - entry fun extract(upgrade_service: &mut UpgradeService, recipient: address, ctx: &TxContext) { - upgrade_service.admin.assert_sender_is_active_role(ctx); - upgrade_service.assert_upgrade_cap_exists(); - - let upgrade_cap = remove_upgrade_cap(upgrade_service); - let upgrade_cap_id = object::id(&upgrade_cap); - - transfer::public_transfer(upgrade_cap, recipient); - - event::emit(UpgradeCapExtracted { - upgrade_cap_id - }); - } - - /// Permanently destroys the `UpgradeService`. - /// - Only callable by the admin. - entry fun destroy_empty(upgrade_service: UpgradeService, ctx: &TxContext) { - upgrade_service.admin.assert_sender_is_active_role(ctx); - upgrade_service.assert_upgrade_cap_does_not_exist(); - - let UpgradeService { id, admin } = upgrade_service; - id.delete(); - admin.destroy(); - - event::emit(UpgradeServiceDestroyed {}); - } - - /// Start admin role transfer process. - /// - Only callable by the admin. - entry fun change_admin(upgrade_service: &mut UpgradeService, new_admin: address, ctx: &TxContext) { - upgrade_service.admin.begin_role_transfer(new_admin, ctx) - } - - /// Finalize admin role transfer process. - /// - Only callable by the pending admin. - entry fun accept_admin(upgrade_service: &mut UpgradeService, ctx: &TxContext) { - upgrade_service.admin.accept_role(ctx) - } - - /// Issues an `UpgradeTicket` that authorizes the upgrade to a package content with `digest` - /// for the package that the stored `UpgradeCap` manages. - /// - Only callable by the admin. - public fun authorize_upgrade( - upgrade_service: &mut UpgradeService, - policy: u8, - digest: vector, - ctx: &TxContext - ): UpgradeTicket { - upgrade_service.admin.assert_sender_is_active_role(ctx); - upgrade_service.assert_upgrade_cap_exists(); - - let package_id_before_authorization = upgrade_service.borrow_upgrade_cap().package(); - let upgrade_ticket = upgrade_service.borrow_upgrade_cap_mut().authorize(policy, digest); - - event::emit(AuthorizeUpgrade { - package_id: package_id_before_authorization, - policy - }); - - upgrade_ticket - } - - /// Consumes an `UpgradeReceipt` to update the stored `UpgradeCap`, - /// finalizing the upgrade. - /// - Only callable by the admin. - public fun commit_upgrade( - upgrade_service: &mut UpgradeService, - receipt: UpgradeReceipt, - ctx: &TxContext - ) { - upgrade_service.admin.assert_sender_is_active_role(ctx); - upgrade_service.assert_upgrade_cap_exists(); - - let new_package_id = receipt.package(); - upgrade_service.borrow_upgrade_cap_mut().commit(receipt); - - event::emit(CommitUpgrade { - package_id: new_package_id - }); - } - - // === Helper functions === - - /// Stores an `UpgradeCap` in a dynamic object field on an `UpgradeService`. - fun add_upgrade_cap(upgrade_service: &mut UpgradeService, upgrade_cap: UpgradeCap) { - dof::add(&mut upgrade_service.id, UpgradeCapKey {}, upgrade_cap); - } - - /// Returns an immutable reference to the `UpgradeCap` stored in a `UpgradeService`. - fun borrow_upgrade_cap(upgrade_service: &UpgradeService): &UpgradeCap { - dof::borrow(&upgrade_service.id, UpgradeCapKey {}) - } - - /// Returns a mutable reference to the `UpgradeCap` stored in a `UpgradeService`. - fun borrow_upgrade_cap_mut(upgrade_service: &mut UpgradeService): &mut UpgradeCap { - dof::borrow_mut(&mut upgrade_service.id, UpgradeCapKey {}) - } - - /// Removes an `UpgradeCap` that is stored in an `UpgradeService` - fun remove_upgrade_cap(upgrade_service: &mut UpgradeService): UpgradeCap { - dof::remove(&mut upgrade_service.id, UpgradeCapKey {}) - } - - /// Ensures that an `UpgradeCap` exists in an `UpgradeService`. - fun assert_upgrade_cap_exists(upgrade_service: &UpgradeService) { - assert!(upgrade_service.exists_upgrade_cap(), EUpgradeCapDoesNotExist); - } - - /// Ensures that an `UpgradeCap` does not exist in an `UpgradeService`. - fun assert_upgrade_cap_does_not_exist(upgrade_service: &UpgradeService) { - assert!(!upgrade_service.exists_upgrade_cap(), EUpgradeCapExists); - } - - /// Checks whether an `UpgradeCap` exists in an `UpgradeService`. - public(package) fun exists_upgrade_cap(upgrade_service: &UpgradeService): bool { - dof::exists_with_type<_, UpgradeCap>(&upgrade_service.id, UpgradeCapKey {}) - } - - // === Test Only === - - #[test_only] - public(package) fun add_upgrade_cap_for_testing(upgrade_service: &mut UpgradeService, upgrade_cap: UpgradeCap) { - add_upgrade_cap(upgrade_service, upgrade_cap) - } - - #[test_only] - public(package) fun borrow_upgrade_cap_for_testing(upgrade_service: &UpgradeService): &UpgradeCap { - upgrade_service.borrow_upgrade_cap() - } - - #[test_only] - public(package) fun borrow_upgrade_cap_mut_for_testing(upgrade_service: &mut UpgradeService): &mut UpgradeCap { - upgrade_service.borrow_upgrade_cap_mut() - } - - #[test_only] - public(package) fun create_upgrade_cap_deposited_event(upgrade_cap_id: ID): UpgradeCapDeposited { - UpgradeCapDeposited { upgrade_cap_id } - } - - #[test_only] - public(package) fun create_upgrade_cap_extracted_event(upgrade_cap_id: ID): UpgradeCapExtracted { - UpgradeCapExtracted { upgrade_cap_id } - } - - #[test_only] - public(package) fun create_authorize_upgrade_event(package_id: ID, policy: u8): AuthorizeUpgrade { - AuthorizeUpgrade { package_id, policy } - } - - #[test_only] - public(package) fun create_commit_upgrade_event(package_id: ID): CommitUpgrade { - CommitUpgrade { package_id } - } -} diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/usdc/Move.toml b/contracts/vendored/circlefin/stablecoin-sui/packages/usdc/Move.toml deleted file mode 100644 index b350611bc..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/usdc/Move.toml +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2024 Circle Internet Group, Inc. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[package] -name = "usdc" -edition = "2024.beta" -license = "Apache 2.0" - -[dependencies.stablecoin] -local = "../stablecoin" - -[dependencies.sui_extensions] -local = "../sui_extensions" - -[addresses] -usdc = "0x0" - -[dev-dependencies] - -[dev-addresses] diff --git a/contracts/vendored/circlefin/stablecoin-sui/packages/usdc/sources/usdc.move b/contracts/vendored/circlefin/stablecoin-sui/packages/usdc/sources/usdc.move deleted file mode 100644 index ea2da7c73..000000000 --- a/contracts/vendored/circlefin/stablecoin-sui/packages/usdc/sources/usdc.move +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2024 Circle Internet Group, Inc. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -module usdc::usdc { - use std::ascii::string; - use sui::coin; - use sui::url; - use stablecoin::treasury; - use sui_extensions::upgrade_service; - - /// The One-Time Witness struct for the USDC coin. - public struct USDC has drop {} - - // === Constants === - - const DESCRIPTION: vector = b"USDC is a US dollar-backed stablecoin issued by Circle. USDC is designed to provide a faster, safer, and more efficient way to send, spend, and exchange money around the world."; - const ICON_URL: vector = b"https://www.circle.com/hubfs/Brand/USDC/USDC_icon_32x32.png"; - - #[allow(lint(share_owned))] - /// Initializes - /// - A shared Treasury object - /// - A shared UpgradeService object - fun init(witness: USDC, ctx: &mut TxContext) { - let (upgrade_service, witness) = upgrade_service::new( - witness, - ctx.sender() /* admin */, - ctx - ); - - let (treasury_cap, deny_cap, metadata) = coin::create_regulated_currency_v2( - witness, - 6, // decimals - b"USDC", // symbol - b"USDC", // name - DESCRIPTION, - option::some(url::new_unsafe(string(ICON_URL))), - true, // allow global pause - ctx - ); - - let treasury = treasury::new( - treasury_cap, - deny_cap, - ctx.sender(), // owner - ctx.sender(), // master minter - ctx.sender(), // blocklister - ctx.sender(), // pauser - ctx.sender(), // metadata updater - ctx - ); - - transfer::public_share_object(metadata); - transfer::public_share_object(treasury); - transfer::public_share_object(upgrade_service); - } - - #[test_only] - public(package) fun init_for_testing(ctx: &mut TxContext) { - init(USDC {}, ctx) - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/Move.toml b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/Move.toml deleted file mode 100644 index 3938e163b..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/Move.toml +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[package] -name = "MessageTransmitter" -edition = "2024.beta" -license = "Apache 2.0" - -[dependencies.sui_extensions] -local = "../../../stablecoin-sui/packages/sui_extensions" - -[addresses] -message_transmitter = "_" - -[dev-dependencies] - -[dev-addresses] -message_transmitter = "0x4931e06dce648b3931f890035bd196920770e913e43e45990b383f6486fdd0a5" diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/attester_manager.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/attester_manager.move deleted file mode 100644 index 96f319ab9..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/attester_manager.move +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: attester_manager -/// Admin functions for attester_manager functionality, including managing -/// signature threshold and enabled/disabled attesters. -module message_transmitter::attester_manager { - // === Imports === - use sui::event::emit; - use message_transmitter::{ - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const EAttesterAlreadyEnabled: u64 = 0; - const EAttesterNotEnabled: u64 = 1; - const ENotAttesterManager: u64 = 2; - const ETooFewAttestersEnabled: u64 = 3; - const ETooFewEnabledAttesters: u64 = 4; - const ESignatureThresholdAlreadySet: u64 = 5; - const ESignatureThresholdTooHigh: u64 = 6; - const EInvalidSignatureThreshold: u64 = 7; - - // === Events === - public struct SignatureThresholdUpdated has copy, drop { - old_signature_threshold: u64, - new_signature_threshold: u64 - } - - public struct AttesterEnabled has copy, drop { - attester: address, - } - - public struct AttesterDisabled has copy, drop { - attester: address, - } - - // === Admin Functions === - - /// Called by the attester manager to enable a new attester. - /// Requires that the new attester is currently not enabled. - /// Calls a public(package) function so that this function can be - /// entry visibility while still allowing the initialize module to call enable_attester_internal. - entry fun enable_attester(new_attester: address, state: &mut State, ctx: &TxContext) { - enable_attester_internal(new_attester, state, ctx); - } - - /// Called by the attester manager to disable an attester. - /// Requires that the attester is currently enabled. Disabling the attester is not allowed - /// if there is only one attester enabled or if it would cause the number of attesters - /// to become less than the signature threshold. - entry fun disable_attester(attester: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_attester_manager(state, ctx); - let num_enabled_attesters: u64 = state.get_num_enabled_attesters(); - assert!((num_enabled_attesters > 1), ETooFewAttestersEnabled); - assert!((num_enabled_attesters > state.signature_threshold()), ETooFewEnabledAttesters); - assert!(state.is_attester_enabled(attester), EAttesterNotEnabled); - - state.disable_attester(attester); - emit(AttesterDisabled { attester }); - } - - /// Called by the attester manager to set the number of signatures required to attest to a message. - /// Requires that the new signature threshold is nonzero, not equal to the current threshold, and - /// does not exceed the number of enabled attesters. - entry fun set_signature_threshold(new_signature_threshold: u64, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_attester_manager(state, ctx); - assert!(new_signature_threshold != 0, EInvalidSignatureThreshold); - assert!((new_signature_threshold <= state.get_num_enabled_attesters()), ESignatureThresholdTooHigh); - assert!(new_signature_threshold != state.signature_threshold(), ESignatureThresholdAlreadySet); - - let old_signature_threshold = state.signature_threshold(); - state.set_signature_threshold(new_signature_threshold); - emit(SignatureThresholdUpdated {old_signature_threshold, new_signature_threshold}); - } - - // === Public(Package) functions === - - /// Called by the attester manager to enable a new attester. - /// Requires that the new attester is currently not enabled. - public(package) fun enable_attester_internal(new_attester: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_attester_manager(state, ctx); - assert!(!state.is_attester_enabled(new_attester), EAttesterAlreadyEnabled); - - state.enable_attester(new_attester); - emit(AttesterEnabled { attester: new_attester }); - } - - // === Private Functions === - - fun verify_attester_manager(state: &State, ctx: &TxContext) { - assert!(ctx.sender() == state.roles().attester_manager(), ENotAttesterManager); - } - - // === Test Functions === - #[test_only] use sui::{event::{num_events}, test_scenario, test_utils}; - #[test_only] use message_transmitter::{ - state, - version_control - }; - #[test_only] use sui_extensions::test_utils::last_event_by_type; - - // === Tests === - - // enable_attester tests - - #[test] - public fun test_enable_attester_successful() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, new_attester) = (@0x1, @0x2); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Successfully enabled attester - scenario.next_tx(attester_manager); - { - enable_attester(new_attester, &mut state, scenario.ctx()); - assert!(state.is_attester_enabled(new_attester)); - assert!(num_events() == 1); - assert!(last_event_by_type().attester == new_attester); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotAttesterManager)] - public fun test_enable_attester_revert_not_attester_manager() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, non_attester_manager, new_attester) = (@0x1, @0x2, @0x3); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if the caller is not the attester manager - scenario.next_tx(non_attester_manager); - { - enable_attester(new_attester, &mut state, scenario.ctx()); - assert!(!state.is_attester_enabled(new_attester)); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EAttesterAlreadyEnabled)] - public fun test_enable_attester_revert_already_enabled() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, new_attester) = (@0x1, @0x2); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if the attester is already enabled - scenario.next_tx(attester_manager); - { - enable_attester(new_attester, &mut state, scenario.ctx()); - assert!(state.is_attester_enabled(new_attester)); - enable_attester(new_attester, &mut state, scenario.ctx()); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_enable_attester_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, new_attester) = (@0x1, @0x2); - - // Create a new State instance with incompatible state - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if the version is incompatible - { - enable_attester(new_attester, &mut state, scenario.ctx()); - assert!(!state.is_attester_enabled(new_attester)); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // disable_attester tests - - #[test] - public fun test_disable_attester_successful() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, first_attester, second_attester) = (@0x1, @0x2, @0x3); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Successfully disabled attester - scenario.next_tx(attester_manager); - { - enable_attester(first_attester, &mut state, scenario.ctx()); - enable_attester(second_attester, &mut state, scenario.ctx()); - disable_attester(second_attester, &mut state, scenario.ctx()); - assert!(!state.is_attester_enabled(second_attester)); - assert!(num_events() == 3); - assert!(last_event_by_type().attester == second_attester); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotAttesterManager)] - public fun test_disable_attester_revert_not_attester_manager() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, non_attester_manager, attester) = (@0x1, @0x2, @0x3); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Enable attesters - scenario.next_tx(attester_manager); - { - enable_attester(attester, &mut state, scenario.ctx()); - }; - - // Test: Revert if the caller is not the attester manager - scenario.next_tx(non_attester_manager); - { - disable_attester(attester, &mut state, scenario.ctx()); - assert!(state.is_attester_enabled(attester)); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ETooFewAttestersEnabled)] - public fun test_disable_attester_revert_too_few_attesters() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, attester) = (@0x1, @0x2); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if only one attester is enabled - scenario.next_tx(attester_manager); - { - enable_attester(attester, &mut state, scenario.ctx()); - disable_attester(attester, &mut state, scenario.ctx()); - assert!(state.is_attester_enabled(attester)); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ETooFewEnabledAttesters)] - public fun test_disable_attester_revert_too_few_enabled_attesters() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, first_attester, second_attester) = (@0x1, @0x2, @0x3); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - state.set_signature_threshold(2); - - // Test: Revert if the number of attesters would go below the signature threshold - scenario.next_tx(attester_manager); - { - enable_attester(first_attester, &mut state, scenario.ctx()); - enable_attester(second_attester, &mut state, scenario.ctx()); - disable_attester(second_attester, &mut state, scenario.ctx()); - assert!(state.is_attester_enabled(second_attester)); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EAttesterNotEnabled)] - public fun test_disable_attester_revert_attester_not_enabled() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, first_attester, second_attester, third_attester) = (@0x1, @0x2, @0x3, @0x4); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if the attester is not enabled - scenario.next_tx(attester_manager); - { - enable_attester(first_attester, &mut state, scenario.ctx()); - enable_attester(second_attester, &mut state, scenario.ctx()); - disable_attester(third_attester, &mut state, scenario.ctx()); - assert!(!state.is_attester_enabled(third_attester)); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_disable_attester_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, attester) = (@0x1, @0x2); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Enable attester and change version - scenario.next_tx(attester_manager); - { - enable_attester(attester, &mut state, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - }; - - // Test: Revert for incompatible version - { - disable_attester(attester, &mut state, scenario.ctx()); - assert!(state.is_attester_enabled(attester)); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // set_signature_threshold tests - - #[test] - public fun test_set_signature_threshold_successful() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, first_attester, second_attester) = (@0x1, @0x2, @0x3); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Successfully set new signature threshold - scenario.next_tx(attester_manager); - { - enable_attester(first_attester, &mut state, scenario.ctx()); - enable_attester(second_attester, &mut state, scenario.ctx()); - set_signature_threshold(2, &mut state, scenario.ctx()); - assert!(state.signature_threshold() == 2); - assert!(num_events() == 3); - let event = last_event_by_type(); - assert!(event.old_signature_threshold == 1); - assert!(event.new_signature_threshold == 2); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotAttesterManager)] - public fun test_set_signature_threshold_revert_not_attester_manager() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, not_attester_manager) = (@0x1, @0x2); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if the caller is not the attester manager - scenario.next_tx(not_attester_manager); - { - set_signature_threshold(2, &mut state, scenario.ctx()); - assert!(state.signature_threshold() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EInvalidSignatureThreshold)] - public fun test_set_signature_threshold_revert_invalid_signature_threshold() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if the signature threshold is 0 - scenario.next_tx(attester_manager); - { - set_signature_threshold(0, &mut state, scenario.ctx()); - assert!(state.signature_threshold() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ESignatureThresholdTooHigh)] - public fun test_set_signature_threshold_revert_signature_threshold_too_high() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, first_attester, second_attester) = (@0x1, @0x2, @0x3); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if the signature threshold is too high - scenario.next_tx(attester_manager); - { - enable_attester(first_attester, &mut state, scenario.ctx()); - enable_attester(second_attester, &mut state, scenario.ctx()); - set_signature_threshold(3, &mut state, scenario.ctx()); - assert!(state.signature_threshold() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ESignatureThresholdAlreadySet)] - public fun test_set_signature_threshold_revert_signature_threshold_already_set() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager, attester) = (@0x1, @0x2); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: Revert if the signature threshold is already set - scenario.next_tx(attester_manager); - { - enable_attester(attester, &mut state, scenario.ctx()); - set_signature_threshold(1, &mut state, scenario.ctx()); - assert!(state.signature_threshold() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_set_signature_threshold_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let attester_manager = @0x1; - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(attester_manager); - { - set_signature_threshold(2, &mut state, scenario.ctx()); - assert!(state.signature_threshold() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - } diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/message_size.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/message_size.move deleted file mode 100644 index e6dd6b56e..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/message_size.move +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: message_size -/// Admin functions for contract message size management functionality -module message_transmitter::message_size { - // === Imports === - use sui::event::emit; - use message_transmitter::{ - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const ENotOwner: u64 = 0; - - // === Events === - public struct MaxMessageBodySizeUpdated has copy, drop { - new_max_message_body_size: u64, - } - - // === Admin Functions === - - /// Called by the owner to update the `max_message_body_size`. - entry fun set_max_message_body_size(new_max_message_body_size: u64, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - assert!(ctx.sender() == state.roles().owner(), ENotOwner); - - state.set_max_message_body_size(new_max_message_body_size); - emit(MaxMessageBodySizeUpdated{new_max_message_body_size}); - } - - // === Tests === - - #[test_only] use sui::{event::{num_events}, test_scenario, test_utils}; - #[test_only] use message_transmitter::{ - state::{Self}, - version_control - }; - #[test_only] use sui_extensions::test_utils::last_event_by_type; - - #[test] - public fun test_set_max_message_body_size_successful() { - let mut scenario = test_scenario::begin(@0x0); - let (owner) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, owner, scenario.ctx()); - - // Test: Successful update of max message body size - scenario.next_tx(owner); - { - set_max_message_body_size(100, &mut state, scenario.ctx()); - assert!(state.max_message_body_size() == 100); - assert!(num_events() == 1); - assert!(last_event_by_type().new_max_message_body_size == 100); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotOwner)] - public fun test_set_max_message_body_size_revert_not_owner() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, non_owner) = (@0x1, @0x2); - - // Create a new State instance - let mut state = state::new(0, 0, 0, owner, scenario.ctx()); - - // Test: Revert if the caller is not the owner - scenario.next_tx(non_owner); - { - set_max_message_body_size(100, &mut state, scenario.ctx()); - assert!(state.max_message_body_size() == 0); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_set_max_message_body_size_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let owner = @0x1; - - // Create a new State instance with incompatible version - let mut state = state::new(0, 0, 0, owner, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(owner); - { - set_max_message_body_size(100, &mut state, scenario.ctx()); - assert!(state.max_message_body_size() == 0); - }; - - test_utils::destroy(state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/migration.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/migration.move deleted file mode 100644 index 4f23af189..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/migration.move +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// module: migration -/// Contains admin functions for migrating the package and state object to new versions. -module message_transmitter::migration { - // === Imports === - use std::u64::{min, max}; - use sui::event; - use message_transmitter::{ - state::State, - version_control - }; - - // === Errors === - - /// Migration related error codes, starting at 100. - const ENotOwner: u64 = 0; - const EMigrationStarted: u64 = 100; - const EMigrationNotStarted: u64 = 101; - const EObjectMigrated: u64 = 102; - const ENotPendingVersion: u64 = 103; - - // === Events === - - public struct MigrationStarted has copy, drop { - compatible_versions: vector - } - - public struct MigrationAborted has copy, drop { - compatible_versions: vector - } - - public struct MigrationCompleted has copy, drop { - compatible_versions: vector - } - - // === Public functions === - - /// Starts the migration process, making the State object be - /// additionally compatible with this package's version. - entry fun start_migration(state: &mut State, ctx: &TxContext) { - assert!(state.roles().owner() == ctx.sender(), ENotOwner); - assert!(state.compatible_versions().size() == 1, EMigrationStarted); - - let active_version = state.compatible_versions().keys()[0]; - assert!(active_version < version_control::current_version(), EObjectMigrated); - - state.add_compatible_version(version_control::current_version()); - - event::emit(MigrationStarted { - compatible_versions: *state.compatible_versions().keys() - }); - } - - /// Aborts the migration process, reverting the State object's compatibility - /// to the previous version. - entry fun abort_migration(state: &mut State, ctx: &TxContext) { - assert!(state.roles().owner() == ctx.sender(), ENotOwner); - assert!(state.compatible_versions().size() == 2, EMigrationNotStarted); - - let pending_version = max( - state.compatible_versions().keys()[0], - state.compatible_versions().keys()[1] - ); - assert!(pending_version == version_control::current_version(), ENotPendingVersion); - - state.remove_compatible_version(pending_version); - - event::emit(MigrationAborted { - compatible_versions: *state.compatible_versions().keys() - }); - } - - /// Completes the migration process, making the State object be - /// only compatible with this package's version. - entry fun complete_migration(state: &mut State, ctx: &TxContext) { - assert!(state.roles().owner() == ctx.sender(), ENotOwner); - assert!(state.compatible_versions().size() == 2, EMigrationNotStarted); - - let (version_a, version_b) = ( - state.compatible_versions().keys()[0], - state.compatible_versions().keys()[1] - ); - let (active_version, pending_version) = ( - min(version_a, version_b), - max(version_a, version_b) - ); - - assert!(pending_version == version_control::current_version(), ENotPendingVersion); - - state.remove_compatible_version(active_version); - - event::emit(MigrationCompleted { - compatible_versions: *state.compatible_versions().keys() - }); - } - - // === Test-Functions === - - #[test_only] - public(package) fun create_migration_started_event(compatible_versions: vector): MigrationStarted { - MigrationStarted { compatible_versions } - } - - #[test_only] - public(package) fun create_migration_aborted_event(compatible_versions: vector): MigrationAborted { - MigrationAborted { compatible_versions } - } - - #[test_only] - public(package) fun create_migration_completed_event(compatible_versions: vector): MigrationCompleted { - MigrationCompleted { compatible_versions } - } -} - -#[test_only] -module message_transmitter::migration_tests { - use sui::{ - event, - test_scenario::{Self, Scenario}, - test_utils::{Self, assert_eq}, - }; - use message_transmitter::{ - migration, - state::{Self, State}, - version_control - }; - use sui_extensions::test_utils::last_event_by_type; - - // Test addresses - const DEPLOYER: address = @0x0; - const OWNER: address = @0x10; - const RANDOM_ADDRESS: address = @0x1000; - - public struct MIGRATION_TESTS has drop {} - - #[test, expected_failure(abort_code = migration::ENotOwner)] - fun start_migration__should_fail_is_caller_is_not_owner() { - let (mut state, mut scenario) = setup(); - - // Some random address attempts to start a migration, should fail. - scenario.next_tx(RANDOM_ADDRESS); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EMigrationStarted)] - fun start_migration__should_fail_if_migration_started() { - let (mut state, mut scenario) = setup(); - - // Start a migration to this package. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - // Attempt to start another migration, should fail. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EObjectMigrated)] - fun start_migration__should_fail_if_state_is_migrated() { - let (mut state, mut scenario) = setup(); - - // Complete a migration flow to this package. - { - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - }; - - // Attempt to start a migration to this package again, should fail. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test] - fun start_migration__should_succeed_and_pass_all_assertions() { - let (mut state, mut scenario) = setup(); - - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotOwner)] - fun abort_migration__should_fail_is_caller_is_not_owner() { - let (mut state, mut scenario) = setup(); - - // Some random address attempts to start a migration, should fail. - scenario.next_tx(RANDOM_ADDRESS); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EMigrationNotStarted)] - fun abort_migration__should_fail_if_migration_not_started() { - let (mut state, mut scenario) = setup(); - - // Attempt to abort a migration that has not started, should fail. - scenario.next_tx(OWNER); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotPendingVersion)] - fun abort_migration__should_fail_if_the_pending_version_is_not_this_package_version() { - let (mut state, mut scenario) = setup(); - - // Start a migration flow to a later package. - scenario.next_tx(OWNER); - start_migration_to_custom_version_for_testing(&mut state, version_control::current_version() + 100); - - // Attempt to abort the migration using this package, should fail. - scenario.next_tx(OWNER); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test] - fun abort_migration__should_succeed_and_pass_all_assertions() { - let (mut state, mut scenario) = setup(); - - // Start a migration. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - // Abort the migration. - scenario.next_tx(OWNER); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotOwner)] - fun complete_migration__should_fail_is_caller_is_not_owner() { - let (mut state, mut scenario) = setup(); - - // Some random address attempts to start a migration, should fail. - scenario.next_tx(RANDOM_ADDRESS); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EMigrationNotStarted)] - fun complete_migration__should_fail_if_migration_not_started() { - let (mut state, mut scenario) = setup(); - - // Attempt to complete a migration that has not started, should fail. - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotPendingVersion)] - fun complete_migration__should_fail_if_the_pending_version_is_not_this_package_version() { - let (mut state, mut scenario) = setup(); - - // Start a migration flow to a later package. - scenario.next_tx(OWNER); - start_migration_to_custom_version_for_testing(&mut state, version_control::current_version() + 100); - - // Attempt to complete the migration using this package, should fail. - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test] - fun complete_migration__should_succeed_and_pass_all_assertions() { - let (mut state, mut scenario) = setup(); - - // Start a migration. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - // Complete the migration. - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - // === Helpers === - - /// Sets up an outdated State object that is initialized with - /// (package's version - 1). - fun setup(): (State, Scenario) { - let mut scenario = test_scenario::begin(DEPLOYER); - let mut state = state::new(0, 0, 1, OWNER, scenario.ctx()); - - let previous_version = version_control::current_version() - 1; - - state.remove_compatible_version(version_control::current_version()); - state.add_compatible_version(previous_version); - assert_eq(*state.compatible_versions().keys(), vector[previous_version]); - - (state, scenario) - } - - fun cleanup(state: State, scenario: Scenario) { - test_utils::destroy(state); - scenario.end(); - } - - fun test_start_migration(state: &mut State, scenario: &mut Scenario) { - migration::start_migration(state, scenario.ctx()); - - let updated_compatible_versions = state.compatible_versions().keys(); - assert_eq(updated_compatible_versions.length(), 2); - assert_eq(updated_compatible_versions.contains(&version_control::current_version()), true); - - assert_eq(event::num_events(), 1); - assert_eq( - last_event_by_type(), - migration::create_migration_started_event(*updated_compatible_versions) - ); - } - - fun test_abort_migration(state: &mut State, scenario: &mut Scenario) { - migration::abort_migration(state, scenario.ctx()); - - let updated_compatible_versions = state.compatible_versions().keys(); - assert_eq(updated_compatible_versions.length(), 1); - assert_eq(updated_compatible_versions.contains(&version_control::current_version()), false); - - assert_eq(event::num_events(), 1); - assert_eq( - last_event_by_type(), - migration::create_migration_aborted_event(*updated_compatible_versions) - ); - } - - fun test_complete_migration(state: &mut State, scenario: &mut Scenario) { - migration::complete_migration(state, scenario.ctx()); - - let updated_compatible_versions = state.compatible_versions().keys(); - assert_eq(*updated_compatible_versions, vector[version_control::current_version()]); - - assert_eq(event::num_events(), 1); - assert_eq( - last_event_by_type(), - migration::create_migration_completed_event(*updated_compatible_versions) - ); - } - - fun start_migration_to_custom_version_for_testing(state: &mut State, version: u64) { - assert_eq(state.compatible_versions().keys().length(), 1); - - state.add_compatible_version(version); - - assert_eq(state.compatible_versions().keys().length(), 2); - assert_eq(state.compatible_versions().contains(&version), true); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/pausable.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/pausable.move deleted file mode 100644 index 1ebca27c8..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/pausable.move +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: pausable -/// Admin functions for contract pause functionality -module message_transmitter::pausable { - // === Imports === - use sui::event::emit; - use message_transmitter::{ - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const ENotPauser: u64 = 0; - const EAlreadyPaused: u64 = 1; - const ENotPaused: u64 = 2; - - // === Events === - public struct Pause has copy, drop {} - - public struct Unpause has copy, drop {} - - // === Admin Functions === - - /// Called by the owner to pause the contract by setting paused - /// to true. Only pauses functions that check this `paused` value. - entry fun pause(state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_pauser(state, ctx); - assert!(!state.paused(), EAlreadyPaused); - - state.set_paused(true); - emit(Pause {}); - } - - /// Called by the owner to unpause the contract by setting paused - /// to false. Only pauses functions that check this `paused` value. - entry fun unpause(state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_pauser(state, ctx); - assert!(state.paused(), ENotPaused); - - state.set_paused(false); - emit(Unpause {}); - } - - // === Private Functions === - - fun verify_pauser(state: &State, ctx: &TxContext) { - assert!(ctx.sender() == state.roles().pauser(), ENotPauser); - } - - // === Test Functions === - #[test_only] use sui::{event::{num_events}, test_scenario, test_utils}; - #[test_only] use message_transmitter::{ - state::{Self}, - version_control - }; - #[test_only] use sui_extensions::test_utils::last_event_by_type; - - // pause tests - - #[test] - public fun test_pause_successful() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Successful pause from pauser - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - assert!(num_events() == 1); - last_event_by_type(); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotPauser)] - public fun test_pause_not_pauser() { - let mut scenario = test_scenario::begin(@0x0); - let (pauser, not_pauser) = (@0x1, @0x2); - - // Create a new State - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Revert if not called from pauser - scenario.next_tx(not_pauser); - { - pause(&mut state, scenario.ctx()); - assert!(!state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EAlreadyPaused)] - public fun test_pause_already_paused() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Revert if already paused - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - pause(&mut state, scenario.ctx()); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_pause_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State with incompatible version - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if incompatible version - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(!state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // unpause tests - - #[test] - public fun test_unpause_successful() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Successful unpause from pauser - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - unpause(&mut state, scenario.ctx()); - assert!(!state.paused(), 2); - assert!(num_events() == 2); - last_event_by_type(); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotPauser)] - public fun test_unpause_not_pauser() { - let mut scenario = test_scenario::begin(@0x0); - let (pauser, not_pauser) = (@0x1, @0x2); - - // Create a new State - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - // Pause the tx so we can test unpausing - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - }; - - // Test: Revert if not called from pauser - scenario.next_tx(not_pauser); - { - unpause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotPaused)] - public fun test_unpause_already_unpaused() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Revert if already unpaused - scenario.next_tx(pauser); - { - unpause(&mut state, scenario.ctx()); - assert!(!state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_unpause_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State with incompatible version - let mut state = state::new(0, 0, 0, pauser, scenario.ctx()); - state.set_paused(true); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if incompatible version - scenario.next_tx(pauser); - { - unpause(&mut state, scenario.ctx()); - assert!(state.paused()); - }; - - test_utils::destroy(state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/role_management.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/role_management.move deleted file mode 100644 index 7f8a051c5..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/role_management.move +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: role_management -/// MessageTransmitter role management functions -module message_transmitter::role_management { - // === Imports === - use sui::event::emit; - use message_transmitter::{ - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const ERoleAlreadySet: u64 = 0; - - // === Events === - public struct AttesterManagerUpdated has copy, drop { - previous_attester_manager: address, - new_attester_manager: address - } - - public struct PauserChanged has copy, drop { - new_pauser: address, - } - - // === Admin Functions === - - /// Called by the owner to update the `pauser` role. - entry fun update_pauser(new_pauser: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - validate_role_transfer(new_pauser, state.roles().pauser(), state, ctx); - - state.roles_mut().update_pauser(new_pauser); - emit(PauserChanged {new_pauser: state.roles().pauser()}); - } - - /// Called by the owner to update the `attester_manager` role. - entry fun update_attester_manager(new_attester_manager: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - validate_role_transfer(new_attester_manager, state.roles().attester_manager(), state, ctx); - let previous_attester_manager = state.roles().attester_manager(); - - state.roles_mut().update_attester_manager(new_attester_manager); - emit(AttesterManagerUpdated {previous_attester_manager, new_attester_manager: state.roles().attester_manager()}); - } - - /// Proxy call to start ownership transfer - entry fun transfer_ownership(new_owner: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - state.roles_mut().owner_role_mut().begin_role_transfer(new_owner, ctx); - } - - /// Proxy call to accept ownership transfer - entry fun accept_ownership(state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - state.roles_mut().owner_role_mut().accept_role(ctx); - } - - // === Private Functions === - - fun validate_role_transfer(new_address: address, current_address: address, state: &State, ctx: &TxContext) { - state.roles().owner_role().assert_sender_is_active_role(ctx); - assert!(new_address != current_address, ERoleAlreadySet) - } - - // === Tests === - #[test_only] use sui::{ - event::{num_events}, - test_scenario::{Self, Scenario}, - test_utils - }; - #[test_only] use message_transmitter::{ - state::{Self}, - version_control - }; - #[test_only] use sui_extensions::{ - test_utils::{last_event_by_type}, - two_step_role - }; - - #[test_only] const OWNER: address = @0x123; - - #[test_only] - fun setup(): (Scenario, State) { - let mut scenario = test_scenario::begin(@0x0); - let state = state::new(0, 0, 0, OWNER, scenario.ctx()); - - (scenario, state) - } - - // update_pauser tests - - #[test] - public fun test_update_pauser_successful() { - let (mut scenario, mut state) = setup(); - let new_pauser = @0x2; - - // Test: Successful update of pauser - scenario.next_tx(OWNER); - { - update_pauser(new_pauser, &mut state, scenario.ctx()); - assert!(state.roles().pauser() == new_pauser); - assert!(num_events() == 1); - assert!(last_event_by_type().new_pauser == new_pauser); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = two_step_role::ESenderNotActiveRole)] - public fun test_update_pauser_revert_not_owner() { - let (mut scenario, mut state) = setup(); - let (non_owner, new_pauser) = (@0x2, @0x3); - - // Test: Revert if the caller is not the owner - scenario.next_tx(non_owner); - { - update_pauser(new_pauser, &mut state, scenario.ctx()); - assert!(state.roles().pauser() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ERoleAlreadySet)] - public fun test_update_pauser_revert_already_set() { - let (mut scenario, mut state) = setup(); - - // Test: Revert if the new pauser address is the same as existing - scenario.next_tx(OWNER); - { - update_pauser(state.roles().pauser(), &mut state, scenario.ctx()); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_update_pauser_revert_incompatible_version() { - let (mut scenario, mut state) = setup(); - let new_pauser = @0x2; - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if incompatible version - scenario.next_tx(OWNER); - { - update_pauser(new_pauser, &mut state, scenario.ctx()); - assert!(state.roles().pauser() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // update_attester_manager tests - - #[test] - public fun test_update_attester_manager_successful() { - let (mut scenario, mut state) = setup(); - let new_attester_manager = @0x2; - - // Test: Successful update of attester_manager - scenario.next_tx(OWNER); - { - update_attester_manager(new_attester_manager, &mut state, scenario.ctx()); - assert!(state.roles().attester_manager() == new_attester_manager, 0); - assert!(num_events() == 1); - let event = last_event_by_type(); - assert!(event.previous_attester_manager == OWNER); - assert!(event.new_attester_manager == new_attester_manager); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = two_step_role::ESenderNotActiveRole)] - public fun test_update_attester_manager_revert_not_owner() { - let (mut scenario, mut state) = setup(); - let (non_owner, new_attester_manager) = (@0x2, @0x3); - - // Test: Revert if the caller is not the owner - scenario.next_tx(non_owner); - { - update_attester_manager(new_attester_manager, &mut state, scenario.ctx()); - assert!(state.roles().attester_manager() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ERoleAlreadySet)] - public fun test_update_attester_manager_revert_already_set() { - let (mut scenario, mut state) = setup(); - - // Test: Revert if the new attester_manager address is the same as existing - scenario.next_tx(OWNER); - { - update_attester_manager(state.roles().attester_manager(), &mut state, scenario.ctx()); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_update_attester_manager_revert_incompatible_version() { - let new_attester_manager = @0x2; - let (mut scenario, mut state) = setup(); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert with incompatible version - scenario.next_tx(OWNER); - { - update_attester_manager(new_attester_manager, &mut state, scenario.ctx()); - assert!(state.roles().attester_manager() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // transfer_ownership tests - - #[test] - public fun test_transfer_ownership_successful() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - - // Test: Successful start transfer of ownership - scenario.next_tx(OWNER); - { - transfer_ownership(new_owner, &mut state, scenario.ctx()); - assert!(*state.roles().pending_owner().borrow() == new_owner); - assert!(state.roles().owner() == OWNER); - // Event fields tested in two_step_role module - assert!(num_events() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_transfer_ownership_revert__incompatible_version() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(OWNER); - { - transfer_ownership(new_owner, &mut state, scenario.ctx()); - assert!(state.roles().pending_owner() == option::none()); - assert!(state.roles().owner() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // accept_ownership tests - - #[test] - public fun test_accept_ownership_successful() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - - // Start transfer ownership first - scenario.next_tx(OWNER); - transfer_ownership(new_owner, &mut state, scenario.ctx()); - - // Test: Successfully accept/transfer ownership - scenario.next_tx(new_owner); - { - accept_ownership(&mut state, scenario.ctx()); - assert!(state.roles().owner() == new_owner); - assert!(state.roles().pending_owner() == option::none()); - // Events tested in two_step_role module - assert!(num_events() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_accept_ownership__incompatible_version() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - - // Start transfer ownership first - scenario.next_tx(OWNER); - transfer_ownership(new_owner, &mut state, scenario.ctx()); - - // Update version to incompatible - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(new_owner); - { - accept_ownership(&mut state, scenario.ctx()); - assert!(state.roles().owner() == OWNER); - assert!(state.roles().pending_owner() == option::some(new_owner)); - }; - - test_utils::destroy(state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/roles.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/roles.move deleted file mode 100644 index a333181c8..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/roles.move +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: roles -/// This module contains all roles for the message_transmitter package -module message_transmitter::roles { - // === Imports === - use sui_extensions::two_step_role::{Self, TwoStepRole}; - - // === Structs === - - /// Track roles via EOAs (rather than Capabilities) to retain revocability. - public struct Roles has key, store { - id: UID, - // Controls other roles - owner: TwoStepRole, - // Controls pausing/unpausing - pauser: address, - // Controls enabling and disabling attesters - attester_manager: address - } - - public struct OwnerRole has drop {} - - // === Public-Mutative Functions === - - /// Create and return a new Roles state object - public(package) fun new(owner: address, pauser: address, attester_manager: address, ctx: &mut TxContext): Roles { - Roles { - id: object::new(ctx), - owner: two_step_role::new(OwnerRole {}, owner), - pauser, - attester_manager - } - } - - // === Public-View Functions === - - public(package) fun owner_role_mut(roles: &mut Roles): &mut TwoStepRole { - &mut roles.owner - } - - public fun owner_role(roles: &Roles): &TwoStepRole { - &roles.owner - } - - public fun owner(roles: &Roles): address { - roles.owner.active_address() - } - - public fun pending_owner(roles: &Roles): Option
{ - roles.owner.pending_address() - } - - public fun pauser(roles: &Roles): address { - roles.pauser - } - - public fun attester_manager(roles: &Roles): address { - roles.attester_manager - } - - // === Public-Package Functions === - - public(package) fun update_pauser(roles: &mut Roles, new_pauser: address) { - roles.pauser = new_pauser; - } - - public(package) fun update_attester_manager(roles: &mut Roles, new_attester_manager: address) { - roles.attester_manager = new_attester_manager; - } - - // === Tests === - #[test_only] use sui::test_utils::{Self, assert_eq}; - - #[test] - fun roles_new_creates_object() { - let mut ctx = tx_context::dummy(); - - let expected_owner = @0x1; - let expected_pauser = @0x2; - let expected_attester_manager = @0x3; - - let roles_obj = new(expected_owner, expected_pauser, expected_attester_manager, &mut ctx); - - assert_eq(roles_obj.owner(), expected_owner); - assert_eq(roles_obj.pending_owner(), option::none()); - assert_eq(roles_obj.pauser(), expected_pauser); - assert_eq(roles_obj.attester_manager(), expected_attester_manager); - - test_utils::destroy(roles_obj); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/version_control.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/version_control.move deleted file mode 100644 index 1000c616f..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/admin/version_control.move +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// module: version_control -/// Contains version control functions. -/// Copied from stablecoin package: -/// https://github.com/circlefin/stablecoin-sui/blob/63fca4360821600ca8686b86f8e26d98e95927c7/packages/stablecoin/sources/version_control.move. -module message_transmitter::version_control { - use sui::vec_set::VecSet; - - /// The current version of the package. - const VERSION: u64 = 2; - - // === Errors === - const EIncompatibleVersion: u64 = 0; - - // === Methods === - /// Public accessor for the current package's version. - public fun current_version(): u64 { - VERSION - } - - /// [Package Private] Helper function to check that the object is - /// compatible with the current package's version. - public(package) fun assert_object_version_is_compatible_with_package(compatible_versions: &VecSet) { - assert!(compatible_versions.contains(¤t_version()), EIncompatibleVersion); - } -} - -#[test_only] -module message_transmitter::version_control_tests { - use sui::vec_set::{Self, VecSet}; - use message_transmitter::version_control; - - #[test, expected_failure(abort_code = version_control::EIncompatibleVersion)] - fun assert_object_version_is_compatible_with_package__should_abort_if_not_compatible() { - let compatible_versions: VecSet = vec_set::empty(); - version_control::assert_object_version_is_compatible_with_package( - &compatible_versions - ) - } - - #[test] - fun assert_object_version_is_compatible_with_package__should_succeed_if_compatible_version_is_contained() { - let compatible_versions: VecSet = vec_set::singleton(version_control::current_version()); - version_control::assert_object_version_is_compatible_with_package( - &compatible_versions - ) - } - - #[test] - fun assert_object_version_is_compatible_with_package__should_succeed_if_one_of_multiple_compatible_versions() { - let mut compatible_versions: VecSet = vec_set::empty(); - compatible_versions.insert(version_control::current_version()); - compatible_versions.insert(version_control::current_version() + 1); - - version_control::assert_object_version_is_compatible_with_package( - &compatible_versions - ) - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/attestation.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/attestation.move deleted file mode 100644 index a9e8e5a3e..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/attestation.move +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: attestation -/// This module contains all attestation processing logic for the message_transmitter package -module message_transmitter::attestation { - // === Imports === - - use sui::{ - address::{Self}, - hash::{Self}, - ecdsa_k1::{Self}, - }; - use message_transmitter::state::{State}; - use message_transmitter::vector_utils; - - // === Errors === - - const EInvalidAttestationLength: u64 = 0; - const EInvalidSignatureOrder: u64 = 1; - const ESignerIsNotAttester: u64 = 2; - const EInvalidSignatureRecoveryId: u64 = 3; - const EInvalidSignatureSValue: u64 = 4; - - // === Constants === - - const SIGNATURE_LENGTH: u64 = 65; - const HALF_CURVE_ORDER: address = @0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0; - - /// The ecdsa_k1 module identifies the hash functions used in signing through a u8 value. - /// The value is 0 for KECCAK256, but constants are internal to their module, so we must redefine it here. - /// https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/packages/sui-framework/sources/crypto/ecdsa_k1.move#L35 - const KECCAK256_ID: u8 = 0; - - // === Public Functions === - - /// Verifies that the attestation for a message, comprised of one or more concatenated 65-byte signatures, is valid. - /// Reverts if invalid. A valid attestation requires the following conditions to be met: - /// 1. length of `attestation` == 65 (signature length) * signature_threshold - /// 2. addresses recovered from attestation must be in increasing order. - /// For example, if signature A is signed by address 0x1..., and signature B - /// is signed by address 0x2..., attestation must be passed as AB. - /// 3. no duplicate signers - /// 4. all signers must be enabled attesters - /// - /// Based on Christian Lundkvist's Simple Multisig - /// (https://github.com/christianlundkvist/simple-multisig/tree/560c463c8651e0a4da331bd8f245ccd2a48ab63d) - public fun verify_attestation_signatures(message: vector, attestation: vector, state: &State) { - let signature_threshold = state.signature_threshold(); - assert!(attestation.length() == signature_threshold * SIGNATURE_LENGTH, EInvalidAttestationLength); - - let mut latest_attester_address = @0x0; - let mut i = 0u64; - while (i < signature_threshold) { - let signature = vector_utils::slice(&attestation, i * SIGNATURE_LENGTH, (i + 1) * SIGNATURE_LENGTH); - verify_low_s_value(signature); - - let normalized_signature = normalize_attestation(signature); - let recovered_attester = recover_attester(&normalized_signature, &message); - - // Signatures must be in increasing order of address, and may not duplicate signatures from same address. - // Addresses may not be directly compared, so they must be cast to u256 first. - assert!(recovered_attester.to_u256() > latest_attester_address.to_u256(), EInvalidSignatureOrder); - assert!(state.is_attester_enabled(recovered_attester), ESignerIsNotAttester); - - latest_attester_address = recovered_attester; - i = i + 1; - } - } - - // === Private Functions === - - /// Checks if `s` value of signature is in the lower half of curve order - /// Using Secp256k1Ecdsa Half Curve order from OpenZeppelin ecdsa recover - /// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol#L137 - fun verify_low_s_value(signature: vector) { - // Signature is made of r(32 bytes) + s(32 bytes) + v(1 byte) - let signature_s_value = vector_utils::slice(&signature, 32, SIGNATURE_LENGTH-1); - let signature_s_address = address::from_bytes(signature_s_value); - - assert!(signature_s_address.to_u256() <= HALF_CURVE_ORDER.to_u256(), EInvalidSignatureSValue); - } - - /// Helper function to recover the attester from a signature and message. - fun recover_attester(signature: &vector, message: &vector): address { - // Recover the compressed public key from the signature and message, then decompress it. - let recovered_key = ecdsa_k1::secp256k1_ecrecover(signature, message, KECCAK256_ID); - let decompressed_pubkey = ecdsa_k1::decompress_pubkey(&recovered_key); - - // Remove the 0x04 prefix from the public key prior to hashing. - let sliced_decompressed_pubkey = vector_utils::slice(&decompressed_pubkey, 1, decompressed_pubkey.length()); - - // Hash the public key and take the last 20 bytes to fetch the attester. - let hashed_pubkey = hash::keccak256(&sliced_decompressed_pubkey); - let attester = vector_utils::slice(&hashed_pubkey, hashed_pubkey.length() - 20, hashed_pubkey.length()); - - // Prepend the attester with 12 empty bytes to produce a Sui address. - let mut attester_address = x"000000000000000000000000"; - attester_address.append(attester); - - address::from_bytes(attester_address) - } - - /// Helper function to normalize the v-value for an attestation. - /// Circle attestations provide v = 27 or 28, while Sui expects v between 0 and 3. - /// This function normalizes by subtracting 27 from v. - fun normalize_attestation(attestation: vector): vector { - let mut normalized_attestation = vector_utils::slice(&attestation, 0, SIGNATURE_LENGTH - 1); - let mut attestation_v = vector_utils::slice(&attestation, SIGNATURE_LENGTH - 1, SIGNATURE_LENGTH); - let v = attestation_v.pop_back(); - - assert!(v >= 27 && v <= 28, EInvalidSignatureRecoveryId); - normalized_attestation.push_back(v - 27); - - normalized_attestation - } - - // === Tests === - #[test_only] use sui::{test_scenario, test_utils}; - #[test_only] use message_transmitter::state::{Self}; - #[test_only] use message_transmitter::attester_manager::{Self}; - - // Sample attestations are pulled from the following transaction - // https://sepolia.etherscan.io/tx/0x151c196be83e2fcbd84204a521ee0a758a5e7335ac7d2c0958ef840fd485dc61 - - #[test_only] const FIRST_ATTESTER: address = @0x0Ce39e399e2038C435Cc097833d5c58f5E9A7E98; - #[test_only] const SECOND_ATTESTER: address = @0xC0b11b8850107DE6e92cF63E3B2CCB179b72F21C; - #[test_only] const FIRST_ATTESTATION: vector = x"16a47e516fca2826c186fdd1ea00ac3c48e46d41d3756187b5f83424b76633dd7f9a45bd9ee5b3cc187de0a40ee20c8841d77ee0933e6d83a626060f15fbb1e51b"; - #[test_only] const SECOND_ATTESTATION: vector = x"4bff09dbfcca2ddb8af1cf8e14670f19096e6de130af14cb7ce21b1e9ccfa76c025d1eddf2dee7f0915861d87d423b62d3afa286f110eef38f6c27f3ccc4169d1c"; - #[test_only] const ATTESTATION: vector = x"16a47e516fca2826c186fdd1ea00ac3c48e46d41d3756187b5f83424b76633dd7f9a45bd9ee5b3cc187de0a40ee20c8841d77ee0933e6d83a626060f15fbb1e51b4bff09dbfcca2ddb8af1cf8e14670f19096e6de130af14cb7ce21b1e9ccfa76c025d1eddf2dee7f0915861d87d423b62d3afa286f110eef38f6c27f3ccc4169d1c"; - #[test_only] const RAW_MESSAGE: vector = x"000000000000000000000001000000000003f3140000000000000000000000009f3b8679c73c2fef8b59b4f3444d4e156fb70aa5000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d00000000000000000000000001f26414439c8d03fc4b9ca912cefd5cb508c9605000000000000000000000000000000001c7d4b196cb0c7b01d743fbc6116a902379c72380000000000000000000000001f26414439c8d03fc4b9ca912cefd5cb508c960500000000000000000000000000000000000000000000000000000000000004be0000000000000000000000003b61abee91852714e4e99b09a1af3e9c13893ef1"; - - #[test] - public fun test_verify_signature_successful() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: successfully verify a signature - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - attester_manager::enable_attester(SECOND_ATTESTER, &mut state, scenario.ctx()); - attester_manager::set_signature_threshold(2, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, ATTESTATION, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EInvalidAttestationLength)] - public fun test_verify_signature_revert_invalid_attestation_length() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: revert when verifying a signature due to invalid attestation length - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, ATTESTATION, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EInvalidSignatureOrder)] - public fun test_verify_signature_revert_invalid_signature_order() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Create an invalid attestation with the first/second attestation swapped - let mut invalid_attestation = SECOND_ATTESTATION; - invalid_attestation.append(FIRST_ATTESTATION); - - // Test: revert when verifying a signature due to invalid signature order - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - attester_manager::enable_attester(SECOND_ATTESTER, &mut state, scenario.ctx()); - attester_manager::set_signature_threshold(2, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, invalid_attestation, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EInvalidSignatureOrder)] - public fun test_verify_signature_revert_duplicate_signer() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Create an invalid attestation with attestations from the same signer twice in a row - let mut invalid_attestation = FIRST_ATTESTATION; - invalid_attestation.append(FIRST_ATTESTATION); - - // Test: revert when verifying a signature due to duplicate signers - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - attester_manager::enable_attester(SECOND_ATTESTER, &mut state, scenario.ctx()); - attester_manager::set_signature_threshold(2, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, invalid_attestation, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ESignerIsNotAttester)] - public fun test_verify_signature_revert_invalid_signer() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Test: revert when verifying a signature due to signer not being an attester - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, SECOND_ATTESTATION, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EInvalidSignatureRecoveryId)] - public fun test_verify_signature_revert_recovery_id_too_high() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Create an invalid attestation with the last byte changed - let mut invalid_attestation = FIRST_ATTESTATION; - invalid_attestation.pop_back(); - invalid_attestation.push_back(31); - - // Test: revert when verifying a signature due to an invalid signature recovery id (too high) - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, invalid_attestation, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EInvalidSignatureRecoveryId)] - public fun test_verify_signature_revert_recovery_id_too_low() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Create an invalid attestation with the last byte changed - let mut invalid_attestation = FIRST_ATTESTATION; - invalid_attestation.pop_back(); - invalid_attestation.push_back(26); - - // Test: revert when verifying a signature due to an invalid signature recovery id (too low) - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, invalid_attestation, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EInvalidSignatureSValue)] - public fun test_verify_signature_revert_invalid_signature_s_value() { - let mut scenario = test_scenario::begin(@0x0); - let (attester_manager) = (@0x1); - - // Create a new State instance - let mut state = state::new(0, 0, 0, attester_manager, scenario.ctx()); - - // Create an invalid attestation with the S value too high (HALF_CURVE_ORDER + 1) - let starting_attestation = FIRST_ATTESTATION; - let mut invalid_attestation = vector_utils::slice(&starting_attestation, 0, 32); - invalid_attestation.append(address::from_u256(address::to_u256(HALF_CURVE_ORDER) + 1).to_bytes()); - invalid_attestation.push_back(27); - - // Test: revert when verifying a signature due to an invalid signature recovery id (too low) - scenario.next_tx(attester_manager); - { - attester_manager::enable_attester(FIRST_ATTESTER, &mut state, scenario.ctx()); - - verify_attestation_signatures(RAW_MESSAGE, invalid_attestation, &state); - }; - - test_utils::destroy(state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/auth.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/auth.move deleted file mode 100644 index 575ca755e..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/auth.move +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: auth -/// This module contains auth_caller_identifier which is used to uniquely identify calling -/// packages for various functions in the CCTP contracts. Any struct that implements the -/// drop trait can be used as an authenticator, but it is recommended to use a dedicated struct. -/// Calling contracts should be careful to not expose these objects to the public or else messages -/// from their package could be forged or replaced. An example implementation exists in the -/// token_messenger_minter::message_transmitter_authenticator module. -module message_transmitter::auth { - // === Imports === - use std::type_name::{Self}; - use sui::{ - address, hash - }; - - // === Errors === - const EInvalidAuth: u64 = 0; - - // === Public-View Functions === - - /// Returns the identifier of a given Auth struct. - /// Identifier is the keccak256 hash of the full type name. This ensures the package, - /// module, and type are encoded in the identifier. - public fun auth_caller_identifier(): address { - let auth_type = type_name::get(); - assert!(!auth_type.is_primitive(), EInvalidAuth); - - address::from_bytes(hash::keccak256(auth_type.into_string().as_bytes())) - } -} - -// === Tests === - -#[test_only] -module message_transmitter::auth_tests { - use sui::{ - test_utils::assert_eq - }; - use message_transmitter::{ - auth::{Self, auth_caller_identifier}, - message_transmitter_authenticator::{SendMessageTestAuth}, - }; - - #[test] - public fun test_auth_caller_identifier_successful() { - let identifier = auth_caller_identifier(); - // address(hash(0000000000000000000000000000000000000000000000000000000000000001::message_transmitter_authenticator::SendMessageTestAuth)) - let expected_identifier = @0x949764be99bacbf6297178f1b467586bac40d0012cb816d5c1a2ea9167e79dfe; - assert_eq(identifier, expected_identifier); - } - - #[test] - #[expected_failure(abort_code = auth::EInvalidAuth)] - public fun test_auth_caller_identifier_revert_primitive_type() { - auth_caller_identifier
(); - } - -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/initialize.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/initialize.move deleted file mode 100644 index 281cf6845..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/initialize.move +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: initialize -/// This module contains initialization logic for the message_transmitter package -module message_transmitter::initialize { - // === Imports === - use message_transmitter::state::{Self}; - use message_transmitter::attester_manager::{Self}; - use sui_extensions::upgrade_service; - - // === Structs === - public struct InitCap has key, store { - id: UID - } - - public struct INITIALIZE has drop {} - - // === Admin Functions === - - #[allow(lint(share_owned))] - /// init (automatically called at deployment) transfers - /// an InitCap to the sender so they can call init_state - /// to initialize state with parameters. - /// Also creates and shares the wrapped Upgrade Service. - fun init(witness: INITIALIZE, ctx: &mut TxContext) { - let (upgrade_service, _witness) = upgrade_service::new( - witness, - ctx.sender() /* admin */, - ctx - ); - transfer::public_share_object(upgrade_service); - transfer::transfer(InitCap {id: object::new(ctx)}, ctx.sender()); - } - - /// Initializes and shares the State object. - /// Initializes state with given local_domain, message_version, max_message_body_size, - /// attester, all roles set to the tx sender, and paused set to false. - /// Requires (and destroys) an InitCap object which can only be created in init method, - /// therefore this function can only be called once. - public fun init_state(init_cap: InitCap, local_domain: u32, message_version: u32, max_message_body_size: u64, attester: address, ctx: &mut TxContext) { - let mut state = state::new(local_domain, message_version, max_message_body_size, ctx.sender(), ctx); - attester_manager::enable_attester_internal(attester, &mut state, ctx); - state.share_state(); - - // Delete the init cap so init_state can only be called once - let InitCap {id} = init_cap; - object::delete(id); - } - - // === Test Functions === - #[test_only] use sui::test_scenario::{Self}; - #[test_only] use message_transmitter::state::{State}; - - #[test] - public fun test_init_successful() { - let mut scenario = test_scenario::begin(@0x0); - - // Test: When package is deployed InitCap is transferred to caller - init(INITIALIZE {}, scenario.ctx()); - let effects = scenario.next_tx(@0x1); - let created_init_cap_id = effects.created()[1]; - assert!(effects.transferred_to_account()[&created_init_cap_id] == @0x0); - // Aborts if it doesn't exist - let created_init_cap = scenario.take_from_address_by_id(@0x0, created_init_cap_id); - test_scenario::return_to_address(@0x0, created_init_cap); - - // Clean up - scenario.end(); - } - - #[test] - fun test_init_state_successful() { - let mut scenario = test_scenario::begin(@0x0); - - // Get InitCap to call init_state - let init_cap = InitCap {id: object::new(scenario.ctx())}; - let init_cap_id = object::id(&init_cap); - - // Test: After init_state is called, shared_state was shared and InitCap was deleted. - scenario.next_tx(@0x5); - { - init_state(init_cap, 1, 1, 1, @0x1, scenario.ctx()); - let effects = scenario.next_tx(@0x0); - let shared_state = scenario.take_shared(); - - assert!(effects.shared().length() == 1, 0); - assert!(effects.shared()[0] == object::id(&shared_state), 1); - assert!(effects.deleted().contains(&init_cap_id), 2); - - test_scenario::return_shared(shared_state); - }; - - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/deserialize.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/deserialize.move deleted file mode 100644 index cb370171b..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/deserialize.move +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: deserialize -/// Contains deserialization methods specific to the CCTP message format. -/// We cannot use BCS directly for uint deserialization because BCS uses -/// little-endian, while CCTP messages use big-endian. So in all uint -/// deserialization methods, reverse the bytes before calling into BCS. -module message_transmitter::deserialize { - // === Imports === - use sui::bcs; - use message_transmitter::vector_utils; - - // === Public-View Functions === - - public fun deserialize_u32_be(data: &vector, index: u64, size: u64): u32 { - let mut sliced_data = vector_utils::slice(data, index, index+size); - vector::reverse(&mut sliced_data); - let mut bcs_bytes = bcs::new(sliced_data); - - bcs_bytes.peel_u32() - } - - public fun deserialize_u64_be(data: &vector, index: u64, size: u64): u64 { - let mut sliced_data = vector_utils::slice(data, index, index+size); - vector::reverse(&mut sliced_data); - let mut bcs_bytes = bcs::new(sliced_data); - - bcs_bytes.peel_u64() - } - - public fun deserialize_u256_be(data: &vector, index: u64, size: u64): u256 { - let mut sliced_data = vector_utils::slice(data, index, index+size); - vector::reverse(&mut sliced_data); - let mut bcs_bytes = bcs::new(sliced_data); - - bcs_bytes.peel_u256() - } - - public fun deserialize_address(data: &vector, index: u64, size: u64): address { - let sliced_data = vector_utils::slice(data, index, index+size); - let mut bcs_bytes = bcs::new(sliced_data); - - bcs_bytes.peel_address() - } - - // === Test Functions === - - #[test] - public fun test_deserialize_u32_be() { - let num: u32 = 1234567; - let mut serialized = bcs::to_bytes(&num); - vector::reverse(&mut serialized); - - let deserialized = deserialize_u32_be(&serialized, 0, serialized.length()); - assert!(deserialized == num); - } - - #[test] - public fun test_deserialize_u64_be() { - let num: u64 = 123456789; - let mut serialized = bcs::to_bytes(&num); - vector::reverse(&mut serialized); - - let deserialized = deserialize_u64_be(&serialized, 0, serialized.length()); - assert!(deserialized == num); - } - - #[test] - public fun test_deserialize_u256_be() { - let num: u256 = 123456789123456789123456789; - let mut serialized = bcs::to_bytes(&num); - vector::reverse(&mut serialized); - - let deserialized = deserialize_u256_be(&serialized, 0, serialized.length()); - assert!(deserialized == num); - } - - #[test] - public fun test_deserialize_address() { - let address: address = @0xa9fb1b3009dcb79e2fe346c16a604b8fa8ae0a79; - let serialized = bcs::to_bytes(&address); - - let deserialized = deserialize_address(&serialized, 0, serialized.length()); - assert!(deserialized == address); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/message.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/message.move deleted file mode 100644 index a4ae94450..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/message.move +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: message -/// This module contains the Message struct for generic CCTP messages. -/// Format defined here: -/// https://developers.circle.com/stablecoins/docs/message-format#message-header. -/// Message is structured in the following format: -/// -------------------------------------------------- -/// Field Bytes Type Index -/// version 4 uint32 0 -/// sourceDomain 4 uint32 4 -/// destinationDomain 4 uint32 8 -/// nonce 8 uint64 12 -/// sender 32 bytes32 20 -/// recipient 32 bytes32 52 -/// destinationCaller 32 bytes32 84 -/// messageBody dynamic bytes 116 -/// -------------------------------------------------- -module message_transmitter::message { - // === Imports === - use message_transmitter::{ - deserialize::{deserialize_u32_be, deserialize_u64_be, deserialize_address}, - serialize::{serialize_u32_be, serialize_u64_be, serialize_address}, - vector_utils - }; - - // === Errors === - const EInvalidMessageLength: u64 = 0; - - // === Constants === - const VERSION_INDEX: u64 = 0; - const SOURCE_DOMAIN_INDEX: u64 = 4; - const DESTINATION_DOMAIN_INDEX: u64 = 8; - const NONCE_INDEX: u64 = 12; - const SENDER_INDEX: u64 = 20; - const RECIPIENT_INDEX: u64 = 52; - const DESTINATION_CALLER_INDEX: u64 = 84; - const MESSAGE_BODY_INDEX: u64 = 116; - - const VERSION_LEN: u64 = 4; - const SOURCE_DOMAIN_LEN: u64 = 4; - const DESTINATION_DOMAIN_LEN: u64 = 4; - const NONCE_LEN: u64 = 8; - const SENDER_LEN: u64 = 32; - const RECIPIENT_LEN: u64 = 32; - const DESTINATION_CALLER_LEN: u64 = 32; - - // === Structs === - public struct Message has drop, copy { - version: u32, - source_domain: u32, - destination_domain: u32, - nonce: u64, - sender: address, - recipient: address, - destination_caller: address, - message_body: vector - } - - // === Public-View Functions === - - public fun version(message: &Message): u32 { - message.version - } - - public fun source_domain(message: &Message): u32 { - message.source_domain - } - - public fun destination_domain(message: &Message): u32 { - message.destination_domain - } - - public fun nonce(message: &Message): u64 { - message.nonce - } - - public fun sender(message: &Message): address { - message.sender - } - - public fun recipient(message: &Message): address { - message.recipient - } - - public fun destination_caller(message: &Message): address { - message.destination_caller - } - - public fun message_body(message: &Message): vector { - message.message_body - } - - public fun message_body_from_bytes(message_bytes: &vector): vector { - validate_raw_message(message_bytes); - vector_utils::slice(message_bytes, MESSAGE_BODY_INDEX, message_bytes.length()) - } - - // === Public Functions === - - /// Serializes a given `Message` into the CCTP message format in bytes. - public fun serialize(message: &Message): vector { - let Message { - version, - source_domain, - destination_domain, - nonce, - sender, - recipient, - destination_caller, - message_body - } = message; - - let mut result = vector::empty(); - vector::append(&mut result, serialize_u32_be(*version)); - vector::append(&mut result, serialize_u32_be(*source_domain)); - vector::append(&mut result, serialize_u32_be(*destination_domain)); - vector::append(&mut result, serialize_u64_be(*nonce)); - vector::append(&mut result, serialize_address(*sender)); - vector::append(&mut result, serialize_address(*recipient)); - vector::append(&mut result, serialize_address(*destination_caller)); - vector::append(&mut result, *message_body); - - result - } - - // === Public-Package Functions === - - /// Creates a new `Message` object from given parameters. - /// Has public(package) visibility so integrators can trust it when returned. - public(package) fun new( - version: u32, - source_domain: u32, - destination_domain: u32, - nonce: u64, - sender: address, - recipient: address, - destination_caller: address, - message_body: vector - ): Message { - Message { - version, source_domain, destination_domain, nonce, sender, recipient, destination_caller, message_body - } - } - - /// Creates a new `Message` object. - /// Validates the message first. - /// Has public(package) visibility so integrators can trust it when returned. - public(package) fun from_bytes(message_bytes: &vector): Message { - validate_raw_message(message_bytes); - - Message { - version: deserialize_u32_be(message_bytes, VERSION_INDEX, VERSION_LEN), - source_domain: deserialize_u32_be(message_bytes, SOURCE_DOMAIN_INDEX, SOURCE_DOMAIN_LEN), - destination_domain: deserialize_u32_be(message_bytes, DESTINATION_DOMAIN_INDEX, DESTINATION_DOMAIN_LEN), - nonce: deserialize_u64_be(message_bytes, NONCE_INDEX, NONCE_LEN), - sender: deserialize_address(message_bytes, SENDER_INDEX, SENDER_LEN), - recipient: deserialize_address(message_bytes, RECIPIENT_INDEX, RECIPIENT_LEN), - destination_caller: deserialize_address(message_bytes, DESTINATION_CALLER_INDEX, DESTINATION_CALLER_LEN), - message_body: vector_utils::slice(message_bytes, MESSAGE_BODY_INDEX, message_bytes.length()) - } - } - - public(package) fun update_message_body( - message: &mut Message, new_message_body: vector - ) { - message.message_body = new_message_body; - } - - public(package) fun update_destination_caller( - message: &mut Message, new_destination_caller: address - ) { - message.destination_caller = new_destination_caller; - } - - public(package) fun update_version( - message: &mut Message, new_version: u32 - ) { - message.version = new_version; - } - - /// Bytes message should contain all the data required for message transmitter. - /// Message body is optional. - public(package) fun validate_raw_message(message: &vector) { - assert!(message.length() >= MESSAGE_BODY_INDEX, EInvalidMessageLength); - } - - // === Test Functions === - - #[test_only] - public fun new_for_testing( - version: u32, - source_domain: u32, - destination_domain: u32, - nonce: u64, - sender: address, - recipient: address, - destination_caller: address, - message_body: vector - ): Message { - new(version, source_domain, destination_domain, nonce, sender, recipient, destination_caller, message_body) - } - - #[test_only] - public fun from_bytes_for_testing(message_bytes: &vector): Message { - from_bytes(message_bytes) - } - - // Following test message is based on -> - // ETH (Source): https://sepolia.etherscan.io/tx/0x151c196be83e2fcbd84204a521ee0a758a5e7335ac7d2c0958ef840fd485dc61 - // AVAX (Destination): https://testnet.snowtrace.io/tx/0xa98d5c33b7571609875f56ae148563411377392c87b9e8cebd483683a0e36413 - // Nonce: 258836 - // Sender: 0x0000000000000000000000009f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5 (ETH TokenMessenger) - // Recipient: 0x000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d0 (AVAX TokenMessenger) - // - // Custom destination caller: 0x1f26414439C8D03FC4b9CA912CeFd5Cb508C9605 - - #[test_only] - public fun get_raw_test_message(): vector { - x"000000000000000000000001000000000003f3140000000000000000000000009f3b8679c73c2fef8b59b4f3444d4e156fb70aa5000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d00000000000000000000000001f26414439c8d03fc4b9ca912cefd5cb508c9605000000000000000000000000000000001c7d4b196cb0c7b01d743fbc6116a902379c72380000000000000000000000001f26414439c8d03fc4b9ca912cefd5cb508c960500000000000000000000000000000000000000000000000000000000000004be0000000000000000000000003b61abee91852714e4e99b09a1af3e9c13893ef1" - } - - // === Tests === - #[test_only] - use sui::test_utils::{assert_eq}; - - #[test_only] const VERSION: u32 = 0; - #[test_only] const SOURCE_DOMAIN: u32 = 0; - #[test_only] const DESTINATION_DOMAIN: u32 = 1; - #[test_only] const NONCE: u64 = 258836; - #[test_only] const SENDER: address = @0x0000000000000000000000009f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5; - #[test_only] const RECIPIENT: address = @0x000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d0; - #[test_only] const DESTINATION_CALLER: address = @0x0000000000000000000000001f26414439C8D03FC4b9CA912CeFd5Cb508C9605; - #[test_only] const MESSAGE_BODY: vector = x"000000000000000000000000000000001c7d4b196cb0c7b01d743fbc6116a902379c72380000000000000000000000001f26414439c8d03fc4b9ca912cefd5cb508c960500000000000000000000000000000000000000000000000000000000000004be0000000000000000000000003b61abee91852714e4e99b09a1af3e9c13893ef1"; - - - // from_bytes tests - - #[test] - public fun test_from_bytes_successful() { - let message = from_bytes(&get_raw_test_message()); - - assert_eq(message.version(), VERSION); - assert_eq(message.source_domain(), SOURCE_DOMAIN); - assert_eq(message.destination_domain(), DESTINATION_DOMAIN); - assert_eq(message.nonce(), NONCE); - assert_eq(message.sender(), SENDER); - assert_eq(message.recipient(), RECIPIENT); - assert_eq(message.destination_caller(), DESTINATION_CALLER); - assert_eq(message.message_body(), MESSAGE_BODY); - } - - #[test] - #[expected_failure(abort_code = EInvalidMessageLength)] - public fun test_from_bytes_invalid() { - let message = vector[1,2,3,4,5]; - from_bytes(&message); - } - - #[test] - fun test_validate_raw_message() { - let orignal_message = get_raw_test_message(); - validate_raw_message(&orignal_message) - } - - // serialize tests - - #[test] - public fun test_serialize_successful() { - let raw_message = get_raw_test_message(); - let message = from_bytes(&raw_message); - let serialized = message.serialize(); - - assert_eq(raw_message, serialized); - } - - // new tests - - #[test] - public fun new_message_successful() { - let message = new(VERSION, SOURCE_DOMAIN, DESTINATION_DOMAIN, NONCE, SENDER, RECIPIENT, DESTINATION_CALLER, MESSAGE_BODY); - - assert_eq(message.version(), VERSION); - assert_eq(message.source_domain(), SOURCE_DOMAIN); - assert_eq(message.destination_domain(), DESTINATION_DOMAIN); - assert_eq(message.nonce(), NONCE); - assert_eq(message.sender(), SENDER); - assert_eq(message.recipient(), RECIPIENT); - assert_eq(message.destination_caller(), DESTINATION_CALLER); - assert_eq(message.message_body(), MESSAGE_BODY); - assert_eq(message_body_from_bytes(&message.serialize()), MESSAGE_BODY); - } - - #[test] - public fun new_message_serialize_successful() { - let message = new(VERSION, SOURCE_DOMAIN, DESTINATION_DOMAIN, NONCE, SENDER, RECIPIENT, DESTINATION_CALLER, MESSAGE_BODY); - let raw_message = get_raw_test_message(); - - assert_eq(message.serialize(), raw_message); - } - - // update_message_body tests - - #[test] - public fun update_message_body_successful() { - let mut message = new(VERSION, SOURCE_DOMAIN, DESTINATION_DOMAIN, NONCE, SENDER, RECIPIENT, DESTINATION_CALLER, MESSAGE_BODY); - assert_eq(message.message_body(), MESSAGE_BODY); - - let new_message_body = x"123456"; - message.update_message_body(new_message_body); - assert_eq(message.message_body(), new_message_body); - } - - // update_destination_caller tests - - #[test] - public fun update_destination_caller_successful() { - let mut message = new(VERSION, SOURCE_DOMAIN, DESTINATION_DOMAIN, NONCE, SENDER, RECIPIENT, DESTINATION_CALLER, MESSAGE_BODY); - assert_eq(message.destination_caller(), DESTINATION_CALLER); - - message.update_destination_caller(SENDER); - assert_eq(message.destination_caller(), SENDER); - } - - // update_version tests - - #[test] - public fun update_version_successful() { - let mut message = new(VERSION, SOURCE_DOMAIN, DESTINATION_DOMAIN, NONCE, SENDER, RECIPIENT, DESTINATION_CALLER, MESSAGE_BODY); - assert_eq(message.version(), VERSION); - - message.update_version(VERSION+1); - assert_eq(message.version(), VERSION+1); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/serialize.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/serialize.move deleted file mode 100644 index 9278ab7a5..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/message/serialize.move +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: serialize -/// Contains serialization methods specific to the CCTP message format. -/// We cannot use BCS directly for uint serialization because BCS uses -/// little-endian, while CCTP messages use big-endian. So in all uint -/// serialization methods, reverse the bytes after calling into BCS. -module message_transmitter::serialize { - // === Imports === - - use sui::bcs; - - // === Public-View Functions === - - public fun serialize_u32_be(num: u32): vector { - let mut serialized = bcs::to_bytes(&num); - vector::reverse(&mut serialized); - serialized - } - - public fun serialize_u64_be(num: u64): vector { - let mut serialized = bcs::to_bytes(&num); - vector::reverse(&mut serialized); - serialized - } - - public fun serialize_u256_be(num: u256): vector { - let mut serialized = bcs::to_bytes(&num); - vector::reverse(&mut serialized); - serialized - } - - public fun serialize_address(address: address): vector { - bcs::to_bytes(&address) - } - - // === Test Functions === - - #[test] - fun test_serialize_u32() { - let num: u32 = 1234; - let expected = x"000004d2"; - - let result = serialize_u32_be(num); - assert!(expected == result); - } - - #[test] - fun test_serialize_u64() { - let num: u64 = 123456789; - let expected = x"00000000075bcd15"; - - let result = serialize_u64_be(num); - assert!(expected == result); - } - - #[test] - fun test_serialize_u256() { - let num: u256 = 123456789123456789123456789; - let expected = x"000000000000000000000000000000000000000000661efdf2e3b19f7c045f15"; - - let result = serialize_u256_be(num); - assert!(expected == result); - } - - #[test] - fun test_serialize_address() { - let address: address = @0xa9fb1b3009dcb79e2fe346c16a604b8fa8ae0a79; - let expected = x"000000000000000000000000a9fb1b3009dcb79e2fe346c16a604b8fa8ae0a79"; - - let result = serialize_address(address); - assert!(expected == result); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/receive_message.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/receive_message.move deleted file mode 100644 index 8b0a4909f..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/receive_message.move +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: receive_message -/// Contains public functions for receiving cross-chain messages. -/// -/// Note on upgrades: If interacting with this module from other packages, it -/// is recommended to call the receive_message_with_package_auth and stamp_receipt -/// methods from a PTB rather than directly from dependent packages. These functions -/// are version gated, so if this package is upgraded, the upgraded package must be called. -module message_transmitter::receive_message { - - // === Imports === - use sui::{ - event::emit, - }; - use message_transmitter::{ - attestation::{Self}, - auth::auth_caller_identifier, - message::{Self}, - state::{State}, - version_control::{Self, assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const EPaused: u64 = 0; - const EInvalidDestinationCaller: u64 = 1; - const EInvalidDestinationDomain: u64 = 2; - const EInvalidMessageVersion: u64 = 3; - const ENonceAlreadyUsed: u64 = 4; - const ERecipientNotAuth: u64 = 5; - const EInvalidReceiptVersion: u64 = 6; - - // === Structs === - public struct Receipt { - caller: address, - recipient: address, - source_domain: u32, - sender: address, - nonce: u64, - message_body: vector, - // Used to ensure all receipt calls are made on the same version of the package as receive_message. - current_version: u64 - } - - public struct StampedReceipt { - receipt: Receipt - } - - // === Events === - public struct MessageReceived has copy, drop { - caller: address, - source_domain: u32, - nonce: u64, - sender: address, - message_body: vector - } - - // === Public-Mutative Functions === - - /// Receives a message. Messages with a given nonce can only be received once for a - /// (sourceDomain, destinationDomain). - /// Intended to be called directly from an EOA when a package destination_caller is not specified on the message. - /// Please use receive_message_with_package_auth if a package destination_caller is specified. - /// - /// This function returns a `Receipt` struct ([Hot Potato](https://medium.com/@borispovod/move-hot-potato-pattern-bbc48a48d93c)) - /// after validating attestation and marking the nonce used. - /// In order to destroy the Receipt and complete the message, `stamp_receipt()` must be called with the receipt and - /// an authenticator struct (see the token_messenger_minter::receive_message_authenticator module for reference) and then - /// `complete_receive_message()` must be called with the Stamped Receipt to emit the `MessageReceived` event and complete the message. - /// It is recommended to call stamp_receipt and complete_receive_message functions from PTBs if possible to prevent breaking packages when an upgrade occurs. - /// create_stamp_receipt_ticket is safe to be called from a package as it is not version-gated. - /// Integrating handle_receive_message calls should only allow Receipt parameters (not StampedReceipt) and should call create_stamp_receipt_ticket in the - /// package to prevent message replays. - /// The Receipt/stamp pattern is used to enforce atomicity and ensure the intended receiver contract is called. - /// Example (in a PTB): - /// ``` - /// let receipt = message_transmitter::receive_message(message, attestation, &state); - /// let stamp_receipt_ticket = receiver_package::handle_receive_message(receipt); - /// let stamped_receipt = message_transmitter::stamp_receipt(stamp_receipt_ticket); - /// message_transmitter::complete_receive_message(receipt); - /// ``` - /// - /// Reverts if: - /// - contract is paused - /// - the message format is invalid - /// - the attestation is invalid - /// - the destination domain of the message does not match the local domain - /// - the destination caller of the message is set and does not match the caller - /// - the message version does not match the local message version - /// - a message from the source domain for the given nonce has already been received on the local domain - /// - /// Parameters: - /// - message: a message, in bytes, corresponding with the format defined in the `message_transmitter::message` module. - /// - attestation: a valid attestation consisting of concatenated 65-byte signature(s) of exactly `signature_threshold` signatures, in - /// increasing order of attester address. - /// - state: State shared object for the MessageTransmitter package. - public fun receive_message(message: vector, attestation: vector, state: &mut State, ctx: &TxContext): Receipt { - let sender = ctx.sender(); - receive_message_shared(message, attestation, sender, state) - } - - /// The same as receive_message, except intended to be used by a dependent package when a package as destination_caller - /// is specified in order to run an atomic operation. This function is version-gated and should be called from a PTB - /// to prevent breaking changes when an upgrade occurs. - /// create_receive_message_ticket is safe to be called directly from a package (not version-gated). - /// - /// This function uses a ReceiveMessageTicket for parameters so that the calling package can - /// call create_receive_message_ticket (not version-gated) from their package with parameters, and call - /// receive_message_with_package_auth (version-gated) from a PTB so packages don't have to be updated - /// during CCTP package upgrades. ReceiveMessageTicket also requires an Auth parameter. This is required - /// whenever a package as assigned as a destination_caller. destination_caller address should be set to the - /// auth identifier returned from the auth_caller_identifier function with the package's Auth struct. - /// Any struct that implements the drop trait can be used as an authenticator, but it is recommended to - /// use a dedicated auth struct. Calling contracts should be careful to not expose these objects to the - /// public or else messages intended for their package could be skipped. - /// - /// Example (in a PTB): - /// ``` - /// let receive_msg_ticket = your_package::prepare_receive_message_ticket(message, attestation); - /// let receipt = message_transmitter::receive_message_with_package_auth(receive_msg_ticket, &state); - /// // create_stamp_receipt_ticket is called from inside receiver_package::handle_receive_message() - /// let (message_body, stamp_receipt_ticket) = receiver_package::handle_receive_message(receipt); - /// let stamped_receipt = message_transmitter::stamp_receipt(stamp_receipt_ticket); - /// message_transmitter::complete_receive_message(stamped_receipt); - /// ``` - /// - /// Parameters: - /// - receive_message_ticket: a ticket struct containing the message, attestation, and an authenticator struct. - /// - state: State shared object for the MessageTransmitter package. - public fun receive_message_with_package_auth(receive_message_ticket: ReceiveMessageTicket, state: &mut State): Receipt { - let ReceiveMessageTicket { message, attestation, auth: _auth } = receive_message_ticket; - let sender_identifier = auth_caller_identifier(); - receive_message_shared(message, attestation, sender_identifier, state) - } - - /// Stamps a receipt after verifying the intended package acknowledged the message (through the Auth struct) by - /// returning a StampedReceipt struct that can be used to complete the message via complete_receive_message. - /// - /// This function is version-gated and should be called from a PTB to prevent breaking changes when an upgrade occurs. - /// create_stamp_receipt_ticket is safe to be called directly from a package (not version-gated), and its returned ticket - /// struct can be passed into stamp_receipt() in a PTB. - /// - /// Reverts if: - /// - an invalid auth module is provided - /// - /// Parameters: - /// - stamp_receipt_ticket: ticket struct created by create_stamp_receipt_ticket() with the receipt and auth struct - public fun stamp_receipt(stamp_receipt_ticket: StampReceiptTicket, state: &State): StampedReceipt { - let StampReceiptTicket { receipt, auth: _auth } = stamp_receipt_ticket; - assert_object_version_is_compatible_with_package(state.compatible_versions()); - assert_valid_receipt_version(&receipt); - assert!(receipt.recipient == auth_caller_identifier(), ERecipientNotAuth); - - StampedReceipt { receipt } - } - - /// Emits `MessageReceived` event for a stamped receipt and destroys the receipt. - /// Cannot be called without a StampedReceipt (returned from stamp_receipt). - /// - /// Parameters: - /// - stamped_receipt: a stamped receipt initially created from a receive_message call and verified in a stamp_receipt call - public fun complete_receive_message(stamped_receipt: StampedReceipt, state: &State) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - assert_valid_receipt_version(stamped_receipt.receipt()); - - emit(MessageReceived { - caller: stamped_receipt.receipt.caller, - source_domain: stamped_receipt.receipt.source_domain, - nonce: stamped_receipt.receipt.nonce, - sender: stamped_receipt.receipt.sender, - message_body: stamped_receipt.receipt.message_body - }); - - stamped_receipt.destroy_receipt(); - } - - /// Fetch the sender for a receipt. - public fun sender( - receipt: &Receipt - ): address { - receipt.sender - } - - /// Fetch the source_domain for a receipt. - public fun source_domain( - receipt: &Receipt - ): u32 { - receipt.source_domain - } - - /// Fetch the message_body for a receipt. - public fun message_body( - receipt: &Receipt - ): &vector { - &receipt.message_body - } - - /// Fetch the state_compatible_versions for a receipt. - public fun current_version( - receipt: &Receipt - ): u64 { - receipt.current_version - } - - // Fetch a reference to a receipt for a stamped receipt. - public fun receipt( - stamped_receipt: &StampedReceipt - ): &Receipt { - &stamped_receipt.receipt - } - - /// Fetch the nonce for a receipt. - public fun nonce( - receipt: &Receipt - ): u64 { - receipt.nonce - } - - /// Fetch the caller for a receipt. - public fun caller( - receipt: &Receipt - ): address { - receipt.caller - } - - /// Fetch the recipient for a receipt. - public fun recipient( - receipt: &Receipt - ): address { - receipt.recipient - } - - // === Ticket Structs/Functions === - /// create_receive_message_ticket and create_stamp_receipt_ticket are non version-gated functions, intended to be - /// called directly from other packages to create ticket structs that can be passed into public version-gated functions - /// outside of the calling package in a PTB. This prevents dependent packages from needing to be updated after CCTP upgrades. - public struct ReceiveMessageTicket { - auth: Auth, - message: vector, - attestation: vector - } - - /// Not version-gated so it can be safely called from a dependent package, - /// and then passed to receive_message_with_package_auth (version-gated) from a PTB. - /// See receive_message for parameter information. - public fun create_receive_message_ticket(auth: Auth, message: vector, attestation: vector): ReceiveMessageTicket { - ReceiveMessageTicket { - auth, - message, - attestation - } - } - - public struct StampReceiptTicket { - auth: Auth, - receipt: Receipt - } - - /// Not version-gated so it can be safely called from a dependent package, - /// and then passed to stamp_receipt (version-gated) from a PTB. - public fun create_stamp_receipt_ticket(auth: Auth, receipt: Receipt): StampReceiptTicket { - StampReceiptTicket { - auth, - receipt - } - } - - // === Private Functions === - - fun receive_message_shared(message: vector, attestation: vector, sender: address, state: &mut State): Receipt { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - assert!(!state.paused(), EPaused); - - let message_struct = message::from_bytes(&message); - attestation::verify_attestation_signatures(message, attestation, state); - - // Validate destination domain - let destination_domain = message_struct.destination_domain(); - assert!(destination_domain == state.local_domain(), EInvalidDestinationDomain); - - // Validate destination caller - let destination_caller = message_struct.destination_caller(); - assert!( - destination_caller == @0x0 || destination_caller == sender, - EInvalidDestinationCaller - ); - - // Validate message version - let message_version = message_struct.version(); - assert!(message_version == state.message_version(), EInvalidMessageVersion); - - // Validate nonce is available and mark it used - let source_domain = message_struct.source_domain(); - let nonce = message_struct.nonce(); - assert!(!state.is_nonce_used(source_domain, nonce), ENonceAlreadyUsed); - state.mark_nonce_used(source_domain, nonce); - - // Return unstamped receipt - Receipt { - caller: sender, - recipient: message_struct.recipient(), - source_domain, - sender: message_struct.sender(), - nonce, - message_body: message_struct.message_body(), - current_version: version_control::current_version() - } - } - - /// Asserts that the current package version matches the version stored on the Receipt. - /// This prevents receipt calls from being called on different package versions than receive_message - /// while a migration is in progress. - fun assert_valid_receipt_version(receipt: &Receipt) { - assert!(receipt.current_version() == version_control::current_version(), EInvalidReceiptVersion); - } - - /// Destroys a stamped receipt (and it's inner receipt) once it is no - /// longer needed in complete_receive_message. - fun destroy_receipt(stamped_receipt: StampedReceipt) { - let StampedReceipt { - receipt - } = stamped_receipt; - - let Receipt { - caller: _, - recipient: _, - source_domain: _, - sender: _, - nonce: _, - message_body: _, - current_version: _ - } = receipt; - } - - // === Test Functions === - #[test_only] use sui::{ - test_utils::{assert_eq} - }; - - #[test_only] - public fun create_receipt( - caller: address, - recipient: address, - source_domain: u32, - sender: address, - nonce: u64, - message_body: vector, - current_version: u64 - ): Receipt { - Receipt { - caller, - recipient, - source_domain, - sender, - nonce, - message_body, - current_version - } - } - - #[test_only] - public fun create_stamped_receipt(receipt: Receipt): StampedReceipt { - StampedReceipt { - receipt - } - } - - #[test_only] - public fun assert_receipts_eq( - given_receipt: &Receipt, - expected_receipt: &Receipt - ) { - // Validate each receipt field - assert_eq(given_receipt.caller(), expected_receipt.caller()); - assert_eq(given_receipt.recipient(), expected_receipt.recipient()); - assert_eq(given_receipt.source_domain(), expected_receipt.source_domain()); - assert_eq(given_receipt.sender(), expected_receipt.sender()); - assert_eq(given_receipt.nonce(), expected_receipt.nonce()); - assert_eq(*given_receipt.message_body(), *expected_receipt.message_body()); - } - - #[test_only] - public fun create_message_received_event( - caller: address, - source_domain: u32, - nonce: u64, - sender: address, - message_body: vector - ): MessageReceived { - MessageReceived { - caller, - source_domain, - nonce, - sender, - message_body - } - } -} - -// === Tests === - -#[test_only] -module message_transmitter::receive_message_authenticator { - public struct ReceiveMessageTestAuth has drop {} - - public fun new(): ReceiveMessageTestAuth { - ReceiveMessageTestAuth {} - } -} - -#[test_only] -module message_transmitter::receive_message_tests { - use sui::{ - event::{num_events}, - test_scenario, - test_utils::{assert_eq, destroy} - }; - use message_transmitter::{ - attestation, - auth::{Self, auth_caller_identifier}, - message, - message_transmitter_authenticator::{Self, SendMessageTestAuth}, - receive_message, - receive_message_authenticator::{Self, ReceiveMessageTestAuth}, - state::{Self}, - version_control - }; - use sui_extensions::test_utils::last_event_by_type; - - const USER: address = @0x1A; - const INVALID_USER: address = @0x2B; - const VALID_MESSAGE: vector = x"0000000000000000000000010000000000001cd80000000000000000000000000000000000000000000000000000000000000001949764be99bacbf6297178f1b467586bac40d0012cb816d5c1a2ea9167e79dfe00000000000000000000000000000000000000000000000000000000000000001234"; - const VALID_MESSAGE_ATTESTATION: vector = x"08e280f19802679344b388ed16a9537d4ff8f713858bd0e4184ad761f2998edb491dd7484648190b664f6e9c75049d9e3e092db2b753c97f44feb96ada3bc9f51c"; - const VALID_MESSAGE_WITH_CALLER: vector = x"0000000000000000000000010000000000001cd80000000000000000000000000000000000000000000000000000000000000001949764be99bacbf6297178f1b467586bac40d0012cb816d5c1a2ea9167e79dfe000000000000000000000000000000000000000000000000000000000000001a1234"; - const VALID_MESSAGE_WITH_CALLER_ATTESTATION: vector = x"6bd2d461eca43a988f109119c216406332a8630d35beec48bbb5fd105500455f64ea1bab07d8e0e301b68f783d8ba41ee620c12127872864ed284e538fb253ee1c"; - const VALID_MESSAGE_WITH_CALLER_WITH_PACKAGE_AUTH: vector = x"0000000000000000000000010000000000001cd80000000000000000000000000000000000000000000000000000000000000001949764be99bacbf6297178f1b467586bac40d0012cb816d5c1a2ea9167e79dfeda182d10342451ea8f9a01ef7964a44d91ef19e53685d579c1724d49f824d0a91234"; - const VALID_MESSAGE_WITH_CALLER_WITH_PACKAGE_AUTH_ATTESTATION: vector = x"b2897be69f5413f41a1edb31835a139f1aa32dd8621983589fa44cade41b3ba75103bdac6f480e425ea0573f6c17026abf7182828fbc8ea6da1992436021bde31c"; - - // === Test Functions === - - #[test_only] - fun setup_state( - scenario: &mut test_scenario::Scenario - ): state::State { - let ctx = test_scenario::ctx(scenario); - let mut message_transmitter_state = state::new_for_testing( - 1, 0, 10000, @0x0, ctx - ); - message_transmitter_state.enable_attester(@0xbcd4042de499d14e55001ccbb24a551f3b954096); - - message_transmitter_state - } - - // === Tests === - - #[test] - public fun test_receive_message_successful_no_destination_caller() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - let receipt = receive_message::receive_message(VALID_MESSAGE, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx()); - let expected_receipt = receive_message::create_receipt(USER, auth_caller_identifier(), 0, @0x1, 7384, x"1234", 1); - - receive_message::assert_receipts_eq(&receipt, &expected_receipt); - assert!(mt_state.is_nonce_used(0, 7384)); - - destroy(receipt); - destroy(expected_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_receive_message_with_package_auth_successful_no_destination_caller() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - let auth = receive_message_authenticator::new(); - let receive_message_ticket = receive_message::create_receive_message_ticket(auth, VALID_MESSAGE, VALID_MESSAGE_ATTESTATION); - let receipt = receive_message::receive_message_with_package_auth(receive_message_ticket, &mut mt_state); - let auth_id = auth_caller_identifier(); - let expected_receipt = receive_message::create_receipt(auth_id, auth_caller_identifier(), 0, @0x1, 7384, x"1234", 1); - - receive_message::assert_receipts_eq(&receipt, &expected_receipt); - assert!(mt_state.is_nonce_used(0, 7384)); - - destroy(receipt); - destroy(expected_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_receive_message_successful_with_destination_caller() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - let receipt = receive_message::receive_message(VALID_MESSAGE_WITH_CALLER, VALID_MESSAGE_WITH_CALLER_ATTESTATION, &mut mt_state, scenario.ctx()); - let expected_receipt = receive_message::create_receipt(USER, auth_caller_identifier(), 0, @0x1, 7384, x"1234", 1); - - receive_message::assert_receipts_eq(&receipt, &expected_receipt); - assert!(mt_state.is_nonce_used(0, 7384)); - - destroy(receipt); - destroy(expected_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_receive_message_with_package_auth_successful_with_destination_caller() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - let auth = receive_message_authenticator::new(); - let auth_id = auth_caller_identifier(); - let receive_message_ticket = receive_message::create_receive_message_ticket(auth, VALID_MESSAGE_WITH_CALLER_WITH_PACKAGE_AUTH, VALID_MESSAGE_WITH_CALLER_WITH_PACKAGE_AUTH_ATTESTATION); - - let receipt = receive_message::receive_message_with_package_auth(receive_message_ticket, &mut mt_state); - let expected_receipt = receive_message::create_receipt(auth_id, auth_caller_identifier(), 0, @0x1, 7384, x"1234", 1); - - receive_message::assert_receipts_eq(&receipt, &expected_receipt); - assert!(mt_state.is_nonce_used(0, 7384)); - - destroy(receipt); - destroy(expected_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = receive_message::EPaused)] - public fun test_receive_message_revert_paused() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Set state to paused - mt_state.set_paused(true); - - let receipt = receive_message::receive_message(VALID_MESSAGE, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx()); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = message::EInvalidMessageLength)] - public fun test_receive_message_revert_invalid_message_length() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Use malformed message - let message = x"1234"; - - let receipt = receive_message::receive_message(message, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx()); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = attestation::EInvalidAttestationLength)] - public fun test_receive_message_revert_invalid_attestation() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Use invalid attestation - let attestation = x"1234"; - - let receipt = receive_message::receive_message(VALID_MESSAGE, attestation, &mut mt_state, scenario.ctx()); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = receive_message::EInvalidDestinationDomain)] - public fun test_receive_message_revert_incorrect_destination_domain() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Use message and attestation with destination domain 2 - let message = x"0000000000000000000000020000000000001cd80000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000001234"; - let attestation = x"5c0fce0a69d89e2144e25c957eac85ad5dfcbdf8182fc2b3a5f9e56ebb0c559961a6cad5f7eeba132d6cca1f3f6e65e6334499ebdf4c27a5638c4cf79e0960231b"; - - let receipt = receive_message::receive_message(message, attestation, &mut mt_state, scenario.ctx()); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = receive_message::EInvalidDestinationCaller)] - public fun test_receive_message_revert_invalid_destination_caller() { - // Attempt to receive message with incorrect caller - let mut scenario = test_scenario::begin(INVALID_USER); - let mut mt_state = setup_state(&mut scenario); - - let receipt = receive_message::receive_message(VALID_MESSAGE_WITH_CALLER, VALID_MESSAGE_WITH_CALLER_ATTESTATION, &mut mt_state, scenario.ctx()); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = receive_message::EInvalidMessageVersion)] - public fun test_receive_message_revert_incorrect_message_version() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Use message and attestation for message version 2 - let message = x"0000000200000000000000010000000000001cd80000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000001234"; - let attestation = x"7a2f4d74e18652854006026a8d2c3865e149e271a588a49b684e7abeef5fc9f24a107a6e25008e902af298f6878b9ec5bc4075586e8b6006b789bc1ef3fd92541b"; - - let receipt = receive_message::receive_message(message, attestation, &mut mt_state, scenario.ctx()); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = receive_message::ENonceAlreadyUsed)] - public fun test_receive_message_revert_nonce_already_used() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Mark nonce already used prior to attempting receive - mt_state.mark_nonce_used(0, 7384); - - let receipt = receive_message::receive_message(VALID_MESSAGE, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx()); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_receive_message_revert_incompatible_version() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - let receipt = receive_message::receive_message( - VALID_MESSAGE, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx() - ); - - destroy(receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_stamp_receipt_successful() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - let receipt = receive_message::receive_message(VALID_MESSAGE, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx()); - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - - let expected_receipt = receive_message::create_receipt(USER, auth_caller_identifier(), 0, @0x1, 7384, x"1234", 1); - let receipt = stamped_receipt.receipt(); - receive_message::assert_receipts_eq( - &expected_receipt, - receipt - ); - - destroy(expected_receipt); - destroy(stamped_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = auth::EInvalidAuth)] - public fun test_stamp_receipt_revert_invalid_auth() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - let receipt = receive_message::receive_message(VALID_MESSAGE, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx()); - - // Attempt to use an invalid authenticator - let auth = @0x123; - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - - destroy(stamped_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = receive_message::ERecipientNotAuth)] - public fun test_stamp_receipt_revert_recipient_not_auth() { - let mut scenario = test_scenario::begin(USER); - let mt_state = setup_state(&mut scenario); - - // Create receipt where the recipient is a user address - let receipt = receive_message::create_receipt(USER, USER, 0, @0x1, 7384, x"1234", 1); - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - - destroy(stamped_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_stamp_receipt_revert_incompatible_state_version() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - // Create receipt where the recipient is a user address - let receipt = receive_message::create_receipt(USER, auth_caller_identifier(), 0, @0x1, 7384, x"1234", 1); - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - - destroy(stamped_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_stamp_receipt_revert_incompatible_receipt_version() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - // Create receipt where the recipient is a user address - let receipt = receive_message::create_receipt(USER, auth_caller_identifier(), 0, @0x1, 7384, x"1234", 123); - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - - destroy(stamped_receipt); - destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_complete_receive_message_successful() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - - let receipt = receive_message::receive_message(VALID_MESSAGE, VALID_MESSAGE_ATTESTATION, &mut mt_state, scenario.ctx()); - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - receive_message::complete_receive_message(stamped_receipt, &mt_state); - - assert_eq(num_events(), 1); - let message_received_event = last_event_by_type(); - assert_eq( - message_received_event, - receive_message::create_message_received_event(USER, 0, 7384, @0x1, x"1234" - )); - - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_complete_receive_message_revert_incompatible_state_version() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - let receipt = receive_message::create_receipt(USER, auth_caller_identifier(), 0, USER, 7384, x"1234", 1); - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - // Attempt to complete with an incorrect version - receive_message::complete_receive_message(stamped_receipt, &mt_state); - - destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = receive_message::EInvalidReceiptVersion)] - public fun test_complete_receive_message_revert_incompatible_receipt_version() { - let mut scenario = test_scenario::begin(USER); - let mut mt_state = setup_state(&mut scenario); - let receipt = receive_message::create_receipt(USER, auth_caller_identifier(), 0, USER, 7384, x"1234", 123); - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = receive_message::create_stamp_receipt_ticket(auth, receipt); - - let stamped_receipt = receive_message::stamp_receipt(stamp_receipt_ticket, &mt_state); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - // Attempt to complete with an incorrect version - receive_message::complete_receive_message(stamped_receipt, &mt_state); - - destroy(mt_state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/send_message.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/send_message.move deleted file mode 100644 index 286e12c11..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/send_message.move +++ /dev/null @@ -1,876 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: send_message -/// Contains public functions for sending cross-chain messages. -/// -/// Note on upgrades: It is recommended to call all of these public -/// methods from PTBs rather than directly from other packages. -/// These functions are version gated, so if the package is upgraded, -/// the upgraded package must be called. In most cases, we will provide -/// a migration period where both package versions are callable for a -/// period of time to avoid breaking all callers immediately. -module message_transmitter::send_message { - // === Imports === - use sui::{ - event::emit, - }; - use message_transmitter::{ - attestation, - auth::{auth_caller_identifier}, - message::{Self, Message}, - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const EPaused: u64 = 0; - const EMessageBodySizeExceedsLimit: u64 = 1; - const EInvalidRecipient: u64 = 2; - const EInvalidDestinationCaller: u64 = 3; - const ENotOriginalSender: u64 = 4; - const EIncorrectSourceDomain: u64 = 5; - - // === Events === - public struct MessageSent has copy, drop { - message: vector - } - - // === Public-Mutative Functions === - - /// Sends a message to the destination domain and recipient. - /// - /// Reverts if: - /// - contract is paused - /// - the Auth parameter is invalid - /// - the message body size exceeds the limit - /// - invalid (e.g. @0x0) recipient is given - /// - /// Parameters: - /// - send_message_ticket: a struct containing the necessary information to send a message created via create_send_message_ticket. - public fun send_message( - send_message_ticket: SendMessageTicket, - state: &mut State, - ): Message { - let SendMessageTicket { auth, destination_domain, recipient, message_body } = send_message_ticket; - let destination_caller = @0x0; - send_message_impl(state, auth, destination_domain, recipient, message_body, destination_caller) - } - - /// Same as send_message, except the receive_message call on the destination - /// domain must be called by `destination_caller`. - /// - /// WARNING: if the `destination_caller` does not represent a valid address, then - /// it will not be possible to broadcast the message on the destination domain. - /// This is an advanced feature, and the standard send_message() should be - /// preferred for use cases where a specific destination caller is not required. - /// - /// Note: If destination is a non-Move chain, destination_caller address should - /// be converted to hex and passed in in the @0x123 address format. - public fun send_message_with_caller( - send_message_with_caller_ticket: SendMessageWithCallerTicket, - state: &mut State, - ): Message { - let SendMessageWithCallerTicket { auth, destination_domain, recipient, message_body, destination_caller } = send_message_with_caller_ticket; - assert!(destination_caller != @0x0, EInvalidDestinationCaller); - send_message_impl(state, auth, destination_domain, recipient, message_body, destination_caller) - } - - /// Allows the sender of a previous Message (created by send_message or - /// send_message_with_caller) to send a new Message to replace the original as - /// long as they have a valid attestation for the message. - /// The new message will reuse the original message's nonce. For a given nonce, all - /// replacement message(s) and the original message are valid to broadcast on the destination - /// domain, until the first message at the nonce confirms, at which point all others are invalidated. - /// - /// Reverts if: - /// - original message or attestation are invalid - /// - tx sender is not the original message sender (identified by Auth parameter) - /// - the Auth parameter is invalid - /// - contract is paused - /// - source domain of original message is not the local domain - /// - new message body size exceeds the limit - /// - recipient is invalid (@0x0) - /// - /// Parameters: - /// - replace_message_ticket: a struct containing the necessary information to replace a message created via create_replace_message_ticket. - /// - /// Note: The sender of the replaced message must be the same as the caller of the original message. - /// This is identified using the Auth generic parameter. - public fun replace_message( - replace_message_ticket: ReplaceMessageTicket, - state: &State - ): Message { - let ReplaceMessageTicket { auth: _auth, original_raw_message, original_attestation, new_message_body, new_destination_caller } = replace_message_ticket; - assert_object_version_is_compatible_with_package(state.compatible_versions()); - assert!(!state.paused(), EPaused); - - attestation::verify_attestation_signatures(original_raw_message, original_attestation, state); - let mut message = message::from_bytes(&original_raw_message); - - let sender_identifier = auth_caller_identifier(); - assert!(message.sender() == sender_identifier, ENotOriginalSender); - assert!(message.source_domain() == state.local_domain(), EIncorrectSourceDomain); - - let final_destination_caller = new_destination_caller.get_with_default(message.destination_caller()); - message.update_destination_caller(final_destination_caller); - - let final_message_body = new_message_body.get_with_default(message.message_body()); - message.update_message_body(final_message_body); - - message.update_version(state.message_version()); - - serialize_message_and_emit_event(message, state); - - message - } - - // === Ticket Structs/Functions === - /// create_..._ticket functions below are non version-gated functions, intended to be - /// called directly from other packages to create ticket structs that can be passed into public version-gated functions - /// outside of the calling package in a PTB. This prevents dependent packages from needing to be updated after CCTP upgrades. - public struct SendMessageTicket { - auth: Auth, - destination_domain: u32, - recipient: address, - message_body: vector, - } - - /// Parameters: - /// - auth: an authenticator struct - /// This is required to securely assign a sender address associated with the calling contract to the message. - /// Any struct that implements the drop trait can be used as an authenticator, but it is recommended to - /// use a dedicated auth struct. - /// Calling contracts should be careful to not expose these objects to the public or else messages from - /// their package could be forged. - /// An example implementation exists in the token_messenger_minter::message_transmitter_authenticator module. - /// - destination_domain: domain to send message to - /// - recipient: address of message recipient on destination domain - /// Note: If destination is a non-Move chain, mint_recipient - /// address should be converted to hex and passed in in the - /// @0x123 address format. - /// - message_body: raw bytes content of the message - public fun create_send_message_ticket( - auth: Auth, - destination_domain: u32, - recipient: address, - message_body: vector, - ): SendMessageTicket { - SendMessageTicket { auth, destination_domain, recipient, message_body } - } - - public struct SendMessageWithCallerTicket { - auth: Auth, - destination_domain: u32, - recipient: address, - destination_caller: address, - message_body: vector - } - - /// See create_send_message_ticket for other parameters - /// Parameters: - /// - destination_caller: address of the required caller on the destination domain. - /// Note: If destination is a non-Move chain, destination_caller address should - /// be converted to hex and passed in in the @0x123 address format. - public fun create_send_message_with_caller_ticket( - auth: Auth, - destination_domain: u32, - recipient: address, - destination_caller: address, - message_body: vector - ): SendMessageWithCallerTicket { - SendMessageWithCallerTicket { auth, destination_domain, recipient, destination_caller, message_body } - } - - public struct ReplaceMessageTicket { - auth: Auth, - original_raw_message: vector, - original_attestation: vector, - new_message_body: Option>, - new_destination_caller: Option
- } - - /// Parameters: - /// - auth: an authenticator struct, must match the auth used to send the original message. - /// - original_raw_message: original message in bytes. - /// - original_attestation: valid attestation for the original message in bytes. - /// - new_message_body: new message body, defaults to body of the original message. - /// - new_destination_caller: new destination caller for message, can be @0x0 for no caller, - /// defaults to destination_caller of original_message. - public fun create_replace_message_ticket( - auth: Auth, - original_raw_message: vector, - original_attestation: vector, - new_message_body: Option>, - new_destination_caller: Option
- ): ReplaceMessageTicket { - ReplaceMessageTicket { auth, original_raw_message, original_attestation, new_message_body, new_destination_caller } - } - - // === Private Functions === - - /// Shared implementation for sending a message. - fun send_message_impl( - state: &mut State, - _auth: Auth, - destination_domain: u32, - recipient: address, - message_body: vector, - destination_caller: address - ): Message { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - assert!(!state.paused(), EPaused); - - let sender_identifier = auth_caller_identifier(); - let nonce = state.reserve_and_increment_nonce(); - - let message = message::new( - state.message_version(), - state.local_domain(), - destination_domain, - nonce, - sender_identifier, - recipient, - destination_caller, - message_body - ); - - serialize_message_and_emit_event(message, state); - - message - } - - /// Shared functionality between send_message, send_message_with_caller, and replace_message. - /// Performs validations and emits a MessageSent event for the serialized message. - fun serialize_message_and_emit_event( - message: Message, - state: &State - ) { - assert!(message.message_body().length() <= state.max_message_body_size(), EMessageBodySizeExceedsLimit); - assert!(message.recipient() != @0x0, EInvalidRecipient); - - let serialized_message = message.serialize(); - emit(MessageSent{ message: serialized_message }); - } - - // === Test Functions === - - #[test_only] - public fun create_message_sent_event( - version: u32, - source_domain: u32, - destination_domain: u32, - nonce: u64, - sender: address, - recipient: address, - destination_caller: address, - message_body: vector - ): MessageSent { - let message = message::new(version, source_domain, destination_domain, nonce, sender, recipient, destination_caller, message_body); - MessageSent { message: message.serialize() } - } -} - -// === Tests === - -#[test_only] -module message_transmitter::message_transmitter_authenticator { - public struct SendMessageTestAuth has drop {} - - public fun new(): SendMessageTestAuth { - SendMessageTestAuth {} - } -} - -#[test_only] -module message_transmitter::send_message_tests { - use sui::{ - event::{num_events}, - test_scenario, - test_utils::{Self, assert_eq} - }; - use message_transmitter::{ - attestation, - auth::{Self, auth_caller_identifier}, - message, - message_transmitter_authenticator, - send_message, - state, - version_control - }; - use sui_extensions::test_utils::last_event_by_type; - - const RECIPIENT: address = @0x1A; - const DEST_CALLER: address = @0x2A; - const ATTESTER: address = @0xBcd4042DE499D14e55001CcbB24a551F3b954096; - - #[test_only] - fun get_valid_send_message_and_attestation(state: &state::State): (vector, vector) { - let original_message = message::new( - state.message_version(), - 0, - 1, - 7384, - auth_caller_identifier(), - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - x"1234", - ); - let serialized_message = original_message.serialize(); - let original_attestation = x"ec683cd0a4324b5bf45fbb329f9f883207a56311caf4dd3e247b1687fbeafa8a278b232dc51f77db03e3630185bb9be6286e65d53f1734dd607a06526e97d1791b"; - (serialized_message, original_attestation) - } - - #[test_only] - fun get_invalid_send_message_and_attestation(state: &state::State): (vector, vector) { - let original_message = message::new( - state.message_version(), - 0, - 1, - 7384, - @0x1234, - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - x"1234", - ); - let serialized_message = original_message.serialize(); - let original_attestation = x"e8334264b7fa8e70b61be9f759cfb1710ba8b7c8dac3a39a7dbb5abba1bb94136521cc61c85e45ba92237dfe738cf60d99a441f0cdabe5fbdb5902bbdd396ab71c"; - (serialized_message, original_attestation) - } - - #[test_only] - fun setup_state( - scenario: &mut test_scenario::Scenario - ): state::State { - let ctx = test_scenario::ctx(scenario); - let mut message_transmitter_state = state::new_for_testing( - 0, 0, 10000, @0x0, ctx - ); - message_transmitter_state.enable_attester(ATTESTER); - - message_transmitter_state - } - - #[test] - public fun test_send_message_successful() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Expect to successfully send message - let ticket = send_message::create_send_message_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, x"1234" - ); - send_message::send_message( - ticket, &mut mt_state - ); - - assert_eq(num_events(), 1); - let message_sent_event = last_event_by_type(); - assert_eq(message_sent_event, send_message::create_message_sent_event( - 0, - 0, - 0, - 0, - auth_caller_identifier(), - RECIPIENT, - @0x0, - x"1234", - )); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EPaused)] - public fun test_send_message_revert_paused() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Update message transmitter state to paused - mt_state.set_paused(true); - - // Expect call to revert due to paused state - let ticket = send_message::create_send_message_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, x"1234" - ); - send_message::send_message( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = auth::EInvalidAuth)] - public fun test_send_message_revert_invalid_auth() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Expect call to revert due to invalid authenticator - let ticket = send_message::create_send_message_ticket( - @0x123, 0, RECIPIENT, x"1234" - ); - send_message::send_message( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EMessageBodySizeExceedsLimit)] - public fun test_send_message_revert_message_size_exceeds_max() { - let mut scenario = test_scenario::begin(@0x0); - // Initialize state with message size limit of 1 to trigger error - let mut mt_state = state::new_for_testing( - 0, 0, 1, @0x0, scenario.ctx() - ); - - // Expect call to revert due to too large message body - let ticket = send_message::create_send_message_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, x"1234" - ); - send_message::send_message( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EInvalidRecipient)] - public fun test_send_message_revert_invalid_recipient() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Expect call to revert due to invalid recipient - let ticket = send_message::create_send_message_ticket( - message_transmitter_authenticator::new(), 0, @0x0, x"1234" - ); - send_message::send_message( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_send_message_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - // Expect call to revert due to incompatible version - let ticket = send_message::create_send_message_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, x"1234" - ); - send_message::send_message( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_send_message_with_caller_successful() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Expect to successfully send message with caller - let ticket = send_message::create_send_message_with_caller_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, DEST_CALLER, x"1234" - ); - send_message::send_message_with_caller( - ticket, &mut mt_state - ); - - assert_eq(num_events(), 1); - let message_sent_event = last_event_by_type(); - assert_eq(message_sent_event, send_message::create_message_sent_event( - 0, - 0, - 0, - 0, - auth_caller_identifier(), - RECIPIENT, - DEST_CALLER, - x"1234", - )); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EPaused)] - public fun test_send_message_with_caller_revert_paused() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Update message transmitter state to paused - mt_state.set_paused(true); - - // Expect to revert due to paused state - let ticket = send_message::create_send_message_with_caller_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, DEST_CALLER, x"1234" - ); - send_message::send_message_with_caller( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EInvalidDestinationCaller)] - public fun test_send_message_with_caller_revert_invalid_destination_caller() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Expect to revert due to invalid destination_caller - let ticket = send_message::create_send_message_with_caller_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, @0x0, x"1234" - ); - send_message::send_message_with_caller( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = auth::EInvalidAuth)] - public fun test_send_message_with_caller_revert_invalid_auth() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Expect to revert due to invalid authenticator - let ticket = send_message::create_send_message_with_caller_ticket( - @0x123, 0, RECIPIENT, DEST_CALLER, x"1234" - ); - send_message::send_message_with_caller( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EMessageBodySizeExceedsLimit)] - public fun test_send_message_with_caller_revert_message_size_exceeds_max() { - let mut scenario = test_scenario::begin(@0x0); - // Initialize state with message size limit of 1 to trigger error - let mut mt_state = state::new_for_testing( - 0, 0, 1, @0x0, scenario.ctx() - ); - - // Expect to revert due to too large message - let ticket = send_message::create_send_message_with_caller_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, DEST_CALLER, x"1234" - ); - send_message::send_message_with_caller( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EInvalidRecipient)] - public fun test_send_message_with_caller_revert_invalid_recipient() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Expect to revert due to invalid recipient - let ticket = send_message::create_send_message_with_caller_ticket( - message_transmitter_authenticator::new(), 0, @0x0, DEST_CALLER, x"1234" - ); - send_message::send_message_with_caller( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_send_message_with_caller_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - // Expect call to revert due to incompatible version - let ticket = send_message::create_send_message_with_caller_ticket( - message_transmitter_authenticator::new(), 0, RECIPIENT, DEST_CALLER, x"1234" - ); - send_message::send_message_with_caller( - ticket, &mut mt_state - ); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_replace_message_successful_no_changes() { - let mut scenario = test_scenario::begin(@0x0); - let mt_state = setup_state(&mut scenario); - - // Expect to successfully replace message without changes - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - assert_eq(num_events(), 1); - let message_sent_event = last_event_by_type(); - assert_eq(message_sent_event, send_message::create_message_sent_event( - 0, - 0, - 1, - 7384, - auth_caller_identifier(), - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - x"1234", - )); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_replace_message_successful_change_message_body() { - let mut scenario = test_scenario::begin(@0x0); - let mt_state = setup_state(&mut scenario); - - // Expect to successfully replace message with new message body - let new_message_body = x"123456"; - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::some(new_message_body), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - assert_eq(num_events(), 1); - let message_sent_event = last_event_by_type(); - assert_eq(message_sent_event, send_message::create_message_sent_event( - 0, - 0, - 1, - 7384, - auth_caller_identifier(), - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - new_message_body, - )); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - public fun test_replace_message_successful_change_destination_caller() { - let mut scenario = test_scenario::begin(@0x0); - let mt_state = setup_state(&mut scenario); - - // Expect to successfully replace message with new destination caller - let new_destination_caller = @0x3B; - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::some(new_destination_caller) - ); - send_message::replace_message(ticket, &mt_state); - - assert_eq(num_events(), 1); - let message_sent_event = last_event_by_type(); - assert_eq(message_sent_event, send_message::create_message_sent_event( - 0, - 0, - 1, - 7384, - auth_caller_identifier(), - @0x1CD223dBC9ff35fF6B29dAB2339ACC842BF58cCb, - new_destination_caller, - x"1234", - )); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EPaused)] - public fun test_replace_message_revert_paused() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Update message transmitter state to paused - mt_state.set_paused(true); - - // Expect call to revert due to paused message transmitter state - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = auth::EInvalidAuth)] - public fun test_replace_message_revert_invalid_auth() { - let mut scenario = test_scenario::begin(@0x0); - let mt_state = setup_state(&mut scenario); - - // Expect call to revert due to invalid auth - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - let ticket = send_message::create_replace_message_ticket( - @0x1234, message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = attestation::EInvalidAttestationLength)] - public fun test_replace_message_revert_invalid_attestation() { - let mut scenario = test_scenario::begin(@0x0); - let mt_state = setup_state(&mut scenario); - - // Expect call to revert due to invalid attestation - let (message, mut attestation) = get_valid_send_message_and_attestation(&mt_state); - attestation.pop_back(); - - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::ENotOriginalSender)] - public fun test_replace_message_revert_not_original_sender() { - let mut scenario = test_scenario::begin(@0x0); - let mt_state = setup_state(&mut scenario); - - // Expect call to revert due to invalid sender - let (message, attestation) = get_invalid_send_message_and_attestation(&mt_state); - - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EIncorrectSourceDomain)] - public fun test_replace_message_revert_incorrect_source_domain() { - let mut scenario = test_scenario::begin(@0x0); - // Initialize state with different local domain to trigger error - let mut mt_state = state::new_for_testing( - 1, 0, 10000, @0x0, scenario.ctx() - ); - mt_state.enable_attester(ATTESTER); - - // Expect call to revert due to incorrect source domain - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = send_message::EMessageBodySizeExceedsLimit)] - public fun test_replace_message_revert_message_size_exceeds_max() { - let mut scenario = test_scenario::begin(@0x0); - // Initialize state with message size limit of 1 to trigger error - let mut mt_state = state::new_for_testing( - 0, 0, 1, @0x0, scenario.ctx() - ); - mt_state.enable_attester(ATTESTER); - - // Expect call to revert due to message size exceeding limit - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - test_utils::destroy(mt_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_replace_message_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let mut mt_state = setup_state(&mut scenario); - - // Add a new version and remove the current version - mt_state.add_compatible_version(5); - mt_state.remove_compatible_version(version_control::current_version()); - - // Expect call to revert due to incompatible version - let (message, attestation) = get_valid_send_message_and_attestation(&mt_state); - let ticket = send_message::create_replace_message_ticket( - message_transmitter_authenticator::new(), message, attestation, option::none(), option::none() - ); - send_message::replace_message(ticket, &mt_state); - - test_utils::destroy(mt_state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/state.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/state.move deleted file mode 100644 index a10d0c1e1..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/state.move +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: state -/// This module contains the core global Shared State used in the message_transmitter package. -module message_transmitter::state { - // === Imports === - use sui::{ - address, - hash, - bcs, - table::{Self, Table}, - vec_set::{Self, VecSet}, - }; - use message_transmitter::{ - roles::{Self, Roles}, - version_control - }; - - // === Structs === - public struct State has key { - id: UID, - /// Immutable local domain - local_domain: u32, - /// Immutable message body version - message_version: u32, - /// Max message body size - max_message_body_size: u64, - /// Set of enabled attesters - enabled_attesters: VecSet
, - /// Next available nonce for this source domain - next_available_nonce: u64, - /// Maps a hash of (source_domain, nonce) -> bool (false if unused, true if used) - used_nonces: Table, - /// Signature threshold for attestations - signature_threshold: u64, - /// Is contract paused - paused: bool, - /// All roles for package - roles: Roles, - /// The set of package version numbers that object is compatible with - compatible_versions: VecSet - } - - // === Public-Mutative Functions === - - /// Initialize the state with an immutable local domain and version, initial max message body size, attester, and initial roles. - /// Roles should be separated to different addresses later. - public(package) fun new(local_domain: u32, message_version: u32, max_message_body_size: u64, caller: address, ctx: &mut TxContext): State { - State { - id: object::new(ctx), - roles: roles::new(caller, caller, caller, ctx), - local_domain, - message_version, - max_message_body_size, - enabled_attesters: vec_set::empty(), - next_available_nonce: 0, - used_nonces: table::new(ctx), - signature_threshold: 1, - paused: false, - compatible_versions: vec_set::singleton(version_control::current_version()) - } - } - - #[allow(lint(share_owned))] - public(package) fun share_state(state: State) { - transfer::share_object(state); - } - - // === Getters === - - public fun local_domain(state: &State): u32 { - state.local_domain - } - - public fun message_version(state: &State): u32 { - state.message_version - } - - public fun max_message_body_size(state: &State): u64 { - state.max_message_body_size - } - - public fun is_attester_enabled(state: &State, attester: address): bool { - state.enabled_attesters.contains(&attester) - } - - public fun get_num_enabled_attesters(state: &State): u64 { - state.enabled_attesters.size() - } - - public fun enabled_attesters(state: &State): &VecSet
{ - &state.enabled_attesters - } - - public fun next_available_nonce(state: &State): u64 { - state.next_available_nonce - } - - public fun is_nonce_used(state: &State, source_domain: u32, nonce: u64): bool { - let used_nonce_key = generate_used_nonce_key(source_domain, nonce); - if (state.used_nonces.contains(used_nonce_key)) { - *state.used_nonces.borrow(used_nonce_key) - } else false - } - - public fun signature_threshold(state: &State): u64 { - state.signature_threshold - } - - public fun paused(state: &State): bool { - state.paused - } - - public fun roles(state: &State): &Roles { - &state.roles - } - - public fun compatible_versions(state: &State): &VecSet { - &state.compatible_versions - } - - // === Public-Package Functions === - - public(package) fun roles_mut(state: &mut State): &mut Roles { - &mut state.roles - } - - public(package) fun set_max_message_body_size(state: &mut State, max_message_body_size: u64) { - state.max_message_body_size = max_message_body_size; - } - - public(package) fun enable_attester(state: &mut State, attester: address) { - state.enabled_attesters.insert(attester); - } - - public(package) fun disable_attester(state: &mut State, attester: address) { - state.enabled_attesters.remove(&attester); - } - - public(package) fun set_paused(state: &mut State, paused: bool) { - state.paused = paused; - } - - public(package) fun reserve_and_increment_nonce(state: &mut State): u64 { - let reserved_nonce = state.next_available_nonce(); - state.next_available_nonce = reserved_nonce + 1; - reserved_nonce - } - - public(package) fun mark_nonce_used(state: &mut State, source_domain: u32, nonce: u64) { - let used_nonce_key = generate_used_nonce_key(source_domain, nonce); - state.used_nonces.add(used_nonce_key, true); - } - - public(package) fun set_signature_threshold(state: &mut State, signature_threshold: u64) { - state.signature_threshold = signature_threshold; - } - - public(package) fun add_compatible_version(state: &mut State, version: u64) { - state.compatible_versions.insert(version); - } - - public(package) fun remove_compatible_version(state: &mut State, version: u64) { - state.compatible_versions.remove(&version); - } - - // === Private Functions === - - /// Helper function for calculating the key for a (source_domain, nonce) pair in a Table. - /// (source_domain, nonce) keys in Tables are represented as an address of the keccak256 - /// hash of their concatenated bytes with a dash delimiter. keccak256 returns a 32 bytes - /// array so this can always be represented as an address type. - fun generate_used_nonce_key(source_domain: u32, nonce: u64): address { - // Create (source_domain, nonce) concatenated bytes vector - let mut used_nonce_key = bcs::to_bytes(&source_domain); - used_nonce_key.append(b"-"); - used_nonce_key.append(bcs::to_bytes(&nonce)); - - // Hash them and return - address::from_bytes(hash::keccak256(&used_nonce_key)) - } - - // === Test Functions === - - #[test_only] - public fun new_for_testing( - local_domain: u32, - message_version: u32, - max_message_body_size: u64, - caller: address, - ctx: &mut TxContext - ): State { - State { - id: object::new(ctx), - roles: roles::new(caller, caller, caller, ctx), - local_domain, - message_version, - max_message_body_size, - enabled_attesters: vec_set::empty(), - next_available_nonce: 0, - used_nonces: table::new(ctx), - signature_threshold: 1, - paused: false, - compatible_versions: vec_set::singleton(version_control::current_version()) - } - } - - #[test_only] - public fun remove_used_nonce(state: &mut State, source_domain: u32, nonce: u64) { - let used_nonce_key = generate_used_nonce_key(source_domain, nonce); - state.used_nonces.remove(used_nonce_key); - } - - #[test_only] use message_transmitter::state::{Self}; - #[test_only] use sui::test_utils; - - // === Tests === - - #[test] - fun state_new_creates_object() { - let ctx = &mut tx_context::dummy(); - - let expected_msg_version = 1; - let expected_role = @0x1; - let expected_local_domain = 0; - let initial_max_message_body_size = 100; - let expected_max_message_body_size = 200; - let initial_attester = @0x2; - let expected_attester = @0x3; - let expected_signature_threshold = 2; - let expected_next_available_nonce = 1; - let used_source_domain = 1; - let used_nonce = 0; - let unused_source_domain = 2; - let new_version = 5; - - // Create state object, then modify and add some objects to the maps - let mut state_obj = state::new(expected_local_domain, expected_msg_version, initial_max_message_body_size, expected_role, ctx); - state_obj.set_max_message_body_size(expected_max_message_body_size); - state_obj.set_paused(true); - state_obj.reserve_and_increment_nonce(); - state_obj.mark_nonce_used(used_source_domain, used_nonce); - state_obj.set_signature_threshold(expected_signature_threshold); - state_obj.enable_attester(initial_attester); - state_obj.enable_attester(expected_attester); - state_obj.disable_attester(initial_attester); - - assert!(state_obj.local_domain() == expected_local_domain); - assert!(state_obj.message_version() == expected_msg_version); - assert!(state_obj.max_message_body_size() == expected_max_message_body_size); - assert!(state_obj.next_available_nonce() == expected_next_available_nonce); - assert!(state_obj.is_nonce_used(used_source_domain, used_nonce)); - assert!(!state_obj.is_nonce_used(unused_source_domain, used_nonce)); - assert!(state_obj.signature_threshold() == expected_signature_threshold); - assert!(state_obj.paused()); - - assert!(state_obj.is_attester_enabled(expected_attester)); - assert!(!state_obj.is_attester_enabled(initial_attester)); - assert!(state_obj.get_num_enabled_attesters() == 1); - assert!(state_obj.enabled_attesters().contains(&expected_attester)); - assert!(!state_obj.enabled_attesters().contains(&initial_attester)); - - assert!(state_obj.roles().owner() == expected_role); - assert!(state_obj.roles().pending_owner() == option::none()); - assert!(state_obj.roles().pauser() == expected_role); - assert!(state_obj.roles().attester_manager() == expected_role); - - state_obj.add_compatible_version(new_version); - assert!(state_obj.compatible_versions().contains(&new_version)); - state_obj.remove_compatible_version(new_version); - assert!(!state_obj.compatible_versions().contains(&new_version)); - - // Empty table before destroying - state_obj.remove_used_nonce(used_source_domain, used_nonce); - test_utils::destroy(state_obj); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/vector_utils.move b/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/vector_utils.move deleted file mode 100644 index 6e8313d34..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/message_transmitter/sources/vector_utils.move +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: vector_utils -/// Provides vector utilities that are not included -/// in the sui::vector module. -module message_transmitter::vector_utils { - // === Errors === - - const EStartIndexOutOfBounds: u64 = 0; - const EEndIndexOutOfBounds: u64 = 1; - - // === Public-View Functions === - - /// Performs a deep-copy of a portion of vector selected from `start` to - /// `end` (`end` not included). - public fun slice(data: &vector, start_index: u64, end_index: u64): vector { - assert!(end_index > start_index, EEndIndexOutOfBounds); - assert!(start_index < data.length(), EStartIndexOutOfBounds); - assert!(end_index <= data.length(), EEndIndexOutOfBounds); - - let mut result = vector::empty(); - let mut i = start_index; - - while (i < end_index) { - result.push_back(copy data[i]); - i = i + 1; - }; - - result - } - - // === Test Functions === - - #[test] - fun test_slice_normal_case_successful() { - let data = vector[1, 2, 3, 4, 5]; - let result = slice(&data, 1, 4); - assert!(result == vector[2, 3, 4], 0); - } - - #[test] - fun test_slice_entire_vector_successful() { - let data = vector[1, 2, 3, 4, 5]; - let result = slice(&data, 0, 5); - assert!(result == data, 0); - } - - #[test] - fun test_slice_single_element_successful() { - let data = vector[1, 2, 3, 4, 5]; - let result = slice(&data, 2, 3); - assert!(result == vector[3], 0); - } - - #[test] - fun test_slice_generic_type_successful() { - let data = vector[b"hello", b"world", b"move"]; - let result = slice(&data, 0, 2); - assert!(result == vector[b"hello", b"world"], 0); - } - - #[test] - #[expected_failure(abort_code = EEndIndexOutOfBounds)] - fun test_slice_invalid_indices_start_gt_end() { - let data = vector[1, 2, 3, 4, 5]; - slice(&data, 3, 2); - } - - #[test] - #[expected_failure(abort_code = EEndIndexOutOfBounds)] - fun test_slice_invalid_indices_start_eq_end() { - let data = vector[1, 2, 3, 4, 5]; - let result = slice(&data, 2, 2); - assert!(vector::is_empty(&result), 0); - } - - #[test] - #[expected_failure(abort_code = EStartIndexOutOfBounds)] - fun test_slice_start_index_out_of_bounds() { - let data = vector[1, 2, 3, 4, 5]; - slice(&data, 5, 6); - } - - #[test] - #[expected_failure(abort_code = EEndIndexOutOfBounds)] - fun test_slice_end_index_out_of_bounds() { - let data = vector[1, 2, 3, 4, 5]; - slice(&data, 2, 6); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/Move.toml b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/Move.toml deleted file mode 100644 index a65b93866..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/Move.toml +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[package] -name = "TokenMessengerMinter" -edition = "2024.beta" -license = "Apache 2.0" - -[dependencies.MessageTransmitter] -local = "../message_transmitter" - -[dependencies.stablecoin] -local = "../../../stablecoin-sui/packages/stablecoin" - -[dependencies.sui_extensions] -local = "../../../stablecoin-sui/packages/sui_extensions" - -[addresses] -token_messenger_minter = "_" -message_transmitter = "_" - -[dev-dependencies] - -[dev-addresses] -token_messenger_minter = "0x31cc14d80c175ae39777c0238f20594c6d4869cfab199f40b69f3319956b8beb" -message_transmitter = "0x4931e06dce648b3931f890035bd196920770e913e43e45990b383f6486fdd0a5" diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/migration.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/migration.move deleted file mode 100644 index a7710bf96..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/migration.move +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// module: migration -/// Contains admin functions for migrating the package and state object to new versions. -module token_messenger_minter::migration { - // === Imports === - use std::u64::{min, max}; - use sui::event; - use token_messenger_minter::{ - state::State, - version_control - }; - - // === Errors === - - /// Migration related error codes, starting at 100. - const ENotOwner: u64 = 0; - const EMigrationStarted: u64 = 100; - const EMigrationNotStarted: u64 = 101; - const EObjectMigrated: u64 = 102; - const ENotPendingVersion: u64 = 103; - - // === Events === - - public struct MigrationStarted has copy, drop { - compatible_versions: vector - } - - public struct MigrationAborted has copy, drop { - compatible_versions: vector - } - - public struct MigrationCompleted has copy, drop { - compatible_versions: vector - } - - // === Public functions === - - /// Starts the migration process, making the State object be - /// additionally compatible with this package's version. - entry fun start_migration(state: &mut State, ctx: &TxContext) { - assert!(state.roles().owner() == ctx.sender(), ENotOwner); - assert!(state.compatible_versions().size() == 1, EMigrationStarted); - - let active_version = state.compatible_versions().keys()[0]; - assert!(active_version < version_control::current_version(), EObjectMigrated); - - state.add_compatible_version(version_control::current_version()); - - event::emit(MigrationStarted { - compatible_versions: *state.compatible_versions().keys() - }); - } - - /// Aborts the migration process, reverting the State object's compatibility - /// to the previous version. - entry fun abort_migration(state: &mut State, ctx: &TxContext) { - assert!(state.roles().owner() == ctx.sender(), ENotOwner); - assert!(state.compatible_versions().size() == 2, EMigrationNotStarted); - - let pending_version = max( - state.compatible_versions().keys()[0], - state.compatible_versions().keys()[1] - ); - assert!(pending_version == version_control::current_version(), ENotPendingVersion); - - state.remove_compatible_version(pending_version); - - event::emit(MigrationAborted { - compatible_versions: *state.compatible_versions().keys() - }); - } - - /// Completes the migration process, making the State object be - /// only compatible with this package's version. - entry fun complete_migration(state: &mut State, ctx: &TxContext) { - assert!(state.roles().owner() == ctx.sender(), ENotOwner); - assert!(state.compatible_versions().size() == 2, EMigrationNotStarted); - - let (version_a, version_b) = ( - state.compatible_versions().keys()[0], - state.compatible_versions().keys()[1] - ); - let (active_version, pending_version) = ( - min(version_a, version_b), - max(version_a, version_b) - ); - - assert!(pending_version == version_control::current_version(), ENotPendingVersion); - - state.remove_compatible_version(active_version); - - event::emit(MigrationCompleted { - compatible_versions: *state.compatible_versions().keys() - }); - } - - // === Test-Functions === - - #[test_only] - public(package) fun create_migration_started_event(compatible_versions: vector): MigrationStarted { - MigrationStarted { compatible_versions } - } - - #[test_only] - public(package) fun create_migration_aborted_event(compatible_versions: vector): MigrationAborted { - MigrationAborted { compatible_versions } - } - - #[test_only] - public(package) fun create_migration_completed_event(compatible_versions: vector): MigrationCompleted { - MigrationCompleted { compatible_versions } - } -} - -#[test_only] -module token_messenger_minter::migration_tests { - use sui::{ - event, - test_scenario::{Self, Scenario}, - test_utils::{Self, assert_eq}, - }; - use token_messenger_minter::{ - migration, - state::{Self, State}, - version_control - }; - use sui_extensions::test_utils::{last_event_by_type}; - - // Test addresses - const DEPLOYER: address = @0x0; - const OWNER: address = @0x10; - const RANDOM_ADDRESS: address = @0x1000; - - public struct MIGRATION_TESTS has drop {} - - #[test, expected_failure(abort_code = migration::ENotOwner)] - fun start_migration__should_fail_is_caller_is_not_owner() { - let (mut state, mut scenario) = setup(); - - // Some random address attempts to start a migration, should fail. - scenario.next_tx(RANDOM_ADDRESS); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EMigrationStarted)] - fun start_migration__should_fail_if_migration_started() { - let (mut state, mut scenario) = setup(); - - // Start a migration to this package. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - // Attempt to start another migration, should fail. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EObjectMigrated)] - fun start_migration__should_fail_if_state_is_migrated() { - let (mut state, mut scenario) = setup(); - - // Complete a migration flow to this package. - { - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - }; - - // Attempt to start a migration to this package again, should fail. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test] - fun start_migration__should_succeed_and_pass_all_assertions() { - let (mut state, mut scenario) = setup(); - - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotOwner)] - fun abort_migration__should_fail_is_caller_is_not_owner() { - let (mut state, mut scenario) = setup(); - - // Some random address attempts to start a migration, should fail. - scenario.next_tx(RANDOM_ADDRESS); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EMigrationNotStarted)] - fun abort_migration__should_fail_if_migration_not_started() { - let (mut state, mut scenario) = setup(); - - // Attempt to abort a migration that has not started, should fail. - scenario.next_tx(OWNER); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotPendingVersion)] - fun abort_migration__should_fail_if_the_pending_version_is_not_this_package_version() { - let (mut state, mut scenario) = setup(); - - // Start a migration flow to a later package. - scenario.next_tx(OWNER); - start_migration_to_custom_version_for_testing(&mut state, version_control::current_version() + 100); - - // Attempt to abort the migration using this package, should fail. - scenario.next_tx(OWNER); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test] - fun abort_migration__should_succeed_and_pass_all_assertions() { - let (mut state, mut scenario) = setup(); - - // Start a migration. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - // Abort the migration. - scenario.next_tx(OWNER); - test_abort_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotOwner)] - fun complete_migration__should_fail_is_caller_is_not_owner() { - let (mut state, mut scenario) = setup(); - - // Some random address attempts to start a migration, should fail. - scenario.next_tx(RANDOM_ADDRESS); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::EMigrationNotStarted)] - fun complete_migration__should_fail_if_migration_not_started() { - let (mut state, mut scenario) = setup(); - - // Attempt to complete a migration that has not started, should fail. - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test, expected_failure(abort_code = migration::ENotPendingVersion)] - fun complete_migration__should_fail_if_the_pending_version_is_not_this_package_version() { - let (mut state, mut scenario) = setup(); - - // Start a migration flow to a later package. - scenario.next_tx(OWNER); - start_migration_to_custom_version_for_testing(&mut state, version_control::current_version() + 100); - - // Attempt to complete the migration using this package, should fail. - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - #[test] - fun complete_migration__should_succeed_and_pass_all_assertions() { - let (mut state, mut scenario) = setup(); - - // Start a migration. - scenario.next_tx(OWNER); - test_start_migration(&mut state, &mut scenario); - - // Complete the migration. - scenario.next_tx(OWNER); - test_complete_migration(&mut state, &mut scenario); - - cleanup(state, scenario); - } - - // === Helpers === - - /// Sets up an outdated State object that is initialized with - /// (package's version - 1). - fun setup(): (State, Scenario) { - let mut scenario = test_scenario::begin(DEPLOYER); - let mut state = state::new(0, OWNER, scenario.ctx()); - - let previous_version = version_control::current_version() - 1; - - state.remove_compatible_version(version_control::current_version()); - state.add_compatible_version(previous_version); - assert_eq(*state.compatible_versions().keys(), vector[previous_version]); - - (state, scenario) - } - - fun cleanup(state: State, scenario: Scenario) { - test_utils::destroy(state); - scenario.end(); - } - - fun test_start_migration(state: &mut State, scenario: &mut Scenario) { - migration::start_migration(state, scenario.ctx()); - - let updated_compatible_versions = state.compatible_versions().keys(); - assert_eq(updated_compatible_versions.length(), 2); - assert_eq(updated_compatible_versions.contains(&version_control::current_version()), true); - - assert_eq(event::num_events(), 1); - assert_eq( - last_event_by_type(), - migration::create_migration_started_event(*updated_compatible_versions) - ); - } - - fun test_abort_migration(state: &mut State, scenario: &mut Scenario) { - migration::abort_migration(state, scenario.ctx()); - - let updated_compatible_versions = state.compatible_versions().keys(); - assert_eq(updated_compatible_versions.length(), 1); - assert_eq(updated_compatible_versions.contains(&version_control::current_version()), false); - - assert_eq(event::num_events(), 1); - assert_eq( - last_event_by_type(), - migration::create_migration_aborted_event(*updated_compatible_versions) - ); - } - - fun test_complete_migration(state: &mut State, scenario: &mut Scenario) { - migration::complete_migration(state, scenario.ctx()); - - let updated_compatible_versions = state.compatible_versions().keys(); - assert_eq(*updated_compatible_versions, vector[version_control::current_version()]); - - assert_eq(event::num_events(), 1); - assert_eq( - last_event_by_type(), - migration::create_migration_completed_event(*updated_compatible_versions) - ); - } - - fun start_migration_to_custom_version_for_testing(state: &mut State, version: u64) { - assert_eq(state.compatible_versions().keys().length(), 1); - - state.add_compatible_version(version); - - assert_eq(state.compatible_versions().keys().length(), 2); - assert_eq(state.compatible_versions().contains(&version), true); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/pausable.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/pausable.move deleted file mode 100644 index ffbd37886..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/pausable.move +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: pausable -/// Admin functions for contract pause functionality -module token_messenger_minter::pausable { - // === Imports === - use sui::event::emit; - use token_messenger_minter::{ - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const ENotPauser: u64 = 0; - const EAlreadyPaused: u64 = 1; - const ENotPaused: u64 = 2; - - // === Events === - public struct Pause has copy, drop {} - - public struct Unpause has copy, drop {} - - // === Admin Functions === - - /// Called by the owner to pause the contract by setting paused - /// to true. Only pauses functions that check this `paused` value. - entry fun pause(state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_pauser(state, ctx); - assert!(!state.paused(), EAlreadyPaused); - - state.set_paused(true); - emit(Pause {}); - } - - /// Called by the owner to unpause the contract by setting paused - /// to false. Only pauses functions that check this `paused` value. - entry fun unpause(state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_pauser(state, ctx); - assert!(state.paused(), ENotPaused); - - state.set_paused(false); - emit(Unpause {}); - } - - // === Private Functions === - - fun verify_pauser(state: &State, ctx: &TxContext) { - assert!(ctx.sender() == state.roles().pauser(), ENotPauser); - } - - // === Test Functions === - #[test_only] use sui::{ - event::{num_events}, - test_scenario, - test_utils - }; - #[test_only] use sui_extensions::test_utils::{last_event_by_type}; - #[test_only] use token_messenger_minter::{ - state::{Self}, - version_control - }; - - // pause tests - - #[test] - public fun test_pause_successful() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Successful pause from pauser - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - assert!(num_events() == 1); - last_event_by_type(); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotPauser)] - public fun test_pause_not_pauser() { - let mut scenario = test_scenario::begin(@0x0); - let (pauser, not_pauser) = (@0x1, @0x2); - - // Create a new State - let mut state = state::new(0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Revert if not called from pauser - scenario.next_tx(not_pauser); - { - pause(&mut state, scenario.ctx()); - assert!(!state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = EAlreadyPaused)] - public fun test_pause_already_paused() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Revert if already paused - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - pause(&mut state, scenario.ctx()); - }; - - test_utils::destroy(state); - scenario.end(); - } - - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_pause_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State with incompatible version - let mut state = state::new(0, pauser, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if incompatible version - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(!state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // unpause tests - - #[test] - public fun test_unpause_successful() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Successful unpause from pauser - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - unpause(&mut state, scenario.ctx()); - assert!(!state.paused(), 2); - assert!(num_events() == 2); - last_event_by_type(); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotPauser)] - public fun test_unpause_not_pauser() { - let mut scenario = test_scenario::begin(@0x0); - let (pauser, not_pauser) = (@0x1, @0x2); - - // Create a new State - let mut state = state::new(0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - // Pause the tx so we can test unpausing - scenario.next_tx(pauser); - { - pause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - }; - - // Test: Revert if not called from pauser - scenario.next_tx(not_pauser); - { - unpause(&mut state, scenario.ctx()); - assert!(state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ENotPaused)] - public fun test_unpause_already_unpaused() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State - let mut state = state::new(0, pauser, scenario.ctx()); - // Starts out not paused - assert!(!state.paused(), 0); - - // Test: Revert if already unpaused - scenario.next_tx(pauser); - { - unpause(&mut state, scenario.ctx()); - assert!(!state.paused(), 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_unpause_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let pauser = @0x1; - - // Create a new State with incompatible version - let mut state = state::new(0, pauser, scenario.ctx()); - state.set_paused(true); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if incompatible version - scenario.next_tx(pauser); - { - unpause(&mut state, scenario.ctx()); - assert!(state.paused()); - }; - - test_utils::destroy(state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/remote_token_messenger.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/remote_token_messenger.move deleted file mode 100644 index e2f25d738..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/remote_token_messenger.move +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: remote_token_messenger -/// Admin functions for controlling remote token messenger, including -/// adding/removing the remote token messenger for a remote domain. -module token_messenger_minter::remote_token_messenger { - // === Imports === - use sui::event::emit; - use token_messenger_minter::{ - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const ENotOwner: u64 = 0; - const EEmptyAddress: u64 = 1; - const ERemoteTokenMessengerAlreadyAdded: u64 = 2; - const ERemoteTokenMessengerNotAdded: u64 = 3; - - // === Events === - - public struct RemoteTokenMessengerAdded has copy, drop { - domain: u32, - token_messenger: address, - } - - public struct RemoteTokenMessengerRemoved has copy, drop { - domain: u32, - token_messenger: address, - } - - // === Admin Functions === - - /// Links a pair of remote domain and remote token messenger. Adds a - /// (remote_domain, remote_token_messenger) pair by updating `remote_token_messengers` - /// mapping. A remote domain can only map to one remote token messenger. - /// Remote token messenger is the 32 byte hex representation of the token messenger on the remote chain. - entry fun add_remote_token_messenger( - remote_domain: u32, - remote_token_messenger: address, - state: &mut State, - ctx: &TxContext - ) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_owner(state, ctx); - assert!(remote_token_messenger != @0x0, EEmptyAddress); - assert!(!state.remote_token_messenger_for_remote_domain_exists(remote_domain), ERemoteTokenMessengerAlreadyAdded); - - state.add_remote_token_messenger(remote_domain, remote_token_messenger); - emit(RemoteTokenMessengerAdded {domain: remote_domain, token_messenger: remote_token_messenger}); - } - - /// Unlinks a pair of remote domain and remote token messenger. Adds a - /// (remote_domain, remote_token_messenger) pair by updating `remote_token_messengers` - /// mapping. A remote domain can only map to one remote token messenger. - /// Remote token messenger is the 32 byte hex representation of the token messenger on the remote chain. - entry fun remove_remote_token_messenger( - remote_domain: u32, - state: &mut State, - ctx: &TxContext - ) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_owner(state, ctx); - assert!(state.remote_token_messenger_for_remote_domain_exists(remote_domain), ERemoteTokenMessengerNotAdded); - - let remote_token_messenger_to_remove = state.remote_token_messenger_from_remote_domain(remote_domain); - state.remove_remote_token_messenger(remote_domain); - emit(RemoteTokenMessengerRemoved {domain: remote_domain, token_messenger: remote_token_messenger_to_remove}); - } - - // === Private Functions === - fun verify_owner(state: &State, ctx: &TxContext) { - assert!(ctx.sender() == state.roles().owner(), ENotOwner); - } - - // === Test Functions === - #[test_only] use sui::{ - event::{num_events}, - test_scenario::{Self}, - test_utils::{Self, assert_eq} - }; - #[test_only] use sui_extensions::test_utils::{last_event_by_type}; - #[test_only] use token_messenger_minter::{ - remote_token_messenger::{Self}, - state::{Self}, - version_control - }; - - // === Tests === - - // add_remote_token_messenger tests - - #[test] - public fun test_add_remote_token_messenger_successful() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, remote_token_messenger) = (@0x1, @0x2); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - - // Test: Successful adding remote token messenger - scenario.next_tx(owner); - { - remote_token_messenger::add_remote_token_messenger(remote_domain, remote_token_messenger, &mut state, scenario.ctx()); - assert_eq(state.remote_token_messenger_from_remote_domain(remote_domain), remote_token_messenger); - assert!(num_events() == 1); - let event = last_event_by_type(); - assert!(event.domain == remote_domain); - assert!(event.token_messenger == remote_token_messenger); - }; - - // Destroy objects - state.remove_remote_token_messenger(remote_domain); - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = remote_token_messenger::ENotOwner)] - public fun test_add_remote_token_messenger_revert_not_owner() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, non_owner, remote_token_messenger) = (@0x1, @0x2, @0x3); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - - // Test: Revert if the caller is not the owner - scenario.next_tx(non_owner); - { - remote_token_messenger::add_remote_token_messenger(remote_domain, remote_token_messenger, &mut state, scenario.ctx()); - assert!(!state.remote_token_messenger_for_remote_domain_exists(remote_domain), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = remote_token_messenger::EEmptyAddress)] - public fun test_add_remote_token_messenger_revert_empty_address() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, remote_token_messenger) = (@0x1, @0x0); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - - // Test: Revert if the remote token messenger is empty - scenario.next_tx(owner); - { - remote_token_messenger::add_remote_token_messenger(remote_domain, remote_token_messenger, &mut state, scenario.ctx()); - assert!(!state.remote_token_messenger_for_remote_domain_exists(remote_domain), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = remote_token_messenger::ERemoteTokenMessengerAlreadyAdded)] - public fun test_remote_token_messenger_revert_already_added() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, remote_token_messenger) = (@0x1, @0x2); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - - // Add the remote token messenger for the first time - scenario.next_tx(owner); - { - remote_token_messenger::add_remote_token_messenger(remote_domain, remote_token_messenger, &mut state, scenario.ctx()); - assert!(state.remote_token_messenger_for_remote_domain_exists(remote_domain), 0); - }; - - // Attempt to add the same remote token messenger again - scenario.next_tx(owner); - { - remote_token_messenger::add_remote_token_messenger(remote_domain, remote_token_messenger, &mut state, scenario.ctx()); - }; - - // Destroy state and scenario - state.remove_remote_token_messenger(remote_domain); - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_add_remote_token_messenger_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, remote_token_messenger) = (@0x1, @0x2); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(owner); - { - remote_token_messenger::add_remote_token_messenger(remote_domain, remote_token_messenger, &mut state, scenario.ctx()); - assert!(!state.remote_token_messenger_for_remote_domain_exists(remote_domain), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - // remove_remote_token_messenger tests - - #[test] - public fun test_remove_token_messenger_successful() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, remote_token_messenger) = (@0x1, @0x2); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - - // Add remote token messenger first - scenario.next_tx(owner); - { - remote_token_messenger::add_remote_token_messenger(remote_domain, remote_token_messenger, &mut state, scenario.ctx()); - assert_eq(state.remote_token_messenger_from_remote_domain(remote_domain), remote_token_messenger); - }; - - // Test: Successful removing of remote token messenger - { - remote_token_messenger::remove_remote_token_messenger( - remote_domain, &mut state, scenario.ctx() - ); - // Validate the local token was removed - assert!(!state.remote_token_messenger_for_remote_domain_exists(remote_domain), 1); - assert!(num_events() == 2); - let event = last_event_by_type(); - assert!(event.domain == remote_domain); - assert!(event.token_messenger == remote_token_messenger); - }; - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = remote_token_messenger::ENotOwner)] - public fun test_remove_remote_token_messenger_revert_not_owner() { - let mut scenario = test_scenario::begin(@0x0); - let (owner, non_owner) = (@0x1, @0x2); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - - // Test: Revert if the caller is not the owner - scenario.next_tx(non_owner); - remote_token_messenger::remove_remote_token_messenger( - remote_domain, &mut state, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = remote_token_messenger::ERemoteTokenMessengerNotAdded)] - public fun test_remove_remote_token_messenger_revert_not_added() { - let mut scenario = test_scenario::begin(@0x0); - let (owner) = (@0x1); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - - // Attempt to remove without adding - scenario.next_tx(owner); - remote_token_messenger::remove_remote_token_messenger( - remote_domain, &mut state, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_remove_remote_token_messenger_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let owner = @0x1; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, owner, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incomaptible version - scenario.next_tx(owner); - remote_token_messenger::remove_remote_token_messenger( - remote_domain, &mut state, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/role_management.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/role_management.move deleted file mode 100644 index 767c7c10d..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/role_management.move +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: role_management -/// TokenMessengerMinter role management functions -module token_messenger_minter::role_management { - // === Imports === - use sui::event::emit; - use token_messenger_minter::{ - state::{State}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const ERoleAlreadySet: u64 = 0; - - // === Events === - public struct SetTokenController has copy, drop { - token_controller: address, - } - - public struct PauserChanged has copy, drop { - new_pauser: address, - } - - // === Admin Functions === - - /// Called by the owner to update the `pauser` role. - entry fun update_pauser(new_pauser: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - validate_role_transfer(new_pauser, state.roles().pauser(), state, ctx); - - state.roles_mut().update_pauser(new_pauser); - emit(PauserChanged {new_pauser: state.roles().pauser()}); - } - - /// Called by the owner to update the `token_controller` role. - entry fun update_token_controller(new_token_controller: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - validate_role_transfer(new_token_controller, state.roles().token_controller(), state, ctx); - - state.roles_mut().update_token_controller(new_token_controller); - emit(SetTokenController {token_controller: state.roles().token_controller()}); - } - - /// Proxy call to start ownership transfer - entry fun transfer_ownership(new_owner: address, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - state.roles_mut().owner_role_mut().begin_role_transfer(new_owner, ctx); - } - - /// Proxy call to accept ownership transfer - entry fun accept_ownership(state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - state.roles_mut().owner_role_mut().accept_role(ctx); - } - - // === Private Functions === - - fun validate_role_transfer(new_address: address, current_address: address, state: &State, ctx: &TxContext) { - state.roles().owner_role().assert_sender_is_active_role(ctx); - assert!(new_address != current_address, ERoleAlreadySet) - } - - // === Test Functions === - #[test_only] use sui::{ - event::{num_events}, - test_scenario::{Self, Scenario}, - test_utils - }; - #[test_only] use sui_extensions::{ - test_utils::{last_event_by_type}, - two_step_role - }; - #[test_only] use token_messenger_minter::{ - state::{Self}, - version_control - }; - - #[test_only] const OWNER: address = @0x123; - - #[test_only] - fun setup(): (Scenario, State) { - let mut scenario = test_scenario::begin(@0x0); - let state = state::new(0, OWNER, scenario.ctx()); - - (scenario, state) - } - - // update_pauser tests - - #[test] - public fun test_update_pauser_successful() { - let (mut scenario, mut state) = setup(); - let new_pauser = @0x2; - - // Test: Successful update of pauser - scenario.next_tx(OWNER); - { - update_pauser(new_pauser, &mut state, scenario.ctx()); - assert!(state.roles().pauser() == new_pauser); - assert!(num_events() == 1); - assert!(last_event_by_type().new_pauser == new_pauser); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = two_step_role::ESenderNotActiveRole)] - public fun test_update_pauser_revert_not_owner() { - let (mut scenario, mut state) = setup(); - let (non_owner, new_pauser) = (@0x2, @0x3); - - // Test: Revert if the caller is not the owner - scenario.next_tx(non_owner); - { - update_pauser(new_pauser, &mut state, scenario.ctx()); - assert!(state.roles().pauser() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ERoleAlreadySet)] - public fun test_update_pauser_revert_already_set() { - let (mut scenario, mut state) = setup(); - - // Test: Revert if the new pauser address is the same as existing - scenario.next_tx(OWNER); - { - update_pauser(state.roles().pauser(), &mut state, scenario.ctx()); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_update_pauser_revert_incompatible_version() { - let (mut scenario, mut state) = setup(); - let new_pauser = @0x2; - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if incompatible version - scenario.next_tx(OWNER); - { - update_pauser(new_pauser, &mut state, scenario.ctx()); - assert!(state.roles().pauser() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // update_token_controller tests - - #[test] - public fun test_update_token_controller_successful() { - let (mut scenario, mut state) = setup(); - let new_token_controller = @0x2; - - // Test: Successful update of token_controller - scenario.next_tx(OWNER); - { - update_token_controller(new_token_controller, &mut state, scenario.ctx()); - assert!(state.roles().token_controller() == new_token_controller, 0); - assert!(num_events() == 1); - assert!(last_event_by_type().token_controller == new_token_controller); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = two_step_role::ESenderNotActiveRole)] - public fun test_update_token_controller_revert_not_owner() { - let (mut scenario, mut state) = setup(); - let (non_owner, new_token_controller) = (@0x2, @0x3); - - // Test: Revert if the caller is not the owner - scenario.next_tx(non_owner); - { - update_token_controller(new_token_controller, &mut state, scenario.ctx()); - assert!(state.roles().token_controller() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = ERoleAlreadySet)] - public fun test_update_token_controller_revert_already_set() { - let (mut scenario, mut state) = setup(); - - // Test: Revert if the new token_controller address is the same as existing - scenario.next_tx(OWNER); - { - update_token_controller(state.roles().token_controller(), &mut state, scenario.ctx()); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_update_token_controller_revert_incompatible_version() { - let (mut scenario, mut state) = setup(); - let new_controller = @0x2; - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert if incompatible version - scenario.next_tx(OWNER); - { - update_pauser(new_controller, &mut state, scenario.ctx()); - assert!(state.roles().pauser() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // transfer_ownership tests - - #[test] - public fun test_transfer_ownership_successful() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - - // Test: Successful start transfer of ownership - scenario.next_tx(OWNER); - { - transfer_ownership(new_owner, &mut state, scenario.ctx()); - assert!(*state.roles().pending_owner().borrow() == new_owner); - assert!(state.roles().owner() == OWNER); - // Event fields tested in two_step_role module - assert!(num_events() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_transfer_ownership_revert__incompatible_version() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(OWNER); - { - transfer_ownership(new_owner, &mut state, scenario.ctx()); - assert!(state.roles().pending_owner() == option::none()); - assert!(state.roles().owner() == OWNER); - }; - - test_utils::destroy(state); - scenario.end(); - } - - // accept_ownership tests - - #[test] - public fun test_accept_ownership_successful() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - - // Start transfer ownership first - scenario.next_tx(OWNER); - transfer_ownership(new_owner, &mut state, scenario.ctx()); - - // Test: Successfully accept/transfer ownership - scenario.next_tx(new_owner); - { - accept_ownership(&mut state, scenario.ctx()); - assert!(state.roles().owner() == new_owner); - assert!(state.roles().pending_owner() == option::none()); - // Event fields tested in two_step_role module - assert!(num_events() == 1); - }; - - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_accept_ownership__incompatible_version() { - let (mut scenario, mut state) = setup(); - let new_owner = @0x2; - - // Start transfer ownership first - scenario.next_tx(OWNER); - transfer_ownership(new_owner, &mut state, scenario.ctx()); - - // Update version to incompatible - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(new_owner); - { - accept_ownership(&mut state, scenario.ctx()); - assert!(state.roles().owner() == OWNER); - assert!(state.roles().pending_owner() == option::some(new_owner)); - }; - - test_utils::destroy(state); - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/roles.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/roles.move deleted file mode 100644 index 76399eacc..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/roles.move +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: roles -/// This module contains all roles for the package -module token_messenger_minter::roles { - // === Imports === - use sui_extensions::two_step_role::{Self, TwoStepRole}; - - // === Structs === - - /// Track roles via EOAs (rather than Capabilities) to retain revocability. - public struct Roles has key, store { - id: UID, - // Controls other roles - owner: TwoStepRole, - // Controls pausing/unpausing - pauser: address, - // Controls remote resources and burn limits - token_controller: address - } - - public struct OwnerRole has drop {} - - // === Public-Mutative Functions === - - /// Create and return a new Roles state object - public(package) fun new(owner: address, pauser: address, token_controller: address, ctx: &mut TxContext): Roles { - Roles { - id: object::new(ctx), - owner: two_step_role::new(OwnerRole {}, owner), - pauser, - token_controller - } - } - - // === Public-View Functions === - - public(package) fun owner_role_mut(roles: &mut Roles): &mut TwoStepRole { - &mut roles.owner - } - - public fun owner_role(roles: &Roles): &TwoStepRole { - &roles.owner - } - - public fun owner(roles: &Roles): address { - roles.owner.active_address() - } - - public fun pending_owner(roles: &Roles): Option
{ - roles.owner.pending_address() - } - - public fun pauser(roles: &Roles): address { - roles.pauser - } - - public fun token_controller(roles: &Roles): address { - roles.token_controller - } - - // === Public-Package Functions === - - public(package) fun update_pauser(roles: &mut Roles, new_pauser: address) { - roles.pauser = new_pauser; - } - - public(package) fun update_token_controller(roles: &mut Roles, new_token_controller: address) { - roles.token_controller = new_token_controller; - } - - // === Tests === - #[test_only] use sui::test_utils; - - #[test] - fun test_new_creates_object() { - let mut ctx = tx_context::dummy(); - - let expected_owner = @0x1; - let expected_pauser = @0x2; - let expected_token_controller = @0x3; - - let roles_obj = new(expected_owner, expected_pauser, expected_token_controller, &mut ctx); - - assert!(roles_obj.owner() == expected_owner, 0); - assert!(roles_obj.pending_owner() == option::none(), 1); - assert!(roles_obj.pauser() == expected_pauser, 2); - assert!(roles_obj.token_controller() == expected_token_controller, 3); - - test_utils::destroy(roles_obj); - } - - #[test] - fun test_update_pauser() { - let mut ctx = tx_context::dummy(); - - let (original_pauser, new_pauser) = (@0x1, @0x2); - - let mut roles_obj = new(original_pauser, original_pauser, original_pauser, &mut ctx); - assert!(roles_obj.pauser() == original_pauser, 0); - - // Test: owner is updated - roles_obj.update_pauser(new_pauser); - assert!(roles_obj.pauser() == new_pauser, 1); - - test_utils::destroy(roles_obj); - } - - #[test] - fun test_update_token_controller() { - let mut ctx = tx_context::dummy(); - - let (original_token_controller, new_token_controller) = (@0x1, @0x2); - - let mut roles_obj = new(original_token_controller, original_token_controller, original_token_controller, &mut ctx); - assert!(roles_obj.token_controller() == original_token_controller, 0); - - // Test: owner is updated - roles_obj.update_token_controller(new_token_controller); - assert!(roles_obj.token_controller() == new_token_controller, 1); - - test_utils::destroy(roles_obj); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/token_controller.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/token_controller.move deleted file mode 100644 index d39848c6d..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/token_controller.move +++ /dev/null @@ -1,880 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: token_controller -/// Admin functions for controlling local/remote token state, including -/// mapping address of local tokens to addresses of corresponding tokens -/// on remote domains, and limiting the amount of each token that can -/// be burned per message. -/// Note: This token_controller module only supports stablecoin coins: https://github.com/circlefin/stablecoin-sui/tree/master/packages/stablecoin -module token_messenger_minter::token_controller { - // === Imports === - use sui::event::emit; - use token_messenger_minter::{ - state::{State}, - token_utils, - version_control::{assert_object_version_is_compatible_with_package} - }; - use stablecoin::treasury::{MintCap, Treasury, is_authorized_mint_cap}; - - // === Errors === - const ENotTokenController: u64 = 0; - const EEmptyAddress: u64 = 1; - const ETokenPairAlreadyLinked: u64 = 2; - const ETokenPairNotLinked: u64 = 3; - const EMintCapAlreadyAdded: u64 = 4; - const EMintCapDoesNotExist: u64 = 5; - const EMintCapNotDeAuthorized: u64 = 6; - - // === Events === - public struct SetBurnLimitPerMessage has copy, drop { - token: address, - burn_limit_per_message: u64, - } - - public struct TokenPairLinked has copy, drop { - local_token: address, - remote_domain: u32, - remote_token: address, - } - - public struct TokenPairUnlinked has copy, drop { - local_token: address, - remote_domain: u32, - remote_token: address, - } - - public struct MintCapAdded has copy, drop { - local_token: address, - mint_cap_id: ID - } - - public struct MintCapRemoved has copy, drop { - local_token: address, - mint_cap_id: ID - } - - // === Admin Functions === - - /// Sets the maximum burn amount per message for a given localToken after removing the existing limit (if exists). - /// Burns with amounts exceeding burnLimitPerMessage will revert. - /// Mints do not respect this value, so if this limit is reduced, previously burned tokens will still be mintable. - /// Generic type `T` should be the Witness of the local Sui token being linked. - entry fun set_max_burn_amount_per_message(burn_limit_per_message: u64, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_token_controller(state, ctx); - - let token_id = token_utils::calculate_token_id(); - if (state.burn_limit_for_token_id_exists(token_id)) { - state.remove_burn_limit(token_id); - }; - - state.add_burn_limit(token_id, burn_limit_per_message); - emit(SetBurnLimitPerMessage {token: token_id, burn_limit_per_message}); - } - - /// Links a pair of local and remote tokens to be supported by the TokenMessengerMinter. Associates a - /// (remote_domain, remote_token) pair with a localToken (e.g. a Sui Coin) by updating `remote_tokens_to_local_tokens` - /// mapping. A remote token (on a certain remote domain) can only map to one local token, but many remote tokens can - /// map to the same local token. Setting a token pair does not enable the localToken (that requires calling `set_max_burn_amount_per_message`). - /// Note that local tokens on Sui are represented by a unique token id. See token_utils::calculate_token_id function for more info. - /// Generic type `T` should be the Witness of the local Sui token being linked. - /// Remote token is the 32 byte hex representation of the token on the remote chain. - entry fun link_token_pair( - remote_domain: u32, - remote_token: address, - state: &mut State, - ctx: &TxContext - ) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_token_controller(state, ctx); - assert!(remote_token != @0x0, EEmptyAddress); - assert!(!state.local_token_from_remote_token_exists(remote_domain, remote_token), ETokenPairAlreadyLinked); - - let local_token_id = token_utils::calculate_token_id(); - state.add_local_token_for_remote_token(remote_domain, remote_token, local_token_id); - emit(TokenPairLinked {local_token: local_token_id, remote_domain, remote_token}); - } - - /// Unlinks a pair of local and remote tokens for this TokenMessengerMinter. Removes link from remoteToken to - /// localToken for given remoteDomain by updating mapping. A remote token (on a certain remote domain) can only - /// map to one local token, but many remote tokens can map to the same local token. - /// Generic type `T` should be the Witness of the local Sui token being linked. - /// Remote token is the 32 byte hex representation of the token on the remote chain. - entry fun unlink_token_pair( - remote_domain: u32, - remote_token: address, - state: &mut State, - ctx: &TxContext - ) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_token_controller(state, ctx); - assert!(remote_token != @0x0, EEmptyAddress); - assert!(state.local_token_from_remote_token_exists(remote_domain, remote_token), ETokenPairNotLinked); - state.remove_local_token_for_remote_token(remote_domain, remote_token); - let local_token_id = token_utils::calculate_token_id(); - emit(TokenPairUnlinked {local_token: local_token_id, remote_domain, remote_token}); - } - - /// Adds a `MintCap` mint capability for the given stablecoin token, `T`. - /// Only one `MintCap` can be stored for any token. - entry fun add_stablecoin_mint_cap(mint_cap: MintCap, state: &mut State, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_token_controller(state, ctx); - let local_token_id = token_utils::calculate_token_id(); - assert!(!state.mint_cap_for_local_token_exists(local_token_id), EMintCapAlreadyAdded); - - let mint_cap_id = object::id(&mint_cap); - state.add_mint_cap(local_token_id, mint_cap); - emit(MintCapAdded {local_token: local_token_id, mint_cap_id }); - } - - /// Removes a `MintCap` for the given stablecoin token, `T`. - /// `MintCap` must exist before removing. - /// Transfers the removed `MintCap` to the caller. - /// Requires the `MintCap` be deauthorized (`treasury::remove_minter`) before removing. - #[allow(lint(self_transfer))] - entry fun remove_stablecoin_mint_cap(state: &mut State, treasury: &Treasury, ctx: &TxContext) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - verify_token_controller(state, ctx); - - // Ensure MintCap exists and is de-authorized before removing. - let local_token_id = token_utils::calculate_token_id(); - assert!(state.mint_cap_for_local_token_exists(local_token_id), EMintCapDoesNotExist); - let mint_cap_ref = state.mint_cap_from_token_id>(local_token_id); - assert!(!is_authorized_mint_cap(treasury, object::id(mint_cap_ref)), EMintCapNotDeAuthorized); - - let mint_cap = state.remove_mint_cap>(local_token_id); - emit(MintCapRemoved {local_token: local_token_id, mint_cap_id: object::id(&mint_cap) }); - - transfer::public_transfer(mint_cap, ctx.sender()); - } - - // === Private Functions === - fun verify_token_controller(state: &State, ctx: &TxContext) { - assert!(ctx.sender() == state.roles().token_controller(), ENotTokenController); - } - - #[test_only] - public fun create_set_burn_limit_per_message_event(token: address, burn_limit_per_message: u64): SetBurnLimitPerMessage { - SetBurnLimitPerMessage {token, burn_limit_per_message} - } - - #[test_only] - public fun create_token_pair_linked_event(local_token: address, remote_domain: u32, remote_token: address): TokenPairLinked { - TokenPairLinked {local_token, remote_domain, remote_token} - } - - #[test_only] - public fun create_token_pair_unlinked_event(local_token: address, remote_domain: u32, remote_token: address): TokenPairUnlinked { - TokenPairUnlinked {local_token, remote_domain, remote_token} - } - - #[test_only] - public fun create_mint_cap_added_event(local_token: address, mint_cap_id: ID): MintCapAdded { - MintCapAdded {local_token, mint_cap_id} - } - - #[test_only] - public fun create_mint_cap_removed_event(local_token: address, mint_cap_id: ID): MintCapRemoved { - MintCapRemoved {local_token, mint_cap_id} - } -} - -#[test_only] -module token_messenger_minter::token_controller_tests { - use sui::{ - coin, - deny_list, - event::{num_events}, - test_scenario::{Self, Scenario}, - test_utils::{Self, assert_eq} - }; - use sui_extensions::test_utils::{last_event_by_type}; - use token_messenger_minter::{ - state::{Self}, - token_utils::{Self}, - token_controller::{ - Self, - MintCapAdded, - MintCapRemoved, - SetBurnLimitPerMessage, - TokenPairUnlinked, - TokenPairLinked, - create_mint_cap_added_event, - create_mint_cap_removed_event, - create_set_burn_limit_per_message_event, - create_token_pair_linked_event, - create_token_pair_unlinked_event, - }, - version_control - }; - use stablecoin::treasury::{Self, MintCap, Treasury}; - - public struct TOKEN_CONTROLLER_TESTS has drop {} - - const TOKEN_CONTROLLER: address = @0x1; - - // set_max_burn_amount_per_message tests - - #[test] - public fun test_set_max_burn_amount_per_message_successful() { - let mut scenario = test_scenario::begin(@0x0); - let burn_limit_per_message = 100; - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Successful setting of max burn amount per message - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::set_max_burn_amount_per_message(burn_limit_per_message, &mut state, scenario.ctx()); - assert_eq(state.burn_limit_from_token_id(local_token_id), burn_limit_per_message); - assert!(num_events() == 1); - assert!(last_event_by_type() == create_set_burn_limit_per_message_event(local_token_id, burn_limit_per_message)); - }; - - state.remove_burn_limit(local_token_id); - test_utils::destroy(state); - scenario.end(); - } - - #[test] - public fun test_set_max_burn_amount_per_message_with_existing_limit_successful() { - let mut scenario = test_scenario::begin(@0x0); - let burn_limit_per_message = 100; - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance and set the initial limit - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - scenario.next_tx(TOKEN_CONTROLLER); - token_controller::set_max_burn_amount_per_message(burn_limit_per_message + 100, &mut state, scenario.ctx()); - assert_eq(state.burn_limit_from_token_id(local_token_id), burn_limit_per_message + 100); - - // Test: Successful setting of max burn amount per message with existing limit - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::set_max_burn_amount_per_message(burn_limit_per_message, &mut state, scenario.ctx()); - assert_eq(state.burn_limit_from_token_id(local_token_id), burn_limit_per_message); - assert!(num_events() == 1); - assert!(last_event_by_type() == create_set_burn_limit_per_message_event(local_token_id, burn_limit_per_message)); - }; - - state.remove_burn_limit(local_token_id); - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::ENotTokenController)] - public fun test_set_max_burn_amount_per_message_revert_not_token_controller() { - let mut scenario = test_scenario::begin(@0x0); - let not_token_controller = @0x2; - let burn_limit_per_message = 100; - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Revert if the caller is not the token controller - scenario.next_tx(not_token_controller); - token_controller::set_max_burn_amount_per_message(burn_limit_per_message, &mut state, scenario.ctx()); - - state.remove_burn_limit(local_token_id); - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_set_max_burn_amount_per_message_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let burn_limit_per_message = 100; - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - scenario.next_tx(TOKEN_CONTROLLER); - token_controller::set_max_burn_amount_per_message(burn_limit_per_message, &mut state, scenario.ctx()); - - state.remove_burn_limit(local_token_id); - test_utils::destroy(state); - scenario.end(); - } - - // link_token_pair tests - - #[test] - public fun test_link_token_pair_successful() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x2; - let remote_domain = 1; - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Successful linking of token pair - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::link_token_pair(remote_domain, remote_token, &mut state, scenario.ctx()); - assert_eq(state.local_token_from_remote_token(remote_domain, remote_token), local_token_id); - assert!(num_events() == 1); - assert!(last_event_by_type() == create_token_pair_linked_event(local_token_id, remote_domain, remote_token)); - }; - - // Destroy objects - state.remove_local_token_for_remote_token(remote_domain, remote_token); - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::ENotTokenController)] - public fun test_link_token_pair_revert_not_token_controller() { - let mut scenario = test_scenario::begin(@0x0); - let (non_token_controller, remote_token) = (@0x2, @0x3); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Revert if the caller is not the token controller - scenario.next_tx(non_token_controller); - { - token_controller::link_token_pair(remote_domain, remote_token, &mut state, scenario.ctx()); - assert!(!state.local_token_from_remote_token_exists(remote_domain, remote_token), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::EEmptyAddress)] - public fun test_link_token_pair_revert_empty_address() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x0; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Revert if the remote token address is empty - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::link_token_pair(remote_domain, remote_token, &mut state, scenario.ctx()); - assert!(!state.local_token_from_remote_token_exists(remote_domain, remote_token), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::ETokenPairAlreadyLinked)] - public fun test_link_token_pair_revert_already_linked() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x2; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Link the token pair for the first time - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::link_token_pair(remote_domain, remote_token, &mut state, scenario.ctx()); - let local_token_id = token_utils::calculate_token_id(); - assert!(state.local_token_from_remote_token(remote_domain, remote_token) == local_token_id, 0); - - // Attempt to link the same token pair again - scenario.next_tx(TOKEN_CONTROLLER); - token_controller::link_token_pair(remote_domain, remote_token, &mut state, scenario.ctx()); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_link_token_pair_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x2; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - { - token_controller::link_token_pair(remote_domain, remote_token, &mut state, scenario.ctx()); - assert!(!state.local_token_from_remote_token_exists(remote_domain, remote_token), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - scenario.end(); - } - - // unlink_token_pair tests - - #[test] - public fun test_unlink_token_pair_successful() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x2; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Link a token pair first - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::link_token_pair(remote_domain, remote_token, &mut state, scenario.ctx()); - let local_token_id = token_utils::calculate_token_id(); - assert!(state.local_token_from_remote_token(remote_domain, remote_token) == local_token_id, 0); - }; - - // Test: Successful unlinking of token pair - { - token_controller::unlink_token_pair( - remote_domain, remote_token, &mut state, scenario.ctx() - ); - // Validate the local token was removed - assert!(!state.local_token_from_remote_token_exists(remote_domain, remote_token), 1); - let local_token_id = token_utils::calculate_token_id(); - assert!(num_events() == 2); - assert!(last_event_by_type() == create_token_pair_unlinked_event(local_token_id, remote_domain, remote_token)); - }; - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::ENotTokenController)] - public fun test_unlink_token_pair_revert_not_token_controller() { - let mut scenario = test_scenario::begin(@0x0); - let (non_token_controller, remote_token) = (@0x2, @0x3); - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Revert if the caller is not the token controller - scenario.next_tx(non_token_controller); - token_controller::unlink_token_pair( - remote_domain, remote_token, &mut state, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::EEmptyAddress)] - public fun test_unlink_token_pair_revert_empty_address() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x0; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Revert if the remote token address is empty - scenario.next_tx(TOKEN_CONTROLLER); - token_controller::unlink_token_pair( - remote_domain, remote_token, &mut state, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::ETokenPairNotLinked)] - public fun test_unlink_token_pair_revert_already_linked() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x2; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Attempt to unlink without linking - scenario.next_tx(TOKEN_CONTROLLER); - token_controller::unlink_token_pair( - remote_domain, remote_token, &mut state, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_unlink_token_pair_revert_incompatible_version() { - let mut scenario = test_scenario::begin(@0x0); - let remote_token = @0x2; - let remote_domain = 1; - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - token_controller::unlink_token_pair( - remote_domain, remote_token, &mut state, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - scenario.end(); - } - - // add_stablecoin_mint_cap tests - - #[test] - public fun test_add_stablecoin_mint_cap_successful() { - let mut scenario = test_scenario::begin(TOKEN_CONTROLLER); - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance and get mint cap - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - let (mut scenario, treasury, mint_cap) = setup_mint_cap(scenario); - - // Test: Successful linking of token pair - scenario.next_tx(TOKEN_CONTROLLER); - { - let mint_cap_id_address = object::id_address(&mint_cap); - let mint_cap_id = object::id(&mint_cap); - token_controller::add_stablecoin_mint_cap( - mint_cap, &mut state, scenario.ctx() - ); - assert_eq( - object::id_address(state.mint_cap_from_token_id>(local_token_id)), - mint_cap_id_address - ); - assert!(num_events() == 1); - assert!(last_event_by_type() == create_mint_cap_added_event(local_token_id, mint_cap_id)); - }; - - // Destroy objects - test_utils::destroy(state.remove_mint_cap>(local_token_id)); - test_utils::destroy(state); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::ENotTokenController)] - public fun test_add_stablecoin_mint_cap_revert_not_token_controller() { - let mut scenario = test_scenario::begin(TOKEN_CONTROLLER); - let non_token_controller = @0x2; - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance and get mint cap - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - let (mut scenario, treasury, mint_cap) = setup_mint_cap(scenario); - - // Test: Revert if the caller is not the token controller - scenario.next_tx(non_token_controller); - { - token_controller::add_stablecoin_mint_cap( - mint_cap, &mut state, scenario.ctx() - ); - assert!(!state.mint_cap_for_local_token_exists(local_token_id), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::EMintCapAlreadyAdded)] - public fun test_add_stablecoin_mint_cap_revert_already_added() { - let mut scenario = test_scenario::begin(TOKEN_CONTROLLER); - - // Create a new State instance and get mint cap - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - let (scenario, treasury, mint_cap) = setup_mint_cap(scenario); - let (mut scenario, treasury2, mint_cap2) = setup_mint_cap(scenario); - - // Add the mint cap for the first time - scenario.next_tx(TOKEN_CONTROLLER); - { - let mint_cap_id = object::id_address(&mint_cap); - token_controller::add_stablecoin_mint_cap( - mint_cap, &mut state, scenario.ctx() - ); - let local_token_id = token_utils::calculate_token_id(); - assert_eq(object::id_address(state.mint_cap_from_token_id>(local_token_id)), mint_cap_id); - - // Attempt to add the same mint cap again - scenario.next_tx(TOKEN_CONTROLLER); - token_controller::add_stablecoin_mint_cap( - mint_cap2, &mut state, scenario.ctx() - ); - assert_eq(object::id_address(state.mint_cap_from_token_id>(local_token_id)), mint_cap_id); - }; - - // Destroy state and scenario - test_utils::destroy(state); - test_utils::destroy(treasury); - test_utils::destroy(treasury2); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_add_stablecoin_mint_cap_revert_incompatible_version() { - let mut scenario = test_scenario::begin(TOKEN_CONTROLLER); - let local_token_id = token_utils::calculate_token_id(); - - // Create a new State instance and get mint cap - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - let (mut scenario, treasury, mint_cap) = setup_mint_cap(scenario); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - { - token_controller::add_stablecoin_mint_cap( - mint_cap, &mut state, scenario.ctx() - ); - assert!(!state.mint_cap_for_local_token_exists(local_token_id), 0); - }; - - // Destroy state and scenario - test_utils::destroy(state); - test_utils::destroy(treasury); - scenario.end(); - } - - // remove_stablecoin_mint_cap tests - - #[test] - public fun test_remove_stablecoin_mint_cap_successful() { - let mut scenario = test_scenario::begin(TOKEN_CONTROLLER); - - // Create a new State instance and get mint cap - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - let (mut scenario, mut treasury, mint_cap) = setup_mint_cap(scenario); - let mint_cap_id_address = object::id_address(&mint_cap); - let mint_cap_id = object::id(&mint_cap); - - // de-authorize the minter so it can be removed later - scenario.next_tx(@0x1); - { treasury.remove_minter(scenario.ctx()) }; - - // Add a mint cap first and deauthorize it - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::add_stablecoin_mint_cap( - mint_cap, &mut state, scenario.ctx() - ); - let local_token_id = token_utils::calculate_token_id(); - assert_eq(object::id_address(state.mint_cap_from_token_id>(local_token_id)), mint_cap_id_address); - }; - - // Test: Successfully remove mint cap - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::remove_stablecoin_mint_cap( - &mut state, &treasury, scenario.ctx() - ); - assert!(num_events() == 1); - let local_token_id = token_utils::calculate_token_id(); - assert!(last_event_by_type() == create_mint_cap_removed_event(local_token_id, mint_cap_id)); - }; - - scenario.end(); - // Validate the transferred mint_cap mint cap is the same one we linked above. - assert_eq(test_scenario::most_recent_id_for_address>(TOKEN_CONTROLLER).extract(), mint_cap_id_address.to_id()); - - // Destroy objects - test_utils::destroy(state); - test_utils::destroy(treasury); - } - - #[test] - #[expected_failure(abort_code = token_controller::EMintCapNotDeAuthorized)] - public fun test_remove_stablecoin_mint_cap_revert_not_de_authorized() { - let mut scenario = test_scenario::begin(TOKEN_CONTROLLER); - - // Create a new State instance and get mint cap - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - let (mut scenario, treasury, mint_cap) = setup_mint_cap(scenario); - let mint_cap_id_address = object::id_address(&mint_cap); - - // Add a mint cap first - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::add_stablecoin_mint_cap( - mint_cap, &mut state, scenario.ctx() - ); - let local_token_id = token_utils::calculate_token_id(); - assert_eq(object::id_address(state.mint_cap_from_token_id>(local_token_id)), mint_cap_id_address); - }; - - // Revert: MintCap not de-authorized - scenario.next_tx(TOKEN_CONTROLLER); - { - token_controller::remove_stablecoin_mint_cap( - &mut state, &treasury, scenario.ctx() - ); - // assert!(num_events() == 1); - }; - - // Destroy objects - test_utils::destroy(state); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::ENotTokenController)] - public fun test_remove_stablecoin_mint_cap_revert_not_token_controller() { - let scenario = test_scenario::begin(TOKEN_CONTROLLER); - let non_token_controller = @0x2; - let local_token_id = token_utils::calculate_token_id(); - let (mut scenario, treasury, mint_cap) = setup_mint_cap(scenario); - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Test: Revert if the caller is not the token controller - scenario.next_tx(non_token_controller); - { - token_controller::remove_stablecoin_mint_cap( - &mut state, &treasury, scenario.ctx() - ); - assert!(!state.mint_cap_for_local_token_exists(local_token_id), 0); - }; - - - // Destroy objects - test_utils::destroy(state); - test_utils::destroy(mint_cap); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = token_controller::EMintCapDoesNotExist)] - public fun test_remove_stablecoin_mint_cap_revert_already_linked() { - let scenario = test_scenario::begin(TOKEN_CONTROLLER); - let (mut scenario, treasury, mint_cap) = setup_mint_cap(scenario); - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - - // Attempt to remove cap without adding - scenario.next_tx(TOKEN_CONTROLLER); - token_controller::remove_stablecoin_mint_cap( - &mut state, &treasury, scenario.ctx() - ); - - // Destroy objects - test_utils::destroy(state); - test_utils::destroy(mint_cap); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_remove_stablecoin_mint_cap_revert_incompatible_version() { - let scenario = test_scenario::begin(TOKEN_CONTROLLER); - let local_token_id = token_utils::calculate_token_id(); - let (mut scenario, treasury, mint_cap) = setup_mint_cap(scenario); - - // Create a new State instance - let mut state = state::new(1, TOKEN_CONTROLLER, scenario.ctx()); - state.add_compatible_version(5); - state.remove_compatible_version(version_control::current_version()); - - // Test: Revert for incompatible version - { - token_controller::remove_stablecoin_mint_cap( - &mut state, &treasury, scenario.ctx() - ); - assert!(!state.mint_cap_for_local_token_exists(local_token_id), 0); - }; - - // Destroy objects - test_utils::destroy(state); - test_utils::destroy(treasury); - test_utils::destroy(mint_cap); - scenario.end(); - } - - /// === Test Helpers === - fun setup_mint_cap(mut scenario: Scenario): (Scenario, Treasury, MintCap) { - let otw = test_utils::create_one_time_witness(); - let (treasury_cap, deny_cap, metadata) = coin::create_regulated_currency_v2( - otw, - 6, - b"SYMBOL", - b"NAME", - b"", - option::none(), - true, - scenario.ctx() - ); - - let mut treasury = treasury::new( - treasury_cap, - deny_cap, - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx() - ); - treasury.configure_new_controller(@0x1, @0x1, scenario.ctx()); - let deny_list = deny_list::new_for_testing(scenario.ctx()); - treasury.configure_minter(&deny_list, 1, scenario.ctx()); - scenario.next_tx(@0x1); - let mint_cap = scenario.take_from_address>(@0x1); - test_utils::destroy(metadata); - test_utils::destroy(deny_list); - - (scenario, treasury, mint_cap) - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/version_control.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/version_control.move deleted file mode 100644 index 0c4937d0a..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/admin/version_control.move +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// module: version_control -/// Contains version control functions. -/// Copied from stablecoin package: -/// https://github.com/circlefin/stablecoin-sui/blob/63fca4360821600ca8686b86f8e26d98e95927c7/packages/stablecoin/sources/version_control.move. -module token_messenger_minter::version_control { - use sui::vec_set::VecSet; - - /// The current version of the package. - const VERSION: u64 = 1; - - // === Errors === - const EIncompatibleVersion: u64 = 0; - - // === Methods === - /// Public accessor for the current package's version. - public fun current_version(): u64 { - VERSION - } - - /// [Package Private] Helper function to check that the object is - /// compatible with the current package's version. - public(package) fun assert_object_version_is_compatible_with_package(compatible_versions: &VecSet) { - assert!(compatible_versions.contains(¤t_version()), EIncompatibleVersion); - } -} - -#[test_only] -module token_messenger_minter::version_control_tests { - use sui::vec_set::{Self, VecSet}; - use token_messenger_minter::version_control; - - #[test, expected_failure(abort_code = version_control::EIncompatibleVersion)] - fun assert_object_version_is_compatible_with_package__should_abort_if_not_compatible() { - let compatible_versions: VecSet = vec_set::empty(); - version_control::assert_object_version_is_compatible_with_package( - &compatible_versions - ) - } - - #[test] - fun assert_object_version_is_compatible_with_package__should_succeed_if_compatible_version_is_contained() { - let compatible_versions: VecSet = vec_set::singleton(version_control::current_version()); - version_control::assert_object_version_is_compatible_with_package( - &compatible_versions - ) - } - - #[test] - fun assert_object_version_is_compatible_with_package__should_succeed_if_one_of_multiple_compatible_versions() { - let mut compatible_versions: VecSet = vec_set::empty(); - compatible_versions.insert(version_control::current_version()); - compatible_versions.insert(version_control::current_version() + 1); - - version_control::assert_object_version_is_compatible_with_package( - &compatible_versions - ) - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/burn_message.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/burn_message.move deleted file mode 100644 index 0b9c50557..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/burn_message.move +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: burn_message -/// This module contains the BurnMessage struct for CCTP TokenMessenger messages. -/// Format defined here: -/// https://developers.circle.com/stablecoins/docs/message-format#message-body. -/// Message is structured in the following format: -/// -------------------------------------------------- -/// Field Bytes Type Index -/// version 4 uint32 0 -/// burnToken 32 bytes32 4 -/// mintRecipient 32 bytes32 36 -/// amount 32 uint256 68 -/// messageSender 32 bytes32 100 -/// -------------------------------------------------- -module token_messenger_minter::burn_message { - // === Imports === - use message_transmitter::{ - deserialize::{deserialize_u32_be, deserialize_u256_be, deserialize_address}, - serialize::{serialize_u32_be, serialize_u256_be, serialize_address}, - }; - - // === Errors === - const EInvalidMessageLength: u64 = 0; - - // === Constants === - const VERSION_INDEX: u64 = 0; - const BURN_TOKEN_INDEX: u64 = 4; - const MINT_RECIPIENT_INDEX: u64 = 36; - const AMOUNT_INDEX: u64 = 68; - const MESSAGE_SENDER_INDEX: u64 = 100; - - const VERSION_LEN: u64 = 4; - const BURN_TOKEN_LEN: u64 = 32; - const MINT_RECIPIENT_LEN: u64 = 32; - const AMOUNT_LEN: u64 = 32; - const MESSAGE_SENDER_LEN: u64 = 32; - - // 132 bytes - const BURN_MESSAGE_LEN: u64 = VERSION_LEN + BURN_TOKEN_LEN + MINT_RECIPIENT_LEN + AMOUNT_LEN + MESSAGE_SENDER_LEN; - - // === Structs === - public struct BurnMessage has drop, copy { - version: u32, - burn_token: address, - mint_recipient: address, - amount: u256, - message_sender: address - } - - // === Public-View Functions === - - public fun version(message: &BurnMessage): u32 { - message.version - } - - public fun burn_token(message: &BurnMessage): address { - message.burn_token - } - - public fun mint_recipient(message: &BurnMessage): address { - message.mint_recipient - } - - public fun amount(message: &BurnMessage): u256 { - message.amount - } - - public fun message_sender(message: &BurnMessage): address { - message.message_sender - } - - // === Public Functions === - - /// Serializes a given `BurnMessage` into the CCTP message format in bytes. - public fun serialize(message: &BurnMessage): vector { - let BurnMessage { - version, - burn_token, - mint_recipient, - amount, - message_sender - } = message; - - let mut result = vector::empty(); - vector::append(&mut result, serialize_u32_be(*version)); - vector::append(&mut result, serialize_address(*burn_token)); - vector::append(&mut result, serialize_address(*mint_recipient)); - vector::append(&mut result, serialize_u256_be(*amount)); - vector::append(&mut result, serialize_address(*message_sender)); - - result - } - - // === Public-Package Functions === - - /// Creates a new `BurnMessage` object from given parameters. - /// Has public(package) visibility so integrators can trust it when returned. - public(package) fun new(version: u32, burn_token: address, mint_recipient: address, amount: u256, message_sender: address): BurnMessage { - BurnMessage { - version, burn_token, mint_recipient, amount, message_sender - } - } - - /// Creates a new `BurnMessage` object from bytes. - /// Validates the message first. - /// Has public(package) visibility so integrators can trust it when returned. - public(package) fun from_bytes(message_bytes: &vector): BurnMessage { - validate_raw_message(message_bytes); - - BurnMessage { - version: deserialize_u32_be(message_bytes, VERSION_INDEX, VERSION_LEN), - burn_token: deserialize_address(message_bytes, BURN_TOKEN_INDEX, BURN_TOKEN_LEN), - mint_recipient: deserialize_address(message_bytes, MINT_RECIPIENT_INDEX, MINT_RECIPIENT_LEN), - amount: deserialize_u256_be(message_bytes, AMOUNT_INDEX, AMOUNT_LEN), - message_sender: deserialize_address(message_bytes, MESSAGE_SENDER_INDEX, MESSAGE_SENDER_LEN), - } - } - - public(package) fun update_mint_recipient( - burn_message: &mut BurnMessage, new_mint_recipient: address - ) { - burn_message.mint_recipient = new_mint_recipient; - } - - public(package) fun update_version( - burn_message: &mut BurnMessage, new_version: u32 - ) { - burn_message.version = new_version; - } - - // === Private Functions === - - fun validate_raw_message(message: &vector) { - assert!(message.length() == BURN_MESSAGE_LEN, EInvalidMessageLength); - } - - // === Test Functions === - - #[test_only] - public fun new_for_testing(version: u32, burn_token: address, mint_recipient: address, amount: u256, message_sender: address): BurnMessage { - new(version, burn_token, mint_recipient, amount, message_sender) - } - - #[test_only] - public(package) fun from_bytes_for_testing(message_bytes: &vector): BurnMessage { - from_bytes(message_bytes) - } - - // Following test message is based on -> - // ETH (Source): https://sepolia.etherscan.io/tx/0x151c196be83e2fcbd84204a521ee0a758a5e7335ac7d2c0958ef840fd485dc61 - // AVAX (Destination): https://testnet.snowtrace.io/tx/0xa98d5c33b7571609875f56ae148563411377392c87b9e8cebd483683a0e36413 - // Burn Token: 0x0000000000000000000000001c7D4B196Cb0C7B01d743Fbc6116a902379C7238 - // Mint Recipient: 0x0000000000000000000000001F26414439C8D03FC4B9CA912CEFD5CB508C9605 - // Amount: 1214 - // Sender: 0x0000000000000000000000003b61AbEe91852714E4e99b09a1AF3e9C13893eF1 - - #[test_only] - public fun get_raw_test_message(): vector { - x"000000000000000000000000000000001c7d4b196cb0c7b01d743fbc6116a902379c72380000000000000000000000001f26414439c8d03fc4b9ca912cefd5cb508c960500000000000000000000000000000000000000000000000000000000000004be0000000000000000000000003b61abee91852714e4e99b09a1af3e9c13893ef1" - } - - // === Tests === - #[test_only] - use sui::test_utils::{assert_eq}; - - #[test_only] const VERSION: u32 = 0; - #[test_only] const BURN_TOKEN: address = @0x0000000000000000000000001c7D4B196Cb0C7B01d743Fbc6116a902379C7238; - #[test_only] const MINT_RECIPIENT: address = @0x0000000000000000000000001F26414439C8D03FC4B9CA912CEFD5CB508C9605; - #[test_only] const AMOUNT: u256 = 1214; - #[test_only] const MESSAGE_SENDER: address = @0x0000000000000000000000003b61AbEe91852714E4e99b09a1AF3e9C13893eF1; - - // from_bytes tests - - #[test] - public fun test_from_bytes_successful() { - let message = from_bytes(&get_raw_test_message()); - - assert_eq(message.version(), VERSION); - assert_eq(message.burn_token(), BURN_TOKEN); - assert_eq(message.mint_recipient(), MINT_RECIPIENT); - assert_eq(message.amount(), AMOUNT); - assert_eq(message.message_sender(), MESSAGE_SENDER); - } - - #[test] - #[expected_failure(abort_code = EInvalidMessageLength)] - public fun test_from_bytes_invalid() { - let message = vector[1,2,3,4,5]; - from_bytes(&message); - } - - #[test] - fun test_validate_raw_message() { - let orignal_message = get_raw_test_message(); - validate_raw_message(&orignal_message) - } - - // serialize tests - - #[test] - public fun test_serialize_successful() { - let raw_message = get_raw_test_message(); - let message = from_bytes(&raw_message); - let serialized = message.serialize(); - - assert_eq(raw_message, serialized); - } - - // new tests - - #[test] - public fun new_message_successful() { - let message = new(VERSION, BURN_TOKEN, MINT_RECIPIENT, AMOUNT, MESSAGE_SENDER); - - assert_eq(message.version(), VERSION); - assert_eq(message.burn_token(), BURN_TOKEN); - assert_eq(message.mint_recipient(), MINT_RECIPIENT); - assert_eq(message.amount(), AMOUNT); - assert_eq(message.message_sender(), MESSAGE_SENDER); - } - - #[test] - public fun new_message_serialize_successful() { - let message = new(VERSION, BURN_TOKEN, MINT_RECIPIENT, AMOUNT, MESSAGE_SENDER); - let raw_message = get_raw_test_message(); - - assert_eq(message.serialize(), raw_message); - } - - // update_mint_recipient tests - - #[test] - public fun update_mint_recipient_successful() { - let mut message = new(VERSION, BURN_TOKEN, MINT_RECIPIENT, AMOUNT, MESSAGE_SENDER); - assert_eq(message.mint_recipient(), MINT_RECIPIENT); - - message.update_mint_recipient(MESSAGE_SENDER); - assert_eq(message.mint_recipient(), MESSAGE_SENDER); - } - - // update_version tests - - #[test] - public fun update_version_successful() { - let mut message = new(VERSION, BURN_TOKEN, MINT_RECIPIENT, AMOUNT, MESSAGE_SENDER); - assert_eq(message.version(), VERSION); - - message.update_version(VERSION+1); - assert_eq(message.version(), VERSION+1); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/deposit_for_burn.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/deposit_for_burn.move deleted file mode 100644 index 3f5267a10..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/deposit_for_burn.move +++ /dev/null @@ -1,1554 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: deposit_for_burn -/// Contains public methods for sending cross-chain USDC transfers. -/// -/// Note on upgrades: If interacting with this module from other packages, it -/// is recommended to call the _with_package_auth methods from PTBs rather than -/// directly from dependent packages. These functions are version gated, so if -/// the package is upgraded, the upgraded package must be called. -module token_messenger_minter::deposit_for_burn { - - // === Imports === - use sui::{ - coin::{Coin}, - deny_list::{DenyList}, - event::emit - }; - use stablecoin::{treasury::{Self, MintCap, Treasury}}; - use message_transmitter::{ - auth::auth_caller_identifier, - message::{Self, Message}, - send_message::{ - create_send_message_ticket, - create_send_message_with_caller_ticket, - create_replace_message_ticket, - replace_message, - send_message, - send_message_with_caller - }, - state::{State as MessageTransmitterState} - }; - use token_messenger_minter::{ - burn_message::{Self, BurnMessage}, - message_transmitter_authenticator, - state::{State}, - token_utils::{calculate_token_id}, - version_control::{assert_object_version_is_compatible_with_package} - }; - - // === Errors === - const EZeroAmount: u64 = 0; - const EZeroAddressMintRecipient: u64 = 1; - const EInvalidDestinationDomain: u64 = 2; - const EPaused: u64 = 3; - const EMissingMintCap: u64 = 4; - const EMissingBurnLimit: u64 = 5; - const EBurnLimitExceeded: u64 = 6; - const ESenderDoesNotMatchOriginalSender: u64 = 7; - - // === Events === - public struct DepositForBurn has copy, drop { - nonce: u64, - burn_token: address, - amount: u64, - depositor: address, - mint_recipient: address, - destination_domain: u32, - destination_token_messenger: address, - destination_caller: address, - } - - // === Public-Mutative Functions === - - /// Burns tokens to be minted on destination domain and sends a - /// message through the MessageTransmitter package. - /// Intended to be called directly by EOA (rather than a dependent package). - /// The initiating EOA will be the "owner" (e.g. message sender) of the message and - /// have the ability to call replace_deposit_for_burn. - /// - /// Reverts if: - /// - given burn token T is not supported - /// - given destinationDomain has no TokenMessenger registered - /// - burn limit per message is exceeded - /// - burn() reverts. For example, if `amount` is 0. - /// - invalid (e.g. 0x0) mint_recipient is given - /// - message_transmitter::send_message reverts - /// - contract is paused - /// - /// Parameters: - /// - coins: Coin of type T to be burned. Full amount in coins will be burned. - /// - destination_domain: domain to mint tokens on - /// - mint_recipient: address of mint recipient on destination domain - /// Note: If destination is a non-Move chain, mint_recipient - /// address should be converted to hex and passed in in the - /// @0x123 address format. - /// - state: State shared object for the TokenMessengerMinter package. - /// - deny_list: DenyList shared object for the stablecoin token T. - /// - treasury: Treasury shared object for the stablecoin token T. - /// - ctx: TxContext for the tx - entry fun deposit_for_burn( - coins: Coin, - destination_domain: u32, - mint_recipient: address, - state: &State, - message_transmitter_state: &mut MessageTransmitterState, - deny_list: &DenyList, - treasury: &mut Treasury, - ctx: &TxContext - ): (BurnMessage, Message) { - let message_sender = ctx.sender(); - deposit_for_burn_shared( - coins, destination_domain, mint_recipient, @0x0, message_sender, - state, message_transmitter_state, deny_list, treasury, ctx - ) - } - - /// Burns tokens to be minted on destination domain and sends a - /// message through the MessageTransmitter package. - /// Intended to be called with Auth struct from a dependent package. The calling package - /// will be the "owner" (e.g. message_sender) of the message and have the ability to call replace_deposit_for_burn_with_package_auth. - /// Direct callers (where EOAs should be the owner) should use deposit_for_burn instead. - /// - /// This function uses a DepositForBurnTicket for parameters so that the calling package can - /// call create_deposit_for_burn_ticket (not version-gated) from their package with parameters, and call - /// deposit_for_burn_with_package_auth (version-gated) from a PTB so packages don't have to be updated - /// during CCTP package upgrades. DepositForBurnTicket also requires an Auth parameter. This is required to - /// securely assign a sender address associated with the calling contract to the message. - /// Any struct that implements the drop trait can be used as an authenticator, but it is recommended to - /// use a dedicated auth struct. Calling contracts should be careful to not expose these objects to the - /// public or else messages from their package could be replaced. - /// - /// Parameters: - /// - deposit_for_burn_ticket: Struct containing parameters and authenticator struct. - /// - deny_list: DenyList shared object for the stablecoin token T. - /// - treasury: Treasury shared object for the stablecoin token T. - /// - ctx: TxContext for the tx - public fun deposit_for_burn_with_package_auth( - deposit_for_burn_ticket: DepositForBurnTicket, - state: &State, - message_transmitter_state: &mut MessageTransmitterState, - deny_list: &DenyList, - treasury: &mut Treasury, - ctx: &TxContext - ): (BurnMessage, Message) { - let DepositForBurnTicket { - auth: _auth, - coins, - destination_domain, - mint_recipient - } = deposit_for_burn_ticket; - - // Since this is called from another package, message_sender is the auth caller identifier from the given auth struct. - let message_sender = auth_caller_identifier(); - deposit_for_burn_shared( - coins, destination_domain, mint_recipient, @0x0, message_sender, - state, message_transmitter_state, deny_list, treasury, ctx - ) - } - - /// Same as deposit_for_burn, except the receive_message call on the destination - /// domain must be called by `destination_caller`. - /// Intended to be called directly by EOA (rather than a dependent package). - /// - /// WARNING: if the `destination_caller` does not represent a valid address, then - /// it will not be possible to broadcast the message on the destination domain. - /// This is an advanced feature, and the standard deposit_for_burn() should be - /// preferred for use cases where a specific destination caller is not required. - /// - /// Note: If destination is a non-Move chain, destination_caller address should - /// be converted to hex and passed in in the @0x123 address format. - entry fun deposit_for_burn_with_caller( - coins: Coin, - destination_domain: u32, - mint_recipient: address, - destination_caller: address, - state: &State, - message_transmitter_state: &mut MessageTransmitterState, - deny_list: &DenyList, - treasury: &mut Treasury, - ctx: &TxContext - ): (BurnMessage, Message) { - deposit_for_burn_shared( - coins, destination_domain, mint_recipient, destination_caller, ctx.sender(), - state, message_transmitter_state, deny_list, treasury, ctx - ) - } - - /// Same as deposit_for_burn_with_package_auth, except the receive_message call on the destination - /// domain must be called by `destination_caller`. - /// Intended to be called from a dependent package. The calling package - /// will be the "owner" of the message and be able to call replace_deposit_for_burn. - /// Direct EOA (non-package) callers should use deposit_for_burn_with_caller instead. - /// - /// This function uses a DepositForBurnWithCallerTicket for parameters so that the calling package can - /// call create_deposit_for_burn_with_caller_ticket (not version-gated) from their package, and call - /// deposit_for_burn_with_caller_with_package_auth (version-gated) from a PTB so packages don't have to be updated - /// during upgrades. - /// - /// WARNING: if the `destination_caller` does not represent a valid address, then - /// it will not be possible to broadcast the message on the destination domain. - /// This is an advanced feature, and the standard deposit_for_burn() should be - /// preferred for use cases where a specific destination caller is not required. - /// - /// Note: If destination is a non-Move chain, destination_caller address should - /// be converted to hex and passed in in the @0x123 address format. - public fun deposit_for_burn_with_caller_with_package_auth( - deposit_for_burn_with_caller_ticket: DepositForBurnWithCallerTicket, - state: &State, - message_transmitter_state: &mut MessageTransmitterState, - deny_list: &DenyList, - treasury: &mut Treasury, - ctx: &TxContext - ): (BurnMessage, Message) { - let DepositForBurnWithCallerTicket { - auth: _auth, - coins, - destination_domain, - mint_recipient , - destination_caller - } = deposit_for_burn_with_caller_ticket; - - let sender_identifier = auth_caller_identifier(); - deposit_for_burn_shared( - coins, destination_domain, mint_recipient, destination_caller, sender_identifier, - state, message_transmitter_state, deny_list, treasury, ctx - ) - } - - /// Allows the sender of a previous BurnMessage (created by depositForBurn or - /// depositForBurnWithCaller) to send a new BurnMessage to replace the original as - /// long as they have a valid attestation for the message. - /// The new BurnMessage will re-use the amount and burn token of the original, - /// without requiring a new Coin deposit. The new message will reuse the original - /// message's nonce. For a given nonce, all replacement message(s) and the - /// original message are valid to broadcast on the destination domain, until - /// the first message at the nonce confirms, at which point all others are invalidated. - /// - /// Intended to be called by an EOA where an EOA was the message_sender of the message. - /// Messages owned by Auth identifiers should use replace_deposit_for_burn_with_package_auth. - /// - /// Reverts if: - /// - original message or attestation are invalid - /// - tx sender is not the original message sender - /// - new mint recipient is null address (0x0) - /// - message_transmitter::replace_message fails - /// - /// Parameters: - /// - original_raw_message: original message in bytes. - /// - original_attestation: valid attestation for the original message in bytes. - /// - new_destination_caller: new destination caller for message, can be @0x0 for no caller, - /// defaults to destination_caller of original_message. - /// - new_mint_recipient: new mint recipient for the message, defaults to mint_recipient of original_message.. - entry fun replace_deposit_for_burn( - original_raw_message: vector, - original_attestation: vector, - new_destination_caller: Option
, - new_mint_recipient: Option
, - state: &State, - message_transmitter_state: &MessageTransmitterState, - ctx: &TxContext - ): (BurnMessage, Message) { - replace_deposit_for_burn_shared( - original_raw_message, original_attestation, new_destination_caller, - new_mint_recipient, ctx.sender(), state, message_transmitter_state - ) - } - - /// The same as replace_deposit_for_burn, but intended to be called from - /// a dependent package. Identifies sender from the unique identifier from the auth parameter. - /// Intended to be called from a dependent package. The calling package - /// must be the sender of the original message from using deposit_for_burn_with_package_auth or deposit_for_burn_with_caller_with_package_auth. - /// Direct callers should use replace_deposit_for_burn instead. - /// - /// Parameters: - /// - replace_deposit_for_burn_ticket: Struct containing parameters and authenticator struct. - public fun replace_deposit_for_burn_with_package_auth( - replace_deposit_for_burn_ticket: ReplaceDepositForBurnTicket, - state: &State, - message_transmitter_state: &MessageTransmitterState, - ): (BurnMessage, Message) { - let ReplaceDepositForBurnTicket { - auth: _auth, - original_raw_message, - original_attestation, - new_destination_caller, - new_mint_recipient - } = replace_deposit_for_burn_ticket; - - // This function call is intended to come from a dependent package, - // so the sender is the auth caller identifier. - let sender = auth_caller_identifier(); - replace_deposit_for_burn_shared( - original_raw_message, original_attestation, new_destination_caller, - new_mint_recipient, sender, state, message_transmitter_state - ) - } - - // === Ticket Structs/Functions === - - /// The following create_..._ticket functions are non version-gated functions, intended to be - /// called directly from other packages to create ticket structs that can be passed into public version-gated functions - /// outside of the calling package in a PTB. This prevents dependent packages from needing to be updated after CCTP upgrades. - #[allow(lint(coin_field))] - public struct DepositForBurnTicket { - auth: Auth, - coins: Coin, - destination_domain: u32, - mint_recipient: address, - } - - /// Not version-gated so it can be safely called from a dependent package, - /// and then passed to deposit_for_burn_with_package_auth (version-gated) from a PTB. - /// See deposit_for_burn for parameter information. - public fun create_deposit_for_burn_ticket( - auth: Auth, - coins: Coin, - destination_domain: u32, - mint_recipient: address - ): DepositForBurnTicket { - DepositForBurnTicket { auth, coins, destination_domain, mint_recipient } - } - - #[allow(lint(coin_field))] - public struct DepositForBurnWithCallerTicket { - auth: Auth, - coins: Coin, - destination_domain: u32, - mint_recipient: address, - destination_caller: address - } - - /// Not version-gated so it can be safely called from a dependent package, - /// and then passed to deposit_for_burn_with_caller_with_package_auth (version-gated) from a PTB. - /// See deposit_for_burn for parameter information. - public fun create_deposit_for_burn_with_caller_ticket( - auth: Auth, - coins: Coin, - destination_domain: u32, - mint_recipient: address, - destination_caller: address - ): DepositForBurnWithCallerTicket { - DepositForBurnWithCallerTicket { auth, coins, destination_domain, mint_recipient, destination_caller } - } - - #[allow(lint(coin_field))] - public struct ReplaceDepositForBurnTicket { - auth: Auth, - original_raw_message: vector, - original_attestation: vector, - new_destination_caller: Option
, - new_mint_recipient: Option
, - } - - /// Not version-gated so it can be safely called from a dependent package, - /// and then passed to replace_deposit_for_burn_with_package_auth (version-gated) from a PTB. - /// See replace_deposit_for_burn for parameter information. - public fun create_replace_deposit_for_burn_ticket( - auth: Auth, - original_raw_message: vector, - original_attestation: vector, - new_destination_caller: Option
, - new_mint_recipient: Option
, - ): ReplaceDepositForBurnTicket { - ReplaceDepositForBurnTicket { auth, original_raw_message, original_attestation, new_destination_caller, new_mint_recipient } - } - - // === Private Functions === - - /// Shared functionality between deposit_for_burn and deposit_for_burn_with_caller. - /// Performs validations, burns tokens, and calls message_transmitter::send_message - /// to emit the cross-chain message. - fun deposit_for_burn_shared( - coins: Coin, - destination_domain: u32, - mint_recipient: address, - destination_caller: address, - message_sender: address, - state: &State, - message_transmitter_state: &mut MessageTransmitterState, - deny_list: &DenyList, - treasury: &mut Treasury, - ctx: &TxContext - ): (BurnMessage, Message) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - let amount = coins.value(); - let token_id = calculate_token_id(); - - assert!(!state.paused(), EPaused); - assert!(amount > 0, EZeroAmount); - assert!(mint_recipient != @0x0, EZeroAddressMintRecipient); - - let destination_token_messenger = safe_get_remote_token_messenger(destination_domain, state); - let mint_cap = safe_get_mint_cap(token_id, state); - let burn_limit = safe_get_burn_limit(token_id, state); - - assert!(burn_limit >= amount, EBurnLimitExceeded); - - treasury::burn(treasury, mint_cap, deny_list, coins, ctx); - - let burn_message = burn_message::new(state.message_body_version(), token_id, mint_recipient, amount as u256, message_sender); - - let message = send_deposit_for_burn_message( - destination_domain, - destination_token_messenger, - destination_caller, - &burn_message, - message_transmitter_state - ); - - emit(DepositForBurn { - nonce: message.nonce(), - burn_token: token_id, - amount, - depositor: message_sender, - mint_recipient, - destination_domain, - destination_token_messenger, - destination_caller - }); - - (burn_message, message) - } - - /// Shared functionality between replace_deposit_for_burn and replace_deposit_for_burn_with_package_auth. - /// Replaces a given BurnMessage if sender is the same as the original message sender. - /// Returns the updated BurnMessage and Message. - fun replace_deposit_for_burn_shared( - original_raw_message: vector, - original_attestation: vector, - new_destination_caller: Option
, - new_mint_recipient: Option
, - sender: address, - state: &State, - message_transmitter_state: &MessageTransmitterState - ): (BurnMessage, Message) { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - let original_message_body = message::message_body_from_bytes(&original_raw_message); - let mut burn_message = burn_message::from_bytes(&original_message_body); - - // sender could either be an EOA or an Auth identifier. - assert!(burn_message.message_sender() == sender, ESenderDoesNotMatchOriginalSender); - - let final_new_mint_recipient = new_mint_recipient.get_with_default(burn_message.mint_recipient()); - assert!(final_new_mint_recipient != @0x0, EZeroAddressMintRecipient); - burn_message.update_mint_recipient(final_new_mint_recipient); - burn_message.update_version(state.message_body_version()); - - let new_message_body = option::some(burn_message.serialize()); - - let authenticator = message_transmitter_authenticator::new(); - let ticket = create_replace_message_ticket( - authenticator, original_raw_message, original_attestation, new_message_body, new_destination_caller - ); - let new_message = replace_message( - ticket, message_transmitter_state - ); - - emit(DepositForBurn { - nonce: new_message.nonce(), - burn_token: burn_message.burn_token(), - amount: burn_message.amount() as u64, - depositor: sender, - mint_recipient: final_new_mint_recipient, - destination_domain: new_message.destination_domain(), - destination_token_messenger: new_message.recipient(), - destination_caller: new_message.destination_caller() - }); - - (burn_message, new_message) - } - - /// Fetches the remote token messsenger, first validating that it exists. - fun safe_get_remote_token_messenger(remote_domain: u32, state: &State): address { - assert!(state.remote_token_messenger_for_remote_domain_exists(remote_domain), EInvalidDestinationDomain); - state.remote_token_messenger_from_remote_domain(remote_domain) - } - - /// Fetches the mint cap, first validating that it exists. - fun safe_get_mint_cap(local_token_id: address, state: &State): &MintCap { - assert!(state.mint_cap_for_local_token_exists(local_token_id), EMissingMintCap); - state.mint_cap_from_token_id>(local_token_id) - } - - /// Fetches the burn limit, first validating that it exists. - fun safe_get_burn_limit(local_token_id: address, state: &State): u64 { - assert!(state.burn_limit_for_token_id_exists(local_token_id), EMissingBurnLimit); - state.burn_limit_from_token_id(local_token_id) - } - - /// Sends a message through message_transmitter package. - fun send_deposit_for_burn_message( - destination_domain: u32, - destination_token_messenger: address, - destination_caller: address, - burn_message: &BurnMessage, - message_transmitter_state: &mut MessageTransmitterState - ): Message { - // Create a new message_transmitter_authenticator to pass to message_transmitter - let authenticator = message_transmitter_authenticator::new(); - - // Create the ticket and send the message. TokenMessengerMinter doesn't follow the pattern of returning the ticket - // and calling send_message in a PTB because TokenMessengerMinter and MessageTransmitter are controlled by the same - // owner so upgrades can be coordinated between the two. - let message; - if (destination_caller == @0x0) { - let ticket = create_send_message_ticket(authenticator, destination_domain, destination_token_messenger, burn_message.serialize()); - message = send_message(ticket, message_transmitter_state) - } else { - let ticket = create_send_message_with_caller_ticket(authenticator, destination_domain, destination_token_messenger, destination_caller, burn_message.serialize()); - message = send_message_with_caller(ticket, message_transmitter_state) - }; - - message - } - - #[test_only] - public fun create_deposit_for_burn_event( - nonce: u64, - burn_token: address, - amount: u64, - depositor: address, - mint_recipient: address, - destination_domain: u32, - destination_token_messenger: address, - destination_caller: address - ): DepositForBurn { - DepositForBurn {nonce, burn_token, amount, depositor,mint_recipient, destination_domain, destination_token_messenger, destination_caller} - } -} - -#[test_only] -module token_messenger_minter::deposit_for_burn_tests { - use sui::{ - coin::{Self, Coin}, - deny_list::{Self, DenyList}, - event::{num_events}, - test_scenario::{Self, Scenario}, - test_utils::{Self, assert_eq}, - }; - use message_transmitter::{ - attester_manager, - auth::auth_caller_identifier, - message::{Self, Message}, - message_transmitter_authenticator, - state as message_transmitter_state, - }; - use stablecoin::treasury::{Self, Treasury, MintCap}; - use token_messenger_minter::{ - burn_message::{Self, BurnMessage}, - deposit_for_burn, - message_transmitter_authenticator::{MessageTransmitterAuthenticator}, - state as token_messenger_state, - token_utils::calculate_token_id, - version_control - }; - use sui_extensions::test_utils::last_event_by_type; - - // Test token type - public struct DEPOSIT_FOR_BURN_TESTS has drop {} - - const AMOUNT: u256 = 100; - const ADMIN: address = @0xAD; - const USER: address = @0xA1; - const DESTINATION_DOMAIN: u32 = 2; - const MINT_RECIPIENT: address = @0xB2; - const DESTINATION_CALLER: address = @0xC3; - const REMOTE_TOKEN_MESSENGER: address = @0xD4; - - const NEW_DESTINATION_CALLER: address = @0xABCD; - const NEW_MINT_RECIPIENT: address = @0x5678; - const ORIGINAL_MINT_RECIPIENT: address = @0x9ABC; - - // === Tests === - - #[test] - fun test_deposit_for_burn_successful() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Perform deposit_for_burn - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - let (burn_message, message) = deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - // Assert correct BurnMessage values - assert_eq(burn_message.version(), 1); - assert_eq(burn_message.burn_token(), calculate_token_id()); - assert_eq(burn_message.mint_recipient(), MINT_RECIPIENT); - assert_eq(burn_message.amount(), AMOUNT); - assert_eq(burn_message.message_sender(), USER); - - // Assert correct Message values - assert_eq(message.version(), 1); - assert_eq(message.source_domain(), 0); - assert_eq(message.destination_domain(), 2); - assert_eq(message.nonce(), 0); - assert_eq(message.sender(), auth_caller_identifier()); - assert_eq(message.recipient(), REMOTE_TOKEN_MESSENGER); - assert_eq(message.destination_caller(), @0x0); - assert_eq( - message.message_body(), - x"00000001aa9d562b0a114a7cfa31074ac0ac0a543a25b034ba38830c82e7163775c94c8600000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000a1" - ); - - // num of events include message_sent, burn, and deposit for burn events - assert!(num_events() == 3); - let burn_token = calculate_token_id(); - assert!(last_event_by_type() == deposit_for_burn::create_deposit_for_burn_event(0,burn_token, AMOUNT as u64, USER, MINT_RECIPIENT, 2, REMOTE_TOKEN_MESSENGER, @0x0)); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - fun test_deposit_for_burn_with_package_auth_successful() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Perform deposit_for_burn - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - let auth = message_transmitter_authenticator::new(); - let auth_id = auth_caller_identifier(); - let ticket = deposit_for_burn::create_deposit_for_burn_ticket(auth, coins, DESTINATION_DOMAIN, MINT_RECIPIENT); - let (burn_message, message) = deposit_for_burn::deposit_for_burn_with_package_auth( - ticket, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - // Assert correct BurnMessage values - assert_eq(burn_message.version(), 1); - assert_eq(burn_message.burn_token(), calculate_token_id()); - assert_eq(burn_message.mint_recipient(), MINT_RECIPIENT); - assert_eq(burn_message.amount(), AMOUNT); - assert_eq(burn_message.message_sender(), auth_id); - - // Assert correct Message values - assert_eq(message.version(), 1); - assert_eq(message.source_domain(), 0); - assert_eq(message.destination_domain(), 2); - assert_eq(message.nonce(), 0); - assert_eq(message.sender(), auth_caller_identifier()); - assert_eq(message.recipient(), REMOTE_TOKEN_MESSENGER); - assert_eq(message.destination_caller(), @0x0); - assert_eq( - message.message_body(), - x"00000001aa9d562b0a114a7cfa31074ac0ac0a543a25b034ba38830c82e7163775c94c8600000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000064949764be99bacbf6297178f1b467586bac40d0012cb816d5c1a2ea9167e79dfe" - ); - - // num of events include message_sent, burn, and deposit for burn events - assert!(num_events() == 3); - let burn_token = calculate_token_id(); - assert_eq( - last_event_by_type(), - deposit_for_burn::create_deposit_for_burn_event(0,burn_token, AMOUNT as u64, auth_id, MINT_RECIPIENT, 2, REMOTE_TOKEN_MESSENGER, @0x0) - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - fun test_deposit_for_burn_with_caller_successful() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Perform deposit_for_burn_with_caller - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - let (burn_message, message) = deposit_for_burn::deposit_for_burn_with_caller( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - DESTINATION_CALLER, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - // Assert correct BurnMessage values - assert_eq(burn_message.version(), 1); - assert_eq(burn_message.burn_token(), calculate_token_id()); - assert_eq(burn_message.mint_recipient(), MINT_RECIPIENT); - assert_eq(burn_message.amount(), AMOUNT); - assert_eq(burn_message.message_sender(), USER); - - // Assert correct Message values - assert_eq(message.version(), 1); - assert_eq(message.source_domain(), 0); - assert_eq(message.destination_domain(), 2); - assert_eq(message.nonce(), 0); - assert_eq(message.sender(), auth_caller_identifier< MessageTransmitterAuthenticator>()); - assert_eq(message.recipient(), REMOTE_TOKEN_MESSENGER); - assert_eq(message.destination_caller(), DESTINATION_CALLER); - // Hardcoded expected message body - assert_eq( - message.message_body(), - x"00000001aa9d562b0a114a7cfa31074ac0ac0a543a25b034ba38830c82e7163775c94c8600000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000a1" - ); - - // num of events include message sent, burn, and deposit for burn events - assert!(num_events() == 3); - let burn_token = calculate_token_id(); - assert!(last_event_by_type() == deposit_for_burn::create_deposit_for_burn_event(0, burn_token, AMOUNT as u64, USER, MINT_RECIPIENT, 2, REMOTE_TOKEN_MESSENGER, DESTINATION_CALLER)); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - fun test_deposit_for_burn_with_caller_with_package_auth_successful() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Perform deposit_for_burn_with_caller_with_package_auth - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - let auth = message_transmitter_authenticator::new(); - let auth_id = auth_caller_identifier(); - let ticket = deposit_for_burn::create_deposit_for_burn_with_caller_ticket(auth, coins, DESTINATION_DOMAIN, MINT_RECIPIENT, DESTINATION_CALLER); - let (burn_message, message) = deposit_for_burn::deposit_for_burn_with_caller_with_package_auth( - ticket, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - // Assert correct BurnMessage values - assert_eq(burn_message.version(), 1); - assert_eq(burn_message.burn_token(), calculate_token_id()); - assert_eq(burn_message.mint_recipient(), MINT_RECIPIENT); - assert_eq(burn_message.amount(), AMOUNT); - assert_eq(burn_message.message_sender(), auth_id); - - // Assert correct Message values - assert_eq(message.version(), 1); - assert_eq(message.source_domain(), 0); - assert_eq(message.destination_domain(), 2); - assert_eq(message.nonce(), 0); - assert_eq(message.sender(), auth_caller_identifier()); - assert_eq(message.recipient(), REMOTE_TOKEN_MESSENGER); - assert_eq(message.destination_caller(), DESTINATION_CALLER); - // Hardcoded expected message body - assert_eq( - message.message_body(), - x"00000001aa9d562b0a114a7cfa31074ac0ac0a543a25b034ba38830c82e7163775c94c8600000000000000000000000000000000000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000064949764be99bacbf6297178f1b467586bac40d0012cb816d5c1a2ea9167e79dfe" - ); - - // num of events include message sent, burn, and deposit for burn events - assert!(num_events() == 3); - let burn_token = calculate_token_id(); - assert_eq( - last_event_by_type(), - deposit_for_burn::create_deposit_for_burn_event(0, burn_token, AMOUNT as u64, auth_id, MINT_RECIPIENT, 2, REMOTE_TOKEN_MESSENGER, DESTINATION_CALLER) - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EPaused)] - fun test_deposit_for_burn_when_paused() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Setup necessary state and pause - token_messenger_state.set_paused(true); - - // Attempt deposit_for_burn while paused - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EZeroAmount)] - fun test_deposit_for_burn_zero_amount() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Attempt deposit_for_burn with zero amount - scenario.next_tx(USER); - { - let mut coins = scenario.take_from_sender>(); - let coins_zero = coin::take(coins.balance_mut(), 0, scenario.ctx()); - deposit_for_burn::deposit_for_burn( - coins_zero, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - test_utils::destroy(coins); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EZeroAddressMintRecipient)] - fun test_deposit_for_burn_zero_address_mint_recipient() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Attempt deposit_for_burn with zero address mint recipient - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - @0x0, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EInvalidDestinationDomain)] - fun test_deposit_for_burn_invalid_destination_domain() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Attempt deposit_for_burn with invalid destination domain - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN + 1, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EMissingMintCap)] - fun test_deposit_for_burn_missing_mint_cap() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Setup necessary state (remove mint cap) - let mint_cap = token_messenger_state.remove_mint_cap>( - calculate_token_id() - ); - test_utils::destroy(mint_cap); - - // Attempt deposit_for_burn for token with missing mint cap - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EMissingBurnLimit)] - fun test_deposit_for_burn_missing_burn_limit() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Setup necessary state (remove burn limit) - token_messenger_state.remove_burn_limit(calculate_token_id()); - - // Attempt deposit_for_burn with missing burn limit - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EBurnLimitExceeded)] - fun test_deposit_for_burn_exceed_burn_limit() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Setup necessary state with a 1 burn limit - token_messenger_state.remove_burn_limit(calculate_token_id()); - token_messenger_state.add_burn_limit(calculate_token_id(), 1); - - // Attempt deposit_for_burn exceeding burn limit - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - fun test_deposit_for_burn_at_burn_limit() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Setup necessary state with burn limit equal to coin amount - token_messenger_state.remove_burn_limit(calculate_token_id()); - token_messenger_state.add_burn_limit( - calculate_token_id(), AMOUNT as u64 - ); - - // Perform deposit_for_burn at burn limit - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - let (burn_message, _) = deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - // Assert correct amount - assert_eq(burn_message.amount(), AMOUNT); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - fun test_deposit_for_burn_revert_incompatible_version() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, mut message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - token_messenger_state.add_compatible_version(5); - token_messenger_state.remove_compatible_version(version_control::current_version()); - - // Attempt deposit_for_burn, revert with incompatible version - scenario.next_tx(USER); - { - let coins = scenario.take_from_sender>(); - deposit_for_burn::deposit_for_burn( - coins, - DESTINATION_DOMAIN, - MINT_RECIPIENT, - &token_messenger_state, - &mut message_transmitter_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - }; - - // Clean up - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - scenario.end(); - } - - // replace_deposit_for_burn tests - - #[test] - fun test_replace_deposit_for_burn_successful() { - let mut admin_scenario = test_scenario::begin(ADMIN); - let admin_ctx = test_scenario::ctx(&mut admin_scenario); - let mut message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, admin_ctx - ); - let token_messenger_state = token_messenger_state::new(1, ADMIN, admin_ctx); - - attester_manager::enable_attester(@0xbcd4042de499d14e55001ccbb24a551f3b954096, &mut message_transmitter_state, admin_ctx); - test_scenario::end(admin_scenario); - - let mut user_scenario = test_scenario::begin(USER); - let user_ctx = test_scenario::ctx(&mut user_scenario); - - // Create original message and burn message - let nonce = 10; - let token_id = calculate_token_id(); - let burn_message = create_mock_burn_message( - 1, token_id, ORIGINAL_MINT_RECIPIENT, 100, USER - ); - let original_message = create_mock_message( - 1, 0, 2, nonce, auth_caller_identifier(), REMOTE_TOKEN_MESSENGER, @0x0, burn_message.serialize() - ); - let original_raw_message = original_message.serialize(); - let original_attestation = x"84e237e1467d8c4d3e8e79d2c165fd4cb5b91f6742e11a740de0b97a4cb720972f136da0ad945b780d3e748658ba2502e134e6b3db2f51ed4b458870c0a56f321b"; - - // Call replace_deposit_for_burn - let (new_burn_message, new_message) = deposit_for_burn::replace_deposit_for_burn( - original_raw_message, - original_attestation, - option::some(NEW_DESTINATION_CALLER), - option::some(NEW_MINT_RECIPIENT), - &token_messenger_state, - &message_transmitter_state, - user_ctx - ); - - // Assert burn message fields - assert_eq(new_burn_message.version(), 1); - assert_eq(new_burn_message.burn_token(), token_id); - assert_eq(new_burn_message.mint_recipient(), NEW_MINT_RECIPIENT); - assert_eq(new_burn_message.amount(), 100); - assert_eq(new_burn_message.message_sender(), USER); - - // Assert message fields - assert_eq(new_message.version(), 1); - assert_eq(new_message.source_domain(), 0); - assert_eq(new_message.destination_domain(), 2); - assert_eq(new_message.nonce(), nonce); - assert_eq(new_message.sender(), auth_caller_identifier()); - assert_eq(new_message.recipient(), REMOTE_TOKEN_MESSENGER); - assert_eq(new_message.destination_caller(), NEW_DESTINATION_CALLER); - assert_eq(new_message.message_body(), new_burn_message.serialize()); - - assert_eq(num_events(), 2); - let burn_token = calculate_token_id(); - assert_eq(last_event_by_type(), deposit_for_burn::create_deposit_for_burn_event(nonce, burn_token, AMOUNT as u64, USER, NEW_MINT_RECIPIENT, 2, REMOTE_TOKEN_MESSENGER, NEW_DESTINATION_CALLER)); - - test_utils::destroy(message_transmitter_state); - test_utils::destroy(token_messenger_state); - test_scenario::end(user_scenario); - } - - #[test] - fun test_replace_deposit_for_burn_with_package_auth_successful() { - let mut admin_scenario = test_scenario::begin(ADMIN); - let admin_ctx = test_scenario::ctx(&mut admin_scenario); - let mut message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, admin_ctx - ); - let token_messenger_state = token_messenger_state::new(1, ADMIN, admin_ctx); - - attester_manager::enable_attester(@0xbcd4042de499d14e55001ccbb24a551f3b954096, &mut message_transmitter_state, admin_ctx); - test_scenario::end(admin_scenario); - - // Create original message and burn message - let auth_id = auth_caller_identifier(); - let nonce = 10; - let token_id = calculate_token_id(); - let burn_message = create_mock_burn_message( - 1, token_id, ORIGINAL_MINT_RECIPIENT, 100, auth_id - ); - let original_message = create_mock_message( - 1, 0, 2, nonce, auth_caller_identifier(), REMOTE_TOKEN_MESSENGER, @0x0, burn_message.serialize() - ); - let original_raw_message = original_message.serialize(); - let original_attestation = x"21bb68570d977ec08120a349fa37615ef548cd98e8de3a4142802cf85c33f65a220626d6ea31bea28f5004e448b14ec85dc227a28a882c985ff8d3976e51f4951c"; - - // Call replace_deposit_for_burn_with_package_auth - let auth = message_transmitter_authenticator::new(); - let ticket = deposit_for_burn::create_replace_deposit_for_burn_ticket(auth, original_raw_message, original_attestation, option::some(NEW_DESTINATION_CALLER), option::some(NEW_MINT_RECIPIENT)); - let (new_burn_message, new_message) = deposit_for_burn::replace_deposit_for_burn_with_package_auth( - ticket, - &token_messenger_state, - &message_transmitter_state - ); - - // Assert burn message fields - assert_eq(new_burn_message.version(), 1); - assert_eq(new_burn_message.burn_token(), token_id); - assert_eq(new_burn_message.mint_recipient(), NEW_MINT_RECIPIENT); - assert_eq(new_burn_message.amount(), 100); - assert_eq(new_burn_message.message_sender(), auth_id); - - // Assert message fields - assert_eq(new_message.version(), 1); - assert_eq(new_message.source_domain(), 0); - assert_eq(new_message.destination_domain(), 2); - assert_eq(new_message.nonce(), nonce); - assert_eq(new_message.sender(), auth_caller_identifier()); - assert_eq(new_message.recipient(), REMOTE_TOKEN_MESSENGER); - assert_eq(new_message.destination_caller(), NEW_DESTINATION_CALLER); - assert_eq(new_message.message_body(), new_burn_message.serialize()); - - assert_eq(num_events(), 2); - let burn_token = calculate_token_id(); - assert_eq( - last_event_by_type(), - deposit_for_burn::create_deposit_for_burn_event(nonce, burn_token, AMOUNT as u64, auth_id, NEW_MINT_RECIPIENT, 2, REMOTE_TOKEN_MESSENGER, NEW_DESTINATION_CALLER) - ); - - test_utils::destroy(message_transmitter_state); - test_utils::destroy(token_messenger_state); - } - - #[test] - fun test_replace_deposit_for_burn_same_mint_recipient() { - let mut admin_scenario = test_scenario::begin(ADMIN); - let admin_ctx = test_scenario::ctx(&mut admin_scenario); - let mut message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, admin_ctx - ); - let token_messenger_state = token_messenger_state::new(1, ADMIN, admin_ctx); - - attester_manager::enable_attester(@0xbcd4042de499d14e55001ccbb24a551f3b954096, &mut message_transmitter_state, admin_ctx); - test_scenario::end(admin_scenario); - - let mut user_scenario = test_scenario::begin(USER); - let user_ctx = test_scenario::ctx(&mut user_scenario); - - let nonce = 10; - let token_id = calculate_token_id(); - let burn_message = create_mock_burn_message( - 1, token_id, ORIGINAL_MINT_RECIPIENT, 100, USER - ); - let original_message = create_mock_message( - 1, 0, 2, nonce, auth_caller_identifier(), REMOTE_TOKEN_MESSENGER, @0x0, burn_message.serialize() - ); - let original_raw_message = original_message.serialize(); - let original_attestation = x"84e237e1467d8c4d3e8e79d2c165fd4cb5b91f6742e11a740de0b97a4cb720972f136da0ad945b780d3e748658ba2502e134e6b3db2f51ed4b458870c0a56f321b"; - - let (new_burn_message, new_message) = deposit_for_burn::replace_deposit_for_burn( - original_raw_message, - original_attestation, - option::some(NEW_DESTINATION_CALLER), - option::none(), // Use same as original - &token_messenger_state, - &message_transmitter_state, - user_ctx - ); - - assert_eq(new_burn_message.mint_recipient(), ORIGINAL_MINT_RECIPIENT); - assert_eq(new_message.destination_caller(), NEW_DESTINATION_CALLER); - - assert_eq(num_events(), 2); - let burn_token = calculate_token_id(); - assert_eq(last_event_by_type(), deposit_for_burn::create_deposit_for_burn_event(nonce, burn_token, AMOUNT as u64, USER, ORIGINAL_MINT_RECIPIENT, 2, REMOTE_TOKEN_MESSENGER, NEW_DESTINATION_CALLER)); - - test_utils::destroy(message_transmitter_state); - test_utils::destroy(token_messenger_state); - test_scenario::end(user_scenario); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::ESenderDoesNotMatchOriginalSender)] - fun test_replace_deposit_for_burn_sender_mismatch() { - let mut scenario = test_scenario::begin(@0x9999); // Different sender - let ctx = test_scenario::ctx(&mut scenario); - let message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, ctx - ); - let token_messenger_state = token_messenger_state::new(1, ADMIN, ctx); - - let token_id = calculate_token_id(); - let burn_message = create_mock_burn_message(1, token_id, ORIGINAL_MINT_RECIPIENT, 100, USER); - let original_message = create_mock_message(1, 0, 2, 10, USER, @0x5678, @0x0, burn_message.serialize()); - let original_raw_message = original_message.serialize(); - let original_attestation = x""; - - deposit_for_burn::replace_deposit_for_burn( - original_raw_message, - original_attestation, - option::some(NEW_DESTINATION_CALLER), - option::some(NEW_MINT_RECIPIENT), - &token_messenger_state, - &message_transmitter_state, - ctx - ); - - test_utils::destroy(message_transmitter_state); - test_utils::destroy(token_messenger_state); - test_scenario::end(scenario); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::ESenderDoesNotMatchOriginalSender)] - fun test_replace_deposit_for_burn_with_package_auth_sender_mismatch() { - let mut scenario = test_scenario::begin(@0x9999); // Different sender - let ctx = test_scenario::ctx(&mut scenario); - let message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, ctx - ); - let token_messenger_state = token_messenger_state::new(1, ADMIN, ctx); - - let token_id = calculate_token_id(); - // Create original message owned by USER (rather than auth identifier) - let burn_message = create_mock_burn_message(1, token_id, ORIGINAL_MINT_RECIPIENT, 100, USER); - let original_message = create_mock_message(1, 0, 2, 10, USER, @0x5678, @0x0, burn_message.serialize()); - let original_raw_message = original_message.serialize(); - let original_attestation = x""; - - let auth = message_transmitter_authenticator::new(); - let ticket = deposit_for_burn::create_replace_deposit_for_burn_ticket(auth, original_raw_message, original_attestation, option::some(NEW_DESTINATION_CALLER), option::some(NEW_MINT_RECIPIENT)); - deposit_for_burn::replace_deposit_for_burn_with_package_auth( - ticket, - &token_messenger_state, - &message_transmitter_state - ); - - test_utils::destroy(message_transmitter_state); - test_utils::destroy(token_messenger_state); - test_scenario::end(scenario); - } - - #[test] - #[expected_failure(abort_code = deposit_for_burn::EZeroAddressMintRecipient)] - fun test_replace_deposit_for_burn_zero_address_mint_recipient() { - let mut scenario = test_scenario::begin(USER); - let ctx = test_scenario::ctx(&mut scenario); - let message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, ctx - ); - let token_messenger_state = token_messenger_state::new(1, ADMIN, ctx); - - let token_id = calculate_token_id(); - let burn_message = create_mock_burn_message( - 1, token_id, ORIGINAL_MINT_RECIPIENT, 100, USER - ); - let original_message = create_mock_message( - 1, 0, 2, 10, USER, @0x5678, @0x0, burn_message.serialize() - ); - let original_raw_message = original_message.serialize(); - let original_attestation = x""; - - deposit_for_burn::replace_deposit_for_burn( - original_raw_message, - original_attestation, - option::some(NEW_DESTINATION_CALLER), - option::some(@0x0), // Zero address mint recipient - &token_messenger_state, - &message_transmitter_state, - ctx - ); - - test_utils::destroy(message_transmitter_state); - test_utils::destroy(token_messenger_state); - test_scenario::end(scenario); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - fun test_replace_deposit_for_burn_revert_incompatible_version() { - let mut scenario = test_scenario::begin(USER); - let ctx = test_scenario::ctx(&mut scenario); - let message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, ctx - ); - let mut token_messenger_state = token_messenger_state::new(1, ADMIN, ctx); - token_messenger_state.add_compatible_version(5); - token_messenger_state.remove_compatible_version(version_control::current_version()); - - let token_id = calculate_token_id(); - let burn_message = create_mock_burn_message( - 1, token_id, ORIGINAL_MINT_RECIPIENT, 100, USER - ); - let original_message = create_mock_message( - 1, 0, 2, 10, USER, @0x5678, @0x0, burn_message.serialize() - ); - let original_raw_message = original_message.serialize(); - let original_attestation = x""; - - deposit_for_burn::replace_deposit_for_burn( - original_raw_message, - original_attestation, - option::some(NEW_DESTINATION_CALLER), - option::some(@0x0), // Zero address mint recipient - &token_messenger_state, - &message_transmitter_state, - ctx - ); - - test_utils::destroy(message_transmitter_state); - test_utils::destroy(token_messenger_state); - test_scenario::end(scenario); - } - - // === Test Helpers === - - fun setup_coin( - scenario: &mut Scenario - ): (MintCap, Treasury, DenyList) { - let otw = test_utils::create_one_time_witness(); - let (treasury_cap, deny_cap, metadata) = coin::create_regulated_currency_v2( - otw, - 6, - b"SYMBOL", - b"NAME", - b"", - option::none(), - true, - scenario.ctx() - ); - - let mut treasury = treasury::new( - treasury_cap, - deny_cap, - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx() - ); - treasury.configure_new_controller(ADMIN, ADMIN, scenario.ctx()); - scenario.next_tx(ADMIN); - let mint_cap = scenario.take_from_address>(ADMIN); - let deny_list = deny_list::new_for_testing(scenario.ctx()); - treasury.configure_minter(&deny_list, 999999999, scenario.ctx()); - test_utils::destroy(metadata); - - // Mint some coins for the user - treasury::mint( - &mut treasury, &mint_cap, &deny_list, AMOUNT as u64, USER, scenario.ctx() - ); - - (mint_cap, treasury, deny_list) - } - - fun setup_cctp_states( - mint_cap: MintCap, - scenario: &mut Scenario - ): (token_messenger_state::State, message_transmitter_state::State) { - let ctx = test_scenario::ctx(scenario); - - let mut token_messenger_state = token_messenger_state::new(1, ADMIN, ctx); - let message_transmitter_state = message_transmitter_state::new_for_testing( - 0, 1, 1000, ADMIN, ctx - ); - - // Setup necessary state - token_messenger_state.add_remote_token_messenger( - DESTINATION_DOMAIN, REMOTE_TOKEN_MESSENGER - ); - token_messenger_state.add_mint_cap( - calculate_token_id(), mint_cap - ); - token_messenger_state.add_burn_limit( - calculate_token_id(), 1000000 - ); - - (token_messenger_state, message_transmitter_state) - } - - // Helper function to create a mock burn message - fun create_mock_burn_message( - version: u32, - burn_token: address, - mint_recipient: address, - amount: u256, - message_sender: address - ): BurnMessage { - burn_message::new(version, burn_token, mint_recipient, amount, message_sender) - } - - // Helper function to create a mock message - fun create_mock_message( - version: u32, - source_domain: u32, - destination_domain: u32, - nonce: u64, - sender: address, - recipient: address, - destination_caller: address, - message_body: vector - ): Message { - message::new_for_testing( - version, - source_domain, - destination_domain, - nonce, - sender, - recipient, - destination_caller, - message_body - ) - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/handle_receive_message.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/handle_receive_message.move deleted file mode 100644 index e2bbe1878..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/handle_receive_message.move +++ /dev/null @@ -1,855 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: handle_receive_message -/// Contains public methods for handling incoming cross-chain stablecoin transfers. -/// -/// Please see message_transmitter::receive_message for starting the receive message flow. -/// Messages should be received in PTBs. -/// After calling message_transmitter::receive_message::receive_message, one should call -/// handle_receive_message from this module, followed by message_transmitter::receive_message::stamp_receipt -/// and message_transmitter::receive_message::complete_receive_message. -/// -/// Note on upgrades: handle_receive_message is version gated, so if -/// the package is upgraded, the upgraded package must be called. It -/// is not recommended to call it directly from a package and instead -/// to call it in a PTB. -module token_messenger_minter::handle_receive_message { - // === Imports === - use sui::{ - deny_list::{DenyList}, - event::emit - }; - use message_transmitter::{ - receive_message::{ - StampReceiptTicket, - Receipt, - create_stamp_receipt_ticket - } - }; - use stablecoin::treasury::{Self, Treasury, MintCap}; - use token_messenger_minter::{ - burn_message::{Self, BurnMessage}, - message_transmitter_authenticator::{Self, MessageTransmitterAuthenticator}, - state::{State}, - token_utils::{calculate_token_id}, - version_control::assert_object_version_is_compatible_with_package - }; - - // === Errors === - const EUnknownRemoteDomain: u64 = 0; - const EInvalidRemoteTokenMessenger: u64 = 1; - const EInvalidBurnMessageVersion: u64 = 2; - const EUnknownBurnToken: u64 = 3; - const EInvalidTokenType: u64 = 4; - const EMissingMintCap: u64 = 5; - const EPaused: u64 = 6; - const EAmountOverflow: u64 = 7; - - // === Constants === - const MAX_U64: u256 = 18_446_744_073_709_551_615; - - // === Events === - public struct MintAndWithdraw has copy, drop { - mint_recipient: address, - amount: u64, - mint_token: address - } - - // === Structs === - - public struct StampReceiptTicketWithBurnMessage { - stamp_receipt_ticket: StampReceiptTicket, - burn_message: BurnMessage - } - - // === Public-Mutative Functions === - - /// Handles an incoming message from message_transmitter, and mints - /// the specified token to the recipient for valid messages. Can only be called with - /// a Receipt object, which can only be created via the message_transmitter::receive_message function. - /// - /// Returns a StampReceiptTicketWithBurnMessage that can be deconstructed in a dependent package - /// via deconstruct_stamp_receipt_ticket_with_burn_message. - /// - /// In the calling PTB, callers must pass the returned StampReceiptTicket to message_transmitter::stamp_receipt - /// and then call message_transmitter::complete_receive_message to complete the message. - /// - /// Full example with a package destination_caller (in a PTB): - /// ``` - /// let receive_msg_ticket = your_package::prepare_receive_message_ticket(message, attestation); - /// let receipt = message_transmitter::receive_message_with_package_auth(receive_msg_ticket, &state); - /// let ticket_with_burn_message = token_messenger_minter::handle_receive_message(receipt); - /// // In your package you can call deconstruct_stamp_receipt_ticket_with_burn_message to deconstruct the ticket and burn_message - /// // and securely take some action with the burn_message. - /// let stamp_receipt_ticket = your_package::take_some_action(ticket_with_burn_message); - /// let stamped_receipt = message_transmitter::stamp_receipt(stamp_receipt_ticket); - /// message_transmitter::complete_receive_message(stamped_receipt); - /// ``` - /// - /// Full example with no destination caller (in a PTB): - /// ``` - /// let receipt = message_transmitter::receive_message(message, attestation, &state); - /// let ticket_with_burn_message = token_messenger_minter::handle_receive_message(receipt); - /// let (stamp_receipt_ticket, _burn_message) = token_messenger_minter::deconstruct_stamp_receipt_ticket_with_burn_message(ticket_with_burn_message); - /// let stamped_receipt = message_transmitter::stamp_receipt(stamp_receipt_ticket); - /// message_transmitter::complete_receive_message(stamped_receipt); - /// ``` - /// - /// Reverts if: - /// - Contract is paused - /// - Receipt is already stamped (e.g. has already been acknowledged by this module) - /// - Message body is not a valid BurnMessage - /// - Remote resources are unknown or invalid (remote token messenger or remote burned token are unknown) - /// - No MintCap for local token exists - /// - Invalid BurnMessage version - /// - stablecoin::mint call fails (insufficient minter allowance, deny list checks, etc.) - /// - /// Parameters: - /// - receipt: Receipt object returned from message_transmitter::receive_message. - /// Receipt is consumed into a StampReceiptTicket which - /// prevents message replays (since Receipt does not have the copy ability). - /// - state: TokenMessengerMinter shared state object. - /// - deny_list: DenyList shared object for the stablecoin token T. - /// - treasury: Treasury shared object for the stablecoin token T. - /// - ctx: TxContext for the tx. - public fun handle_receive_message( - receipt: Receipt, - state: &mut State, - deny_list: &DenyList, - treasury: &mut Treasury, - ctx: &mut TxContext - ): StampReceiptTicketWithBurnMessage { - assert_object_version_is_compatible_with_package(state.compatible_versions()); - assert!(!state.paused(), EPaused); - - let remote_domain = receipt.source_domain(); - let burn_message = burn_message::from_bytes(receipt.message_body()); - let burn_token_id = burn_message.burn_token(); - assert!(burn_message.amount() <= MAX_U64, EAmountOverflow); - let amount = burn_message.amount() as u64; - - // Validate the token messenger is setup correctly for the given message. - // Requires a valid remote token messenger, correct message version, a remote token, and a mint cap. - validate_remote_token_messenger(remote_domain, receipt.sender(), state); - validate_burn_message_version(burn_message.version(), state); - let local_token_id = validate_and_return_local_token(remote_domain, burn_token_id, state); - let mint_cap = validate_and_return_mint_cap(local_token_id, state); - - // Mint the Coin directly to the mint recipient - treasury::mint( - treasury, - mint_cap, - deny_list, - amount, - burn_message.mint_recipient(), - ctx - ); - - emit( - MintAndWithdraw { - mint_recipient: burn_message.mint_recipient(), - amount, - mint_token: local_token_id - } - ); - - // Create StampReceiptTicket so PTB can call stamp_receipt and complete the message - let auth = message_transmitter_authenticator::new(); - let stamp_receipt_ticket = create_stamp_receipt_ticket(auth, receipt); - - StampReceiptTicketWithBurnMessage { - stamp_receipt_ticket, - burn_message - } - } - - public fun deconstruct_stamp_receipt_ticket_with_burn_message( - ticket: StampReceiptTicketWithBurnMessage - ): (StampReceiptTicket, BurnMessage) { - let StampReceiptTicketWithBurnMessage { - stamp_receipt_ticket, - burn_message - } = ticket; - (stamp_receipt_ticket, burn_message) - } - - // === Private-Functions === - - /// Validates that a valid known remote token messenger exists for the given remote domain and sender. - fun validate_remote_token_messenger(remote_domain: u32, sender: address, state: &State) { - assert!(state.remote_token_messenger_for_remote_domain_exists(remote_domain), EUnknownRemoteDomain); - let remote_token_messenger = state.remote_token_messenger_from_remote_domain(remote_domain); - assert!( - remote_token_messenger == sender && sender != @0x0, - EInvalidRemoteTokenMessenger - ); - } - - /// Validates a valid known local token exists for the given remote domain, burn token, and Coin type T. - /// Returns the local token id for the given remote domain and token. - fun validate_and_return_local_token(remote_domain: u32, burn_token_id: address, state: &State): address { - assert!( - state.local_token_from_remote_token_exists(remote_domain, burn_token_id), - EUnknownBurnToken - ); - - let local_token_id = state.local_token_from_remote_token( - remote_domain, burn_token_id - ); - assert!(calculate_token_id() == local_token_id, EInvalidTokenType); - - local_token_id - } - - /// Validates that a valid known MintCap exists for the given local token id. - fun validate_and_return_mint_cap(local_token_id: address, state: &State): &MintCap { - assert!( - state.mint_cap_for_local_token_exists(local_token_id), - EMissingMintCap - ); - state.mint_cap_from_token_id>( - local_token_id - ) - } - - fun validate_burn_message_version(version: u32, state: &State) { - assert!(version == state.message_body_version(), EInvalidBurnMessageVersion); - } - - // === Test-Functions === - #[test_only] - public fun create_mint_and_withdraw_event( - mint_recipient: address, - amount: u64, - mint_token: address - ): MintAndWithdraw { - MintAndWithdraw { - mint_recipient, amount, mint_token - } - } -} - -#[test_only] -module token_messenger_minter::invalid_test_token { - public struct INVALID_TEST_TOKEN has drop {} -} - -#[test_only] -module token_messenger_minter::handle_receive_message_tests { - use sui::{ - coin, - deny_list::{Self, DenyList}, - event::{num_events}, - test_scenario::{Self, Scenario}, - test_utils::{Self, assert_eq} - }; - use stablecoin::treasury::{Self, Treasury, MintCap}; - use token_messenger_minter::{ - burn_message, - handle_receive_message::{Self, MintAndWithdraw, create_mint_and_withdraw_event}, - invalid_test_token::{INVALID_TEST_TOKEN}, - message_transmitter_authenticator::MessageTransmitterAuthenticator, - state as token_messenger_state, - token_utils::calculate_token_id, - version_control - }; - use message_transmitter::{ - auth::auth_caller_identifier, - receive_message::{Self, complete_receive_message, stamp_receipt}, - state as message_transmitter_state, - }; - use sui_extensions::test_utils::last_event_by_type; - - public struct HANDLE_RECEIVE_MESSAGE_TESTS has drop {} - - const USER: address = @0x1A; - const ADMIN: address = @0x2B; - const LOCAL_DOMAIN: u32 = 0; - const REMOTE_DOMAIN: u32 = 1; - const REMOTE_TOKEN_MESSENGER: address = @0x0000000000000000000000003b61AbEe91852714E4e99b09a1AF3e9C13893eF1; - const REMOTE_TOKEN: address = @0x0000000000000000000000001c7D4B196Cb0C7B01d743Fbc6116a902379C7238; - const MINT_RECIPIENT: address = @0x1f26414439c8d03fc4b9ca912cefd5cb508c9605; - const AMOUNT: u64 = 1214; - const VERSION: u32 = 0; - const MAX_U64: u256 = 18_446_744_073_709_551_615; - - #[test] - public fun test_handle_receive_message_successful() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - scenario.next_tx(USER); - { - // Get a fake receipt. In real scenarios this would be returned from receive_message. - let receipt = receive_message::create_receipt( - USER, - auth_caller_identifier(), - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - let (stamp_receipt_ticket, _message) = handle_receive_message::deconstruct_stamp_receipt_ticket_with_burn_message(ticket_and_message); - let stamped_receipt = stamp_receipt(stamp_receipt_ticket, &message_transmitter_state); - complete_receive_message(stamped_receipt, &message_transmitter_state); - }; - - // 3 events -- Mint, MintAndWithdraw, MessageReceived - assert_eq(num_events(), 3); - let emitted_mint_and_withdraw_event = last_event_by_type(); - let expected_event = create_mint_and_withdraw_event( - MINT_RECIPIENT, AMOUNT, calculate_token_id() - ); - assert_eq(emitted_mint_and_withdraw_event, expected_event); - - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EPaused)] - public fun test_handle_receive_message_revert_paused() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Set state to paused - token_messenger_state.set_paused(true); - - scenario.next_tx(USER); - { - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - let (stamp_receipt_ticket, _message) = handle_receive_message::deconstruct_stamp_receipt_ticket_with_burn_message(ticket_and_message); - test_utils::destroy(stamp_receipt_ticket); - }; - - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EUnknownRemoteDomain)] - public fun test_handle_receive_message_revert_unknown_remote_domain() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Use a remote domain that is not set up - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN + 1, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EAmountOverflow)] - public fun test_handle_receive_message_revert_amount_overflow() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Use a new burn message with a very large amount - let burn_message = burn_message::new( - VERSION, - REMOTE_TOKEN, - MINT_RECIPIENT, - MAX_U64 + 1, - REMOTE_TOKEN_MESSENGER - ); - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN + 1, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message.serialize(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EInvalidRemoteTokenMessenger)] - public fun test_handle_receive_message_revert_invalid_remote_token_messenger() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Use a different remote token messenger than the one set up - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - @0x2B, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EInvalidRemoteTokenMessenger)] - public fun test_handle_receive_message_revert_null_address_remote_token_messenger() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Add 0x0 remote token messenger to ensure it still reverts. - token_messenger_state.remove_remote_token_messenger(REMOTE_DOMAIN); - token_messenger_state.add_remote_token_messenger(REMOTE_DOMAIN, @0x0); - - // Use a different remote token messenger than the one set up - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - @0x0, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EInvalidBurnMessageVersion)] - public fun test_handle_receive_message_revert_invalid_burn_message_version() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Use a burn message with a different version than the one set up - let burn_message_with_different_version = burn_message::new( - VERSION + 1, - REMOTE_TOKEN, - MINT_RECIPIENT, - AMOUNT as u256, - REMOTE_TOKEN_MESSENGER - ).serialize(); - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message_with_different_version, - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EUnknownBurnToken)] - public fun test_handle_receive_message_revert_unknown_burn_token() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Use a remote token that is not set up - let burn_message_with_different_token = burn_message::new( - VERSION, - @0x12345, - MINT_RECIPIENT, - AMOUNT as u256, - REMOTE_TOKEN_MESSENGER - ).serialize(); - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message_with_different_token, - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EInvalidTokenType)] - public fun test_handle_receive_message_revert_invalid_token_type() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Use a local token ID that does not match the expected token type - token_messenger_state.remove_local_token_for_remote_token(REMOTE_DOMAIN, REMOTE_TOKEN); - token_messenger_state.add_local_token_for_remote_token(REMOTE_DOMAIN, REMOTE_TOKEN, @0x12345); - - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EInvalidTokenType)] - public fun test_handle_receive_message_revert_invalid_generic_token_type() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Setup a second token with a different type that token_messenger doesn't know about to try to pass in - let (mint_cap_2, mut treasury_2, deny_list_2) = setup_coin(&mut scenario); - - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list_2, - &mut treasury_2, - scenario.ctx() - ); - - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(deny_list_2); - test_utils::destroy(treasury); - test_utils::destroy(treasury_2); - test_utils::destroy(mint_cap_2); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = handle_receive_message::EMissingMintCap)] - public fun test_handle_receive_message_revert_missing_mint_cap() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - - // Remove the mint cap for the local token - let mint_cap = token_messenger_state.remove_mint_cap>( - calculate_token_id() - ); - - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - - test_utils::destroy(mint_cap); - test_utils::destroy(ticket_and_message); - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - #[test] - #[expected_failure(abort_code = version_control::EIncompatibleVersion)] - public fun test_handle_receive_message_revert_incompatible_version() { - let mut scenario = test_scenario::begin(ADMIN); - let (mint_cap, mut treasury, deny_list) = setup_coin(&mut scenario); - let (mut token_messenger_state, message_transmitter_state) = setup_cctp_states( - mint_cap, &mut scenario - ); - token_messenger_state.add_compatible_version(5); - token_messenger_state.remove_compatible_version(version_control::current_version()); - - scenario.next_tx(USER); - { - let receipt = receive_message::create_receipt( - USER, - @token_messenger_minter, - REMOTE_DOMAIN, - REMOTE_TOKEN_MESSENGER, - 12, - burn_message::get_raw_test_message(), - 1 - ); - - let ticket_and_message = handle_receive_message::handle_receive_message( - receipt, - &mut token_messenger_state, - &deny_list, - &mut treasury, - scenario.ctx() - ); - test_utils::destroy(ticket_and_message); - }; - - test_utils::destroy(token_messenger_state); - test_utils::destroy(message_transmitter_state); - test_utils::destroy(deny_list); - test_utils::destroy(treasury); - scenario.end(); - } - - // === Test-Functions === - - fun setup_coin( - scenario: &mut Scenario - ): (MintCap, Treasury, DenyList) { - let otw = test_utils::create_one_time_witness(); - let (treasury_cap, deny_cap, metadata) = coin::create_regulated_currency_v2( - otw, - 6, - b"SYMBOL", - b"NAME", - b"", - option::none(), - true, - scenario.ctx() - ); - - let mut treasury = treasury::new( - treasury_cap, - deny_cap, - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx().sender(), - scenario.ctx() - ); - treasury.configure_new_controller(ADMIN, ADMIN, scenario.ctx()); - scenario.next_tx(ADMIN); - let mint_cap = scenario.take_from_address>(ADMIN); - let deny_list = deny_list::new_for_testing(scenario.ctx()); - treasury.configure_minter(&deny_list, 999999999, scenario.ctx()); - test_utils::destroy(metadata); - - - // Mint some coins for the user - treasury::mint( - &mut treasury, &mint_cap, &deny_list, AMOUNT as u64, USER, scenario.ctx() - ); - - (mint_cap, treasury, deny_list) - } - - fun setup_cctp_states( - mint_cap: MintCap, - scenario: &mut Scenario - ): (token_messenger_state::State, message_transmitter_state::State) { - let ctx = test_scenario::ctx(scenario); - - let mut token_messenger_state = token_messenger_state::new(VERSION, ADMIN, ctx); - let message_transmitter_state = message_transmitter_state::new_for_testing( - LOCAL_DOMAIN, VERSION, 1000, ADMIN, ctx - ); - - // Setup necessary state - token_messenger_state.add_remote_token_messenger( - REMOTE_DOMAIN, REMOTE_TOKEN_MESSENGER - ); - token_messenger_state.add_mint_cap( - calculate_token_id(), mint_cap - ); - token_messenger_state.add_local_token_for_remote_token( - REMOTE_DOMAIN, REMOTE_TOKEN, calculate_token_id() - ); - token_messenger_state.add_burn_limit( - calculate_token_id(), 1000000 - ); - - (token_messenger_state, message_transmitter_state) - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/initialize.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/initialize.move deleted file mode 100644 index 96c214f2a..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/initialize.move +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: initialize -/// This module contains initialization code for the -/// TokenMessengerMinter package. -module token_messenger_minter::initialize { - // === Imports === - use token_messenger_minter::state::{Self}; - use sui_extensions::upgrade_service; - - // === Structs === - public struct InitCap has key, store { - id: UID - } - - public struct INITIALIZE has drop {} - - // === Admin Functions === - - #[allow(lint(share_owned))] - /// init (automatically called at deployment) transfers - /// an InitCap to the sender so they can call init_state - /// to initialize state with parameters. - /// Also creates and shares the wrapped Upgrade Service. - fun init(witness: INITIALIZE, ctx: &mut TxContext) { - let (upgrade_service, _witness) = upgrade_service::new( - witness, - ctx.sender() /* admin */, - ctx - ); - transfer::public_share_object(upgrade_service); - transfer::transfer(InitCap {id: object::new(ctx)}, ctx.sender()); - } - - /// Initializes and shares the State object. - /// Initializes state with given message_body_version, all roles set to the tx sender, - /// and paused set to false. - /// Requires (and destroys) an InitCap object which can only be created in init method, - /// therefore this function can only be called once. - public fun init_state(init_cap: InitCap, message_body_version: u32, ctx: &mut TxContext) { - let state = state::new(message_body_version, ctx.sender(), ctx); - state.share_state(); - - // Delete the init cap so init_state can only be called once - let InitCap {id} = init_cap; - object::delete(id); - } - - // === Test Functions === - #[test_only] use sui::test_scenario::{Self}; - #[test_only] use token_messenger_minter::state::{State}; - - #[test] - public fun test_init_successful() { - let mut scenario = test_scenario::begin(@0x0); - - // Test: When package is deployed InitCap is transferred to caller - init(INITIALIZE {}, scenario.ctx()); - let effects = scenario.next_tx(@0x1); - let created_init_cap_id = effects.created()[1]; - assert!(effects.transferred_to_account()[&created_init_cap_id] == @0x0); - - // Aborts if it doesn't exist - let created_init_cap = scenario.take_from_address_by_id(@0x0, created_init_cap_id); - test_scenario::return_to_address(@0x0, created_init_cap); - - // Clean up - scenario.end(); - } - - #[test] - fun test_init_state_successful() { - let mut scenario = test_scenario::begin(@0x0); - - // Get InitCap to call init_state - let init_cap = InitCap {id: object::new(scenario.ctx())}; - let init_cap_id = object::id(&init_cap); - - // Test: After init_state is called, shared_state was shared and InitCap was deleted. - scenario.next_tx(@0x5); - { - init_state(init_cap, 0, scenario.ctx()); - let effects = scenario.next_tx(@0x0); - let shared_state = scenario.take_shared(); - - assert!(effects.shared().length() == 1, 0); - assert!(effects.shared()[0] == object::id(&shared_state), 1); - assert!(effects.deleted().contains(&init_cap_id), 2); - - test_scenario::return_shared(shared_state); - }; - - scenario.end(); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/message_transmitter_authenticator.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/message_transmitter_authenticator.move deleted file mode 100644 index 3e78d5a60..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/message_transmitter_authenticator.move +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: message_transmitter_authenticator -/// message_transmitter::send_message requires message creators to pass in -/// an authentication object to prove the address that created the message. -/// This module implements methods to create that authentication object. -module token_messenger_minter::message_transmitter_authenticator { - // === Structs === - public struct MessageTransmitterAuthenticator has drop {} - - // === Public-Package Functions === - public(package) fun new(): MessageTransmitterAuthenticator { - MessageTransmitterAuthenticator {} - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/state.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/state.move deleted file mode 100644 index 749b01d1d..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/state.move +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: state -/// This module contains the core global Shared State used in the token_messenger_minter package. -module token_messenger_minter::state { - // === Imports === - use sui::{ - address::{Self}, - bag::{Self, Bag}, - bcs::{Self}, - hash::{Self}, - table::{Self, Table}, - vec_set::{Self, VecSet} - }; - use token_messenger_minter::{ - roles::{Self, Roles}, - version_control - }; - - // === Structs === - public struct State has key { - id: UID, - /// Immutable message body version - message_body_version: u32, - /// Map from remote domain to remote token messenger address - /// Use `address` type to represent remote addresses since Sui addresses - /// are conveniently 32 bytes and the CCTP protocol specifies 32 byte arrays - /// for representing external addresses. - remote_token_messengers: Table, - /// Map from local token ID to burn limit amount - burn_limits_per_message: Table, - /// Map from keccak(remote_domain, remote_token) to local token ID - /// A remote token (on a certain remote domain) can only map to one - /// local token, but many remote tokens can map to the same local token. - remote_tokens_to_local_tokens: Table, - /// Mapping of token ID to MintCap for minting - /// Use a Bag so we can store multiple different capability types - mint_caps: Bag, - /// Is contract paused - paused: bool, - /// All roles for package - roles: Roles, - /// The set of package version numbers that object is compatible with - compatible_versions: VecSet - } - - // === Public-Mutative Functions === - - /// Initialize the state with an immutable version and initial roles. Roles should be separated to different addresses later. - public(package) fun new(message_body_version: u32, caller: address, ctx: &mut TxContext): State { - State { - id: object::new(ctx), - roles: roles::new(caller, caller, caller, ctx), - remote_token_messengers: table::new(ctx), - burn_limits_per_message: table::new(ctx), - remote_tokens_to_local_tokens: table::new(ctx), - mint_caps: bag::new(ctx), - paused: false, - message_body_version, - compatible_versions: vec_set::singleton(version_control::current_version()) - } - } - - #[allow(lint(share_owned))] - public(package) fun share_state(state: State) { - transfer::share_object(state); - } - - // === Getters === - - public fun message_body_version(state: &State): u32 { - state.message_body_version - } - - public fun paused(state: &State): bool { - state.paused - } - - public fun roles(state: &State): &Roles { - &state.roles - } - - public fun remote_token_messenger_from_remote_domain(state: &State, remote_domain: u32): address { - *state.remote_token_messengers.borrow(remote_domain) - } - - public fun burn_limit_from_token_id(state: &State, token_id: address): u64 { - *state.burn_limits_per_message.borrow(token_id) - } - - public fun local_token_from_remote_token(state: &State, remote_domain: u32, remote_token: address): address { - let key = generate_remote_token_key(remote_domain, remote_token); - *state.remote_tokens_to_local_tokens.borrow(key) - } - - public fun local_token_from_remote_token_exists(state: &State, remote_domain: u32, remote_token: address): bool { - let key = generate_remote_token_key(remote_domain, remote_token); - state.remote_tokens_to_local_tokens.contains(key) - } - - public fun remote_token_messenger_for_remote_domain_exists(state: &State, remote_domain: u32): bool { - state.remote_token_messengers.contains(remote_domain) - } - - public fun mint_cap_for_local_token_exists(state: &State, local_token_id: address): bool { - state.mint_caps.contains(local_token_id) - } - - public fun burn_limit_for_token_id_exists(state: &State, token_id: address): bool { - state.burn_limits_per_message.contains(token_id) - } - - public fun compatible_versions(state: &State): &VecSet { - &state.compatible_versions - } - - // === Public-Package Functions === - - public(package) fun roles_mut(state: &mut State): &mut Roles { - &mut state.roles - } - - public(package) fun mint_cap_from_token_id(state: &State, token_id: address): &T { - state.mint_caps.borrow(token_id) - } - - public(package) fun set_paused(state: &mut State, paused: bool) { - state.paused = paused; - } - - public(package) fun add_mint_cap(state: &mut State, token_id: address, mint_cap: T) { - state.mint_caps.add(token_id, mint_cap); - } - - public(package) fun add_remote_token_messenger(state: &mut State, remote_domain: u32, remote_token_messenger: address) { - state.remote_token_messengers.add(remote_domain, remote_token_messenger); - } - - public(package) fun add_burn_limit(state: &mut State, token_id: address, limit: u64) { - state.burn_limits_per_message.add(token_id, limit); - } - - public(package) fun add_local_token_for_remote_token(state: &mut State, remote_domain: u32, remote_token: address, local_token_id: address) { - let key = generate_remote_token_key(remote_domain, remote_token); - state.remote_tokens_to_local_tokens.add(key, local_token_id); - } - - public(package) fun remove_mint_cap(state: &mut State, token_id: address): T { - state.mint_caps.remove(token_id) - } - - public(package) fun remove_remote_token_messenger(state: &mut State, remote_domain: u32): address { - state.remote_token_messengers.remove(remote_domain) - } - - public(package) fun remove_burn_limit(state: &mut State, token_id: address): u64 { - state.burn_limits_per_message.remove(token_id) - } - - public(package) fun remove_local_token_for_remote_token(state: &mut State, remote_domain: u32, remote_token: address): address { - let key = generate_remote_token_key(remote_domain, remote_token); - state.remote_tokens_to_local_tokens.remove(key) - } - - public(package) fun add_compatible_version(state: &mut State, version: u64) { - state.compatible_versions.insert(version); - } - - public(package) fun remove_compatible_version(state: &mut State, version: u64) { - state.compatible_versions.remove(&version); - } - - // === Private Functions === - - /// Helper function for calculating the key for a (remote_domain, remote_token) pair in a Table. - /// (remote_domain, remote_token) keys in Tables are represented as an address of the keccak256 - /// hash of their concatenated bytes. keccak256 returns a 32 bytes array so this can always be - /// represented as an address type. - fun generate_remote_token_key(remote_domain: u32, remote_token: address): address { - // Create (remote_domain, remote_token) concatenated bytes vector - let mut remote_resource = bcs::to_bytes(&remote_domain); - remote_resource.append(b"-"); - remote_resource.append(remote_token.to_bytes()); - - // Hash them and return - address::from_bytes(hash::keccak256(&remote_resource)) - } - - // === Test Functions === - #[test_only] use sui::test_utils; - #[test_only] use token_messenger_minter::state::{Self}; - - #[test_only] - public fun new_for_testing(message_body_version: u32, caller: address, ctx: &mut TxContext): State { - State { - id: object::new(ctx), - roles: roles::new(caller, caller, caller, ctx), - remote_token_messengers: table::new(ctx), - burn_limits_per_message: table::new(ctx), - remote_tokens_to_local_tokens: table::new(ctx), - mint_caps: bag::new(ctx), - paused: false, - message_body_version, - compatible_versions: vec_set::singleton(version_control::current_version()) - } - } - - #[test_only] - public struct TestCap has store, key { - id: UID, - address: address - } - - // new tests - - #[test] - fun state_new_creates_object() { - let ctx = &mut tx_context::dummy(); - - let expected_msg_version = 1; - let expected_role = @0x1; - let expected_remote_token_messenger = @0x1; - let mint_cap = TestCap { id: object::new(ctx), address: ctx.fresh_object_address() }; - let expected_mint_cap_id = mint_cap.address; - let expected_burn_limit = 100; - let expected_local_token = @0x5; - let expected_remote_token = @0x6; - let remote_domain = 5; - let new_version = 5; - - // Create state object and add some objects to the maps - let mut state_obj = state::new(expected_msg_version, expected_role, ctx); - state_obj.add_mint_cap(expected_local_token, mint_cap); - state_obj.add_remote_token_messenger(0, expected_remote_token_messenger); - state_obj.add_burn_limit(expected_local_token, expected_burn_limit); - state_obj.add_local_token_for_remote_token(remote_domain, expected_remote_token, expected_local_token); - state_obj.set_paused(true); - - assert!(state_obj.message_body_version() == expected_msg_version); - assert!(state_obj.paused() == true); - assert!(state_obj.roles().owner() == expected_role); - assert!(state_obj.roles().pending_owner() == option::none()); - assert!(state_obj.roles().pauser() == expected_role); - assert!(state_obj.roles().token_controller() == expected_role); - assert!(state::mint_cap_for_local_token_exists(&state_obj, expected_local_token)); - assert!(&state::mint_cap_from_token_id(&state_obj, expected_local_token).address == expected_mint_cap_id); - assert!(state_obj.remote_token_messenger_for_remote_domain_exists(0)); - assert!(state_obj.remote_token_messenger_from_remote_domain(0) == expected_remote_token_messenger); - assert!(state_obj.burn_limit_for_token_id_exists(expected_local_token)); - assert!(state_obj.burn_limit_from_token_id(expected_local_token) == expected_burn_limit); - assert!(state_obj.local_token_from_remote_token_exists(remote_domain, expected_remote_token) == true); - assert!(state_obj.local_token_from_remote_token(remote_domain, expected_remote_token) == expected_local_token); - - state_obj.add_compatible_version(new_version); - assert!(state_obj.compatible_versions().contains(&new_version)); - state_obj.remove_compatible_version(new_version); - assert!(!state_obj.compatible_versions().contains(&new_version)); - - // Empty the tables and bags before destroying - let TestCap {id: mint_id, address: mint_cap_address} = state_obj.remove_mint_cap(expected_local_token); - assert!(mint_cap_address == expected_mint_cap_id); - assert!(state_obj.remove_remote_token_messenger(0) == expected_remote_token_messenger); - assert!(state_obj.remove_burn_limit(expected_local_token) == expected_burn_limit); - assert!(state_obj.remove_local_token_for_remote_token(remote_domain, expected_remote_token) == expected_local_token); - mint_id.delete(); - - test_utils::destroy(state_obj); - } -} diff --git a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/token_utils.move b/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/token_utils.move deleted file mode 100644 index cfbddf73e..000000000 --- a/contracts/vendored/circlefin/sui-cctp/packages/token_messenger_minter/sources/token_utils.move +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2024, Circle Internet Group, Inc. All rights reserved. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/// Module: token_utils -/// This module contains token utilities like calculating a token id. -module token_messenger_minter::token_utils { - // === Imports === - use std::type_name::{Self}; - use sui::{hash::{Self}, address::{Self}}; - - // === Public-View Functions === - - /// Calculates the unique token id for a given coin Witness Type T. - /// CCTP defines a Sui Token id as the keccak-256 hash of it's full type name. - /// We cannot use the package address alone as it could contain multiple coin Witnesses. - public fun calculate_token_id(): address { - let full_type_name = type_name::get().into_string().into_bytes(); - address::from_bytes(hash::keccak256(&full_type_name)) - } - - // === Tests === - - #[test_only] - public struct TestStr has drop {} - - #[test] - fun calculate_token_id_returns_id() { - // Pre-calculate hash of the TestStr typename (0000000000000000000000000000000000000000000000000000000000000002::token_utils::TestStr) - let expected_bytes = @0xf9f9bf6008c46a66c228f4e44f81b3e14ea6e14d1578aad1bfce9621bf7dd9be; - - // Test: should return the expected (pre-caluclated) bytes - let id = calculate_token_id(); - assert!(id == expected_bytes, 0); - } -} diff --git a/deployment/changesets/cs_mcms_execute_ownership_transfer.go b/deployment/changesets/cs_mcms_execute_ownership_transfer.go index eda10f0af..25a436dc4 100644 --- a/deployment/changesets/cs_mcms_execute_ownership_transfer.go +++ b/deployment/changesets/cs_mcms_execute_ownership_transfer.go @@ -16,7 +16,6 @@ import ( offrampops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_offramp" onrampops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_onramp" routerops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_router" - usdctokenpoolops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_usdc_token_pool" managedtokenops "github.com/smartcontractkit/chainlink-sui/deployment/ops/managed_token" mcmsops "github.com/smartcontractkit/chainlink-sui/deployment/ops/mcms" ownershipops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ownership" @@ -40,7 +39,6 @@ type MCMSExecuteTransferOwnershipInput struct { OffRamp bool `json:"offramp,omitempty" yaml:"offramp,omitempty"` Router bool `json:"router,omitempty" yaml:"router,omitempty"` ManagedToken bool `json:"managed_token,omitempty" yaml:"managed_token,omitempty"` - UsdcTokenPool bool `json:"usdc_token_pool,omitempty" yaml:"usdc_token_pool,omitempty"` BurnMintTokenPoolTokenSymbol string `json:"burn_mint_token_pool,omitempty" yaml:"burn_mint_token_pool,omitempty"` LockReleaseTokenPoolTokenSymbol string `json:"lock_release_token_pool,omitempty" yaml:"lock_release_token_pool,omitempty"` ManagedTokenPoolTokenSymbol string `json:"managed_token_pool,omitempty" yaml:"managed_token_pool,omitempty"` @@ -181,12 +179,6 @@ func (d MCMSExecuteTransferOwnership) Apply(e cldf.Environment, config MCMSExecu } } - // TODO: not supported yet - if config.UsdcTokenPool { - input.UsdcTokenPool = &usdctokenpoolops.ExecuteOwnershipTransferToMcmsUsdcTokenPoolInput{} - return cldf.ChangesetOutput{}, fmt.Errorf("usdc token pool ownership transfer not implemented yet") - } - // Execute the sequence _, err = cld_ops.ExecuteSequence(e.OperationsBundle, ownershipops.ExecuteOwnershipTransferToMcmsSequence, deps, input) if err != nil { @@ -204,7 +196,7 @@ func (d MCMSExecuteTransferOwnership) VerifyPreconditions(e cldf.Environment, co // Check that at least one contract type is selected if !config.MCMS && !config.StateObject && !config.OnRamp && !config.OffRamp && !config.Router && !config.ManagedToken && - !config.UsdcTokenPool && config.LockReleaseTokenPoolTokenSymbol == "" && + config.LockReleaseTokenPoolTokenSymbol == "" && config.ManagedTokenPoolTokenSymbol == "" && config.BurnMintTokenPoolTokenSymbol == "" { return fmt.Errorf("at least one contract type must be selected for ownership transfer") } diff --git a/deployment/ops/ccip_usdc_token_pool/op_deploy.go b/deployment/ops/ccip_usdc_token_pool/op_deploy.go deleted file mode 100644 index 827fd3207..000000000 --- a/deployment/ops/ccip_usdc_token_pool/op_deploy.go +++ /dev/null @@ -1,185 +0,0 @@ -package usdctokenpoolops - -import ( - "fmt" - - "github.com/Masterminds/semver/v3" - - cld_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations" - - "github.com/smartcontractkit/chainlink-sui/bindings/bind" - module_usdctokenpool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/usdc_token_pool" - usdctokenpool "github.com/smartcontractkit/chainlink-sui/bindings/packages/ccip_token_pools/usdc_token_pool" - sui_ops "github.com/smartcontractkit/chainlink-sui/deployment/ops" -) - -type USDCTokenPoolDeployInput struct { - CCIPPackageId string - USDCCoinMetadataObjectId string - TokenMessengerMinterPackageId string - TokenMessengerMinterStateObjectId string - MessageTransmitterPackageId string - MessageTransmitterStateObjectId string - TreasuryObjectId string - MCMSAddress string - FastMcmsAddress string - MCMSOwnerAddress string -} - -type USDCTokenPoolDeployOutput struct { - OwnerCapObjectId string -} - -var deployHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input USDCTokenPoolDeployInput) (output sui_ops.OpTxResult[USDCTokenPoolDeployOutput], err error) { - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tokenPoolPackage, tx, err := usdctokenpool.PublishCCIPUSDCTokenPool( - b.GetContext(), - opts, - deps.Client, - input.CCIPPackageId, - input.USDCCoinMetadataObjectId, - input.TokenMessengerMinterPackageId, - input.TokenMessengerMinterStateObjectId, - input.MessageTransmitterPackageId, - input.MessageTransmitterStateObjectId, - input.TreasuryObjectId, - input.MCMSAddress, - input.FastMcmsAddress, - input.MCMSOwnerAddress, - deps.SuiRPC, - ) - if err != nil { - return sui_ops.OpTxResult[USDCTokenPoolDeployOutput]{}, err - } - - ownerCapObj, err := bind.FindObjectIdFromPublishTx(*tx, "ownable", "OwnerCap") - if err != nil { - return sui_ops.OpTxResult[USDCTokenPoolDeployOutput]{}, fmt.Errorf("failed to find OwnerCap object ID: %w", err) - } - - return sui_ops.OpTxResult[USDCTokenPoolDeployOutput]{ - Digest: tx.Digest, - PackageId: tokenPoolPackage.Address(), - Objects: USDCTokenPoolDeployOutput{ - OwnerCapObjectId: ownerCapObj, - }, - }, err -} - -var DeployCCIPUSDCTokenPoolOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip-usdc-token-pool", "package", "deploy"), - semver.MustParse("0.1.0"), - "Deploys the CCIP USDC token pool package", - deployHandler, -) - -type TransferOwnershipUsdcTokenPoolInput struct { - UsdcTokenPoolPackageId string - TypeArgs []string - StateObjectId string - OwnerCapObjectId string - To string -} - -type TransferOwnershipUsdcTokenPoolObjects struct { - // No specific objects are returned from transfer_ownership -} - -var transferOwnershipUsdcTokenPoolHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input TransferOwnershipUsdcTokenPoolInput) (output sui_ops.OpTxResult[TransferOwnershipUsdcTokenPoolObjects], err error) { - usdcTokenPoolPackage, err := module_usdctokenpool.NewUsdcTokenPool(input.UsdcTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[TransferOwnershipUsdcTokenPoolObjects]{}, err - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := usdcTokenPoolPackage.TransferOwnership( - b.GetContext(), - opts, - input.TypeArgs, - bind.Object{Id: input.StateObjectId}, - bind.Object{Id: input.OwnerCapObjectId}, - input.To, - ) - if err != nil { - return sui_ops.OpTxResult[TransferOwnershipUsdcTokenPoolObjects]{}, fmt.Errorf("failed to execute TransferOwnership on UsdcTokenPool: %w", err) - } - - b.Logger.Infow("Ownership transfer initiated for UsdcTokenPool", "to", input.To) - - return sui_ops.OpTxResult[TransferOwnershipUsdcTokenPoolObjects]{ - Digest: tx.Digest, - PackageId: input.UsdcTokenPoolPackageId, - Objects: TransferOwnershipUsdcTokenPoolObjects{}, - }, nil -} - -var TransferOwnershipUsdcTokenPoolOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip-usdc-token-pool-transfer-ownership", "package", "configure"), - semver.MustParse("0.1.0"), - "Transfers ownership of the UsdcTokenPool", - transferOwnershipUsdcTokenPoolHandler, -) - -type AcceptOwnershipUsdcTokenPoolInput struct { - UsdcTokenPoolPackageId string - TypeArgs []string - StateObjectId string -} - -type AcceptOwnershipUsdcTokenPoolObjects struct { - // No specific objects are returned from accept_ownership -} - -var acceptOwnershipUsdcTokenPoolHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input AcceptOwnershipUsdcTokenPoolInput) (output sui_ops.OpTxResult[AcceptOwnershipUsdcTokenPoolObjects], err error) { - usdcTokenPoolPackage, err := module_usdctokenpool.NewUsdcTokenPool(input.UsdcTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[AcceptOwnershipUsdcTokenPoolObjects]{}, err - } - - encodedCall, err := usdcTokenPoolPackage.Encoder().AcceptOwnership(input.TypeArgs, bind.Object{Id: input.StateObjectId}) - if err != nil { - return sui_ops.OpTxResult[AcceptOwnershipUsdcTokenPoolObjects]{}, fmt.Errorf("failed to encode AcceptOwnership call: %w", err) - } - call, err := sui_ops.ToTransactionCallWithTypeArgs(encodedCall, input.StateObjectId, input.TypeArgs) - if err != nil { - return sui_ops.OpTxResult[AcceptOwnershipUsdcTokenPoolObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err) - } - if deps.Signer == nil { - b.Logger.Infow("Skipping execution of AcceptOwnership on UsdcTokenPool as per no Signer provided") - return sui_ops.OpTxResult[AcceptOwnershipUsdcTokenPoolObjects]{ - Digest: "", - PackageId: input.UsdcTokenPoolPackageId, - Objects: AcceptOwnershipUsdcTokenPoolObjects{}, - Call: call, - }, nil - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := usdcTokenPoolPackage.Bound().ExecuteTransaction( - b.GetContext(), - opts, - encodedCall, - ) - if err != nil { - return sui_ops.OpTxResult[AcceptOwnershipUsdcTokenPoolObjects]{}, fmt.Errorf("failed to execute AcceptOwnership on UsdcTokenPool: %w", err) - } - - b.Logger.Infow("Ownership accepted for UsdcTokenPool") - - return sui_ops.OpTxResult[AcceptOwnershipUsdcTokenPoolObjects]{ - Digest: tx.Digest, - PackageId: input.UsdcTokenPoolPackageId, - Objects: AcceptOwnershipUsdcTokenPoolObjects{}, - Call: call, - }, nil -} - -var AcceptOwnershipUsdcTokenPoolOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip-usdc-token-pool-accept-ownership", "package", "configure"), - semver.MustParse("0.1.0"), - "Accepts ownership of the UsdcTokenPool", - acceptOwnershipUsdcTokenPoolHandler, -) diff --git a/deployment/ops/ccip_usdc_token_pool/op_execute_ownership_transfer_to_mcms.go b/deployment/ops/ccip_usdc_token_pool/op_execute_ownership_transfer_to_mcms.go deleted file mode 100644 index 56580703b..000000000 --- a/deployment/ops/ccip_usdc_token_pool/op_execute_ownership_transfer_to_mcms.go +++ /dev/null @@ -1,95 +0,0 @@ -package usdctokenpoolops - -import ( - "fmt" - - "github.com/Masterminds/semver/v3" - - cld_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations" - - "github.com/smartcontractkit/chainlink-sui/bindings/bind" - module_usdc_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/usdc_token_pool" - sui_ops "github.com/smartcontractkit/chainlink-sui/deployment/ops" -) - -// =================== Execute Ownership Transfer To MCMS Operations =================== // - -type ExecuteOwnershipTransferToMcmsUsdcTokenPoolInput struct { - UsdcTokenPoolPackageId string - TypeArgs []string - OwnerCapObjectId string - StateObjectId string - RegistryObjectId string - To string -} - -type ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects struct { - // No specific objects are returned from execute_ownership_transfer_to_mcms -} - -var executeOwnershipTransferToMcmsUsdcTokenPoolHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input ExecuteOwnershipTransferToMcmsUsdcTokenPoolInput) (output sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects], err error) { - contract, err := module_usdc_token_pool.NewUsdcTokenPool(input.UsdcTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{}, fmt.Errorf("failed to create UsdcTokenPool contract: %w", err) - } - - encodedCall, err := contract.Encoder().ExecuteOwnershipTransferToMcms( - input.TypeArgs, - bind.Object{Id: input.OwnerCapObjectId}, - bind.Object{Id: input.StateObjectId}, - bind.Object{Id: input.RegistryObjectId}, - input.To, - ) - if err != nil { - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{}, fmt.Errorf("failed to encode ExecuteOwnershipTransferToMcms call: %w", err) - } - call, err := sui_ops.ToTransactionCallWithTypeArgs(encodedCall, input.StateObjectId, input.TypeArgs) - if err != nil { - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{}, fmt.Errorf("failed to convert encoded call to TransactionCall: %w", err) - } - if deps.Signer == nil { - b.Logger.Infow("Skipping execution of ExecuteOwnershipTransferToMcms on UsdcTokenPool as per no Signer provided", "to", input.To) - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{ - Digest: "", - PackageId: input.UsdcTokenPoolPackageId, - Objects: ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects{}, - Call: call, - }, nil - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := contract.Bound().ExecuteTransaction( - b.GetContext(), - opts, - encodedCall, - ) - if err != nil { - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{}, fmt.Errorf("failed to execute ExecuteOwnershipTransferToMcms on UsdcTokenPool: %w", err) - } - - newOwner, err := contract.DevInspect().Owner(b.GetContext(), opts, input.TypeArgs, bind.Object{Id: input.StateObjectId}) - if err != nil { - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{}, fmt.Errorf("failed to get new owner for UsdcTokenPool: %w", err) - } - - if newOwner != input.To { - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{}, fmt.Errorf("ownership transfer to MCMS failed for UsdcTokenPool: expected new owner %s, got %s", input.To, newOwner) - } - - b.Logger.Infow("Ownership transfer to MCMS executed successfully for UsdcTokenPool", "to", input.To) - - return sui_ops.OpTxResult[ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects]{ - Digest: tx.Digest, - PackageId: input.UsdcTokenPoolPackageId, - Objects: ExecuteOwnershipTransferToMcmsUsdcTokenPoolObjects{}, - Call: call, - }, nil -} - -var ExecuteOwnershipTransferToMcmsUsdcTokenPoolOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip", "usdc_token_pool", "execute_ownership_transfer_to_mcms"), - semver.MustParse("0.1.0"), - "Executes ownership transfer to MCMS for the CCIP UsdcTokenPool", - executeOwnershipTransferToMcmsUsdcTokenPoolHandler, -) diff --git a/deployment/ops/ccip_usdc_token_pool/op_usdc_token_pool.go b/deployment/ops/ccip_usdc_token_pool/op_usdc_token_pool.go deleted file mode 100644 index 4b4bb542e..000000000 --- a/deployment/ops/ccip_usdc_token_pool/op_usdc_token_pool.go +++ /dev/null @@ -1,328 +0,0 @@ -package usdctokenpoolops - -import ( - "fmt" - - "github.com/Masterminds/semver/v3" - - cld_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations" - - "github.com/smartcontractkit/chainlink-sui/bindings/bind" - module_usdc_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/usdc_token_pool" - sui_ops "github.com/smartcontractkit/chainlink-sui/deployment/ops" -) - -// USDC Token Pool -- INITIALIZE -type USDCTokenPoolInitializeObjects struct { - StateObjectId string -} - -type USDCTokenPoolInitializeInput struct { - USDCTokenPoolPackageId string - OwnerCapObjectId string - CCIPObjectRefObjectId string - CCIPAdminProofObjectId string - CoinObjectTypeArg string - StateObjectId string - CoinMetadataObjectId string - LocalDomainIdentifier uint32 - TokenPoolPackageId string - TokenPoolAdministrator string -} - -var initUSDCTokenPoolHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input USDCTokenPoolInitializeInput) (output sui_ops.OpTxResult[USDCTokenPoolInitializeObjects], err error) { - contract, err := module_usdc_token_pool.NewUsdcTokenPool(input.USDCTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[USDCTokenPoolInitializeObjects]{}, fmt.Errorf("failed to create USDC token pool contract: %w", err) - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := contract.Initialize( - b.GetContext(), - opts, - []string{input.CoinObjectTypeArg}, - bind.Object{Id: input.OwnerCapObjectId}, - bind.Object{Id: input.CoinMetadataObjectId}, - input.LocalDomainIdentifier, - ) - if err != nil { - return sui_ops.OpTxResult[USDCTokenPoolInitializeObjects]{}, fmt.Errorf("failed to execute USDC token pool initialization: %w", err) - } - - stateObj, err := bind.FindObjectIdFromPublishTx(*tx, "usdc_token_pool", "USDCTokenPoolState") - if err != nil { - return sui_ops.OpTxResult[USDCTokenPoolInitializeObjects]{}, fmt.Errorf("failed to find object IDs in tx: %w", err) - } - - return sui_ops.OpTxResult[USDCTokenPoolInitializeObjects]{ - Digest: tx.Digest, - PackageId: input.USDCTokenPoolPackageId, - Objects: USDCTokenPoolInitializeObjects{ - StateObjectId: stateObj, - }, - }, nil -} - -var USDCTokenPoolInitializeOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip", "usdc_token_pool", "initialize"), - semver.MustParse("0.1.0"), - "Initializes the CCIP USDC Token Pool contract", - initUSDCTokenPoolHandler, -) - -// USDC Token Pool -- SET_DOMAINS -type NoObjects struct { -} - -type USDCTokenPoolSetDomainsInput struct { - USDCTokenPoolPackageId string - CoinObjectTypeArg string - StateObjectId string - OwnerCap string - RemoteChainSelectors []uint64 - RemoteDomainIdentifiers []uint32 - AllowedRemoteCallers [][]byte - Enableds []bool -} - -var setDomainsHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input USDCTokenPoolSetDomainsInput) (output sui_ops.OpTxResult[NoObjects], err error) { - contract, err := module_usdc_token_pool.NewUsdcTokenPool(input.USDCTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to create USDC token pool contract: %w", err) - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := contract.SetDomains( - b.GetContext(), - opts, - []string{input.CoinObjectTypeArg}, - bind.Object{Id: input.StateObjectId}, - bind.Object{Id: input.OwnerCap}, - input.RemoteChainSelectors, - input.RemoteDomainIdentifiers, - input.AllowedRemoteCallers, - input.Enableds, - ) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to execute set domains: %w", err) - } - - return sui_ops.OpTxResult[NoObjects]{ - Digest: tx.Digest, - PackageId: input.USDCTokenPoolPackageId, - }, nil -} - -var USDCTokenPoolSetDomainsOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip", "usdc_token_pool", "set_domains"), - semver.MustParse("0.1.0"), - "Sets domain configurations for the USDC Token Pool", - setDomainsHandler, -) - -// USDC Token Pool -- APPLY_CHAIN_UPDATES -type USDCTokenPoolApplyChainUpdatesInput struct { - USDCTokenPoolPackageId string - CoinObjectTypeArg string - StateObjectId string - OwnerCap string - RemoteChainSelectorsToRemove []uint64 - RemoteChainSelectorsToAdd []uint64 - RemotePoolAddressesToAdd [][]string - RemoteTokenAddressesToAdd []string -} - -var applyChainUpdatesHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input USDCTokenPoolApplyChainUpdatesInput) (output sui_ops.OpTxResult[NoObjects], err error) { - contract, err := module_usdc_token_pool.NewUsdcTokenPool(input.USDCTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to create USDC token pool contract: %w", err) - } - - // Convert string arrays to byte arrays for remote pool addresses - remotePoolAddresses := make([][][]byte, len(input.RemotePoolAddressesToAdd)) - for i, addresses := range input.RemotePoolAddressesToAdd { - remotePoolAddresses[i] = make([][]byte, len(addresses)) - for j, addr := range addresses { - remotePoolAddresses[i][j] = []byte(addr) - } - } - - // Convert string addresses to byte arrays for remote token addresses - remoteTokenAddresses := make([][]byte, len(input.RemoteTokenAddressesToAdd)) - for i, addr := range input.RemoteTokenAddressesToAdd { - remoteTokenAddresses[i] = []byte(addr) - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := contract.ApplyChainUpdates( - b.GetContext(), - opts, - []string{input.CoinObjectTypeArg}, - bind.Object{Id: input.StateObjectId}, - bind.Object{Id: input.OwnerCap}, - input.RemoteChainSelectorsToRemove, - input.RemoteChainSelectorsToAdd, - remotePoolAddresses, - remoteTokenAddresses, - ) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to execute apply chain updates: %w", err) - } - - return sui_ops.OpTxResult[NoObjects]{ - Digest: tx.Digest, - PackageId: input.USDCTokenPoolPackageId, - }, nil -} - -var USDCTokenPoolApplyChainUpdatesOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip", "usdc_token_pool", "apply_chain_updates"), - semver.MustParse("0.1.0"), - "Applies chain updates to the USDC Token Pool", - applyChainUpdatesHandler, -) - -// USDC Token Pool -- SET_CHAIN_RATE_LIMITER_CONFIGS -type USDCTokenPoolSetChainRateLimiterInput struct { - USDCTokenPoolPackageId string - CoinObjectTypeArg string - StateObjectId string - OwnerCap string - ClockObjectId string - RemoteChainSelectors []uint64 - OutboundIsEnableds []bool - OutboundCapacities []uint64 - OutboundRates []uint64 - InboundIsEnableds []bool - InboundCapacities []uint64 - InboundRates []uint64 -} - -var setChainRateLimiterHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input USDCTokenPoolSetChainRateLimiterInput) (output sui_ops.OpTxResult[NoObjects], err error) { - contract, err := module_usdc_token_pool.NewUsdcTokenPool(input.USDCTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to create USDC token pool contract: %w", err) - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := contract.SetChainRateLimiterConfigs( - b.GetContext(), - opts, - []string{input.CoinObjectTypeArg}, - bind.Object{Id: input.StateObjectId}, - bind.Object{Id: input.OwnerCap}, - bind.Object{Id: input.ClockObjectId}, - input.RemoteChainSelectors, - input.OutboundIsEnableds, - input.OutboundCapacities, - input.OutboundRates, - input.InboundIsEnableds, - input.InboundCapacities, - input.InboundRates, - ) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to execute set chain rate limiter configs: %w", err) - } - - return sui_ops.OpTxResult[NoObjects]{ - Digest: tx.Digest, - PackageId: input.USDCTokenPoolPackageId, - }, nil -} - -var USDCTokenPoolSetChainRateLimiterOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip", "usdc_token_pool", "set_chain_rate_limiter"), - semver.MustParse("0.1.0"), - "Sets chain rate limiter configurations for the USDC Token Pool", - setChainRateLimiterHandler, -) - -// USDC Token Pool -- SET_ALLOWLIST_ENABLED -type USDCTokenPoolSetAllowlistEnabledInput struct { - USDCTokenPoolPackageId string - CoinObjectTypeArg string - StateObjectId string - OwnerCap string - Enabled bool -} - -var setAllowlistEnabledHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input USDCTokenPoolSetAllowlistEnabledInput) (output sui_ops.OpTxResult[NoObjects], err error) { - contract, err := module_usdc_token_pool.NewUsdcTokenPool(input.USDCTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to create USDC token pool contract: %w", err) - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := contract.SetAllowlistEnabled( - b.GetContext(), - opts, - []string{input.CoinObjectTypeArg}, - bind.Object{Id: input.StateObjectId}, - bind.Object{Id: input.OwnerCap}, - input.Enabled, - ) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to execute set allowlist enabled: %w", err) - } - - return sui_ops.OpTxResult[NoObjects]{ - Digest: tx.Digest, - PackageId: input.USDCTokenPoolPackageId, - }, nil -} - -var USDCTokenPoolSetAllowlistEnabledOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip", "usdc_token_pool", "set_allowlist_enabled"), - semver.MustParse("0.1.0"), - "Sets allowlist enabled for the USDC Token Pool", - setAllowlistEnabledHandler, -) - -// USDC Token Pool -- APPLY_ALLOWLIST_UPDATES -type USDCTokenPoolApplyAllowlistUpdatesInput struct { - USDCTokenPoolPackageId string - CoinObjectTypeArg string - StateObjectId string - OwnerCap string - Removes []string - Adds []string -} - -var applyAllowlistUpdatesHandler = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input USDCTokenPoolApplyAllowlistUpdatesInput) (output sui_ops.OpTxResult[NoObjects], err error) { - contract, err := module_usdc_token_pool.NewUsdcTokenPool(input.USDCTokenPoolPackageId, deps.Client) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to create USDC token pool contract: %w", err) - } - - opts := deps.GetCallOpts() - opts.Signer = deps.Signer - tx, err := contract.ApplyAllowlistUpdates( - b.GetContext(), - opts, - []string{input.CoinObjectTypeArg}, - bind.Object{Id: input.StateObjectId}, - bind.Object{Id: input.OwnerCap}, - input.Removes, - input.Adds, - ) - if err != nil { - return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to execute apply allowlist updates: %w", err) - } - - return sui_ops.OpTxResult[NoObjects]{ - Digest: tx.Digest, - PackageId: input.USDCTokenPoolPackageId, - }, nil -} - -var USDCTokenPoolApplyAllowlistUpdatesOp = cld_ops.NewOperation( - sui_ops.NewSuiOperationName("ccip", "usdc_token_pool", "apply_allowlist_updates"), - semver.MustParse("0.1.0"), - "Applies allowlist updates to the USDC Token Pool", - applyAllowlistUpdatesHandler, -) diff --git a/deployment/ops/ccip_usdc_token_pool/seq_deploy_and_init.go b/deployment/ops/ccip_usdc_token_pool/seq_deploy_and_init.go deleted file mode 100644 index 6c17968d5..000000000 --- a/deployment/ops/ccip_usdc_token_pool/seq_deploy_and_init.go +++ /dev/null @@ -1,155 +0,0 @@ -package usdctokenpoolops - -import ( - "github.com/Masterminds/semver/v3" - - cld_ops "github.com/smartcontractkit/chainlink-deployments-framework/operations" - - sui_ops "github.com/smartcontractkit/chainlink-sui/deployment/ops" -) - -type DeployUSDCTokenPoolObjects struct { - OwnerCapObjectId string - StateObjectId string -} - -type DeployUSDCTokenPoolOutput struct { - CCIPPackageId string - Objects DeployUSDCTokenPoolObjects -} - -type DeployAndInitUSDCTokenPoolInput struct { - USDCTokenPoolDeployInput - // init - CoinObjectTypeArg string - CCIPObjectRefObjectId string - CCIPAdminProofObjectId string - CoinMetadataObjectId string - LocalDomainIdentifier uint32 - TokenPoolPackageId string - TokenPoolAdministrator string - // set domains - RemoteChainSelectors []uint64 - RemoteDomainIdentifiers []uint32 - AllowedRemoteCallers [][]byte - DomainsEnableds []bool - // apply chain updates - RemoteChainSelectorsToRemove []uint64 - RemoteChainSelectorsToAdd []uint64 - RemotePoolAddressesToAdd [][]string - RemoteTokenAddressesToAdd []string - // set chain rate limiter configs - RateLimiterRemoteChainSelectors []uint64 - OutboundIsEnableds []bool - OutboundCapacities []uint64 - OutboundRates []uint64 - InboundIsEnableds []bool - InboundCapacities []uint64 - InboundRates []uint64 - ClockObjectId string -} - -var DeployAndInitUSDCTokenPoolSequence = cld_ops.NewSequence( - "sui-deploy-usdc-token-pool-seq", - semver.MustParse("0.1.0"), - "Deploys and sets initial USDC token pool configuration", - func(env cld_ops.Bundle, deps sui_ops.OpTxDeps, input DeployAndInitUSDCTokenPoolInput) (DeployUSDCTokenPoolOutput, error) { - deployReport, err := cld_ops.ExecuteOperation(env, DeployCCIPUSDCTokenPoolOp, deps, input.USDCTokenPoolDeployInput) - if err != nil { - return DeployUSDCTokenPoolOutput{}, err - } - - initReport, err := cld_ops.ExecuteOperation( - env, - USDCTokenPoolInitializeOp, - deps, - USDCTokenPoolInitializeInput{ - USDCTokenPoolPackageId: deployReport.Output.PackageId, - OwnerCapObjectId: deployReport.Output.Objects.OwnerCapObjectId, - CCIPObjectRefObjectId: input.CCIPObjectRefObjectId, - CCIPAdminProofObjectId: input.CCIPAdminProofObjectId, - CoinObjectTypeArg: input.CoinObjectTypeArg, - StateObjectId: input.CCIPObjectRefObjectId, - CoinMetadataObjectId: input.CoinMetadataObjectId, - LocalDomainIdentifier: input.LocalDomainIdentifier, - TokenPoolPackageId: input.TokenPoolPackageId, - TokenPoolAdministrator: input.TokenPoolAdministrator, - }, - ) - if err != nil { - return DeployUSDCTokenPoolOutput{}, err - } - - // Set domains configuration - _, err = cld_ops.ExecuteOperation( - env, - USDCTokenPoolSetDomainsOp, - deps, - USDCTokenPoolSetDomainsInput{ - USDCTokenPoolPackageId: deployReport.Output.PackageId, - CoinObjectTypeArg: input.CoinObjectTypeArg, - StateObjectId: initReport.Output.Objects.StateObjectId, - OwnerCap: deployReport.Output.Objects.OwnerCapObjectId, - RemoteChainSelectors: input.RemoteChainSelectors, - RemoteDomainIdentifiers: input.RemoteDomainIdentifiers, - AllowedRemoteCallers: input.AllowedRemoteCallers, - Enableds: input.DomainsEnableds, - }, - ) - if err != nil { - return DeployUSDCTokenPoolOutput{}, err - } - - // Apply chain updates - _, err = cld_ops.ExecuteOperation( - env, - USDCTokenPoolApplyChainUpdatesOp, - deps, - USDCTokenPoolApplyChainUpdatesInput{ - USDCTokenPoolPackageId: deployReport.Output.PackageId, - CoinObjectTypeArg: input.CoinObjectTypeArg, - StateObjectId: initReport.Output.Objects.StateObjectId, - OwnerCap: deployReport.Output.Objects.OwnerCapObjectId, - RemoteChainSelectorsToRemove: input.RemoteChainSelectorsToRemove, - RemoteChainSelectorsToAdd: input.RemoteChainSelectorsToAdd, - RemotePoolAddressesToAdd: input.RemotePoolAddressesToAdd, - RemoteTokenAddressesToAdd: input.RemoteTokenAddressesToAdd, - }, - ) - if err != nil { - return DeployUSDCTokenPoolOutput{}, err - } - - // Set chain rate limiter configurations - _, err = cld_ops.ExecuteOperation( - env, - USDCTokenPoolSetChainRateLimiterOp, - deps, - USDCTokenPoolSetChainRateLimiterInput{ - USDCTokenPoolPackageId: deployReport.Output.PackageId, - CoinObjectTypeArg: input.CoinObjectTypeArg, - StateObjectId: initReport.Output.Objects.StateObjectId, - OwnerCap: deployReport.Output.Objects.OwnerCapObjectId, - ClockObjectId: input.ClockObjectId, - RemoteChainSelectors: input.RateLimiterRemoteChainSelectors, - OutboundIsEnableds: input.OutboundIsEnableds, - OutboundCapacities: input.OutboundCapacities, - OutboundRates: input.OutboundRates, - InboundIsEnableds: input.InboundIsEnableds, - InboundCapacities: input.InboundCapacities, - InboundRates: input.InboundRates, - }, - ) - if err != nil { - return DeployUSDCTokenPoolOutput{}, err - } - - return DeployUSDCTokenPoolOutput{ - CCIPPackageId: deployReport.Output.PackageId, - Objects: DeployUSDCTokenPoolObjects{ - OwnerCapObjectId: deployReport.Output.Objects.OwnerCapObjectId, - StateObjectId: initReport.Output.Objects.StateObjectId, - }, - }, nil - }, -) diff --git a/deployment/ops/ownership/seq_execute_ownership_transfer_to_mcms.go b/deployment/ops/ownership/seq_execute_ownership_transfer_to_mcms.go index 0b0a1ea85..5ad8e2bf5 100644 --- a/deployment/ops/ownership/seq_execute_ownership_transfer_to_mcms.go +++ b/deployment/ops/ownership/seq_execute_ownership_transfer_to_mcms.go @@ -15,7 +15,6 @@ import ( offrampops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_offramp" onrampops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_onramp" routerops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_router" - usdctokenpoolops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip_usdc_token_pool" managedtokenops "github.com/smartcontractkit/chainlink-sui/deployment/ops/managed_token" mcmsops "github.com/smartcontractkit/chainlink-sui/deployment/ops/mcms" ) @@ -31,7 +30,6 @@ const ( ContractTypeManagedToken ContractType = "managed_token" ContractTypeBurnMintTokenPool ContractType = "burn_mint_token_pool" ContractTypeLockReleaseTokenPool ContractType = "lock_release_token_pool" - ContractTypeUsdcTokenPool ContractType = "usdc_token_pool" ContractTypeManagedTokenPool ContractType = "managed_token_pool" ContractTypeMCMS ContractType = "mcms" ) @@ -46,7 +44,6 @@ type ExecuteOwnershipTransferToMcmsSeqInput struct { ManagedToken *managedtokenops.ExecuteOwnershipTransferToMcmsManagedTokenInput `json:"managed_token,omitempty"` BurnMintTokenPool *burnminttokenpoolops.ExecuteOwnershipTransferToMcmsBurnMintTokenPoolInput `json:"burn_mint_token_pool,omitempty"` LockReleaseTokenPool *lockreleasetokenpoolops.ExecuteOwnershipTransferToMcmsLockReleaseTokenPoolInput `json:"lock_release_token_pool,omitempty"` - UsdcTokenPool *usdctokenpoolops.ExecuteOwnershipTransferToMcmsUsdcTokenPoolInput `json:"usdc_token_pool,omitempty"` ManagedTokenPool *managedtokenpoolops.ExecuteOwnershipTransferToMcmsManagedTokenPoolInput `json:"managed_token_pool,omitempty"` } @@ -165,19 +162,6 @@ var ExecuteOwnershipTransferToMcmsSequence = cld_ops.NewSequence( "digest", report.Output.Digest) } - // Execute UsdcTokenPool ownership transfer if provided - if input.UsdcTokenPool != nil { - report, err := cld_ops.ExecuteOperation(env, usdctokenpoolops.ExecuteOwnershipTransferToMcmsUsdcTokenPoolOp, deps, *input.UsdcTokenPool) - if err != nil { - return ExecuteOwnershipTransferToMcmsSeqOutput{}, fmt.Errorf("failed to execute ownership transfer for UsdcTokenPool: %w", err) - } - results[ContractTypeUsdcTokenPool] = report.Output.Digest - env.Logger.Infow("Successfully executed ownership transfer to MCMS for UsdcTokenPool", - "packageId", input.UsdcTokenPool.UsdcTokenPoolPackageId, - "to", input.UsdcTokenPool.To, - "digest", report.Output.Digest) - } - // Execute ManagedTokenPool ownership transfer if provided if input.ManagedTokenPool != nil { report, err := cld_ops.ExecuteOperation(env, managedtokenpoolops.ExecuteOwnershipTransferToMcmsManagedTokenPoolOp, deps, *input.ManagedTokenPool) diff --git a/deployment/view/token_pool.go b/deployment/view/token_pool.go index ed8b3baaa..2eef34e7c 100644 --- a/deployment/view/token_pool.go +++ b/deployment/view/token_pool.go @@ -12,14 +12,12 @@ import ( module_burn_mint_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/burn_mint_token_pool" module_lock_release_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/lock_release_token_pool" module_managed_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/managed_token_pool" - module_usdc_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/usdc_token_pool" ) type TokenBucketWrapper interface { module_burn_mint_token_pool.TokenBucketWrapper | module_lock_release_token_pool.TokenBucketWrapper | - module_managed_token_pool.TokenBucketWrapper | - module_usdc_token_pool.TokenBucketWrapper + module_managed_token_pool.TokenBucketWrapper } // ITokenPoolDevInspect defines the common DevInspect methods across pool types diff --git a/relayer/common/pointer_config.go b/relayer/common/pointer_config.go index c3d71f2d3..40f7cd4ce 100644 --- a/relayer/common/pointer_config.go +++ b/relayer/common/pointer_config.go @@ -63,13 +63,6 @@ var PointerConfigs = map[string][]PointerConfig{ ParentFieldName: "managed_token_pool_object_id", }, }, - "usdc_token_pool": { - { - Module: "usdc_token_pool", - Pointer: "USDCTokenPoolStatePointer", - ParentFieldName: "usdc_token_pool_object_id", - }, - }, "lock_release_token_pool": { { Module: "lock_release_token_pool", @@ -94,7 +87,6 @@ var StateObjectNameByModule = map[string]string{ "burn_mint_token_pool": "BurnMintTokenPoolState", "lock_release_token_pool": "LockReleaseTokenPoolState", "managed_token_pool": "ManagedTokenPoolState", - "usdc_token_pool": "USDCTokenPoolState", "counter": "Counter", } diff --git a/relayer/common/utils.go b/relayer/common/utils.go index b64d1196d..21c4abe09 100644 --- a/relayer/common/utils.go +++ b/relayer/common/utils.go @@ -127,8 +127,6 @@ func GetModuleForContract(contractName string) string { return "burn_mint_token_pool" case "ManagedTokenPool", "managed_token_pool", "managedtokenpool": return "managed_token_pool" - case "USDCTokenPool", "usdc_token_pool", "usdctokenpool": - return "usdc_token_pool" case "LockReleaseTokenPool", "lock_release_token_pool", "lockreleasetokenpool": return "lock_release_token_pool" default: diff --git a/relayer/testutils/onramp.go b/relayer/testutils/onramp.go index b7b0c692a..21c867e0f 100644 --- a/relayer/testutils/onramp.go +++ b/relayer/testutils/onramp.go @@ -20,7 +20,6 @@ const ( TokenPoolTypeBurnMint TokenPoolType = "burn_mint_token_pool" TokenPoolTypeManaged TokenPoolType = "managed_token_pool" TokenPoolTypeBase TokenPoolType = "token_pool" - TokenPoolTypeUSDC TokenPoolType = "usdc_token_pool" ZeroAddress string = "0x0000000000000000000000000000000000000000000000000000000000000000" ) @@ -325,9 +324,6 @@ func ConfigureOnRampChainWriter( case TokenPoolTypeManaged: managedCommand := getManagedLockOrBurnCommand(tokenPool.TokenPoolPackageId, ethTokenType) tokenTransferCommands = append(tokenTransferCommands, managedCommand) - case TokenPoolTypeUSDC: - // TODO: Add USDC token pool command when available - return cwConfig.ChainWriterConfig{}, fmt.Errorf("usdc_token_pool not yet implemented") default: return cwConfig.ChainWriterConfig{}, fmt.Errorf("unknown token pool type: %s", tokenPool.TokenPoolType) } diff --git a/scripts/generate_bindings.sh b/scripts/generate_bindings.sh index d339a10ad..47768fb42 100755 --- a/scripts/generate_bindings.sh +++ b/scripts/generate_bindings.sh @@ -48,9 +48,6 @@ go run bindgen/main.go --moveConfig ./contracts/ccip/ccip_token_pools/burn_mint_ # CCIP - Managed Token Pool go run bindgen/main.go --moveConfig ./contracts/ccip/ccip_token_pools/managed_token_pool --input ./contracts/ccip/ccip_token_pools/managed_token_pool/sources/managed_token_pool.move --output ./bindings/generated/ccip/ccip_token_pools/managed_token_pool -# CCIP - USDCTokenPool -go run bindgen/main.go --moveConfig ./contracts/ccip/ccip_token_pools/usdc_token_pool --input ./contracts/ccip/ccip_token_pools/usdc_token_pool/sources/usdc_token_pool.move --output ./bindings/generated/ccip/ccip_token_pools/usdc_token_pool - # CCIP Router go run bindgen/main.go --moveConfig ./contracts/ccip/ccip_router --input ./contracts/ccip/ccip_router/sources/router.move --output ./bindings/generated/ccip/ccip_router/ From 6f44b8ad00c69058df516d547877728c53f8d2f3 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 18 Jun 2026 08:43:43 -0400 Subject: [PATCH 2/4] fix --- .github/workflows/pull-request-develop.yml | 4 +++ go.md | 29 ++++++++++++++++++---- go.mod | 4 +-- go.sum | 4 +++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pull-request-develop.yml b/.github/workflows/pull-request-develop.yml index d487981f3..0676d47b4 100644 --- a/.github/workflows/pull-request-develop.yml +++ b/.github/workflows/pull-request-develop.yml @@ -174,6 +174,10 @@ jobs: - name: Setup Nix uses: smartcontractkit/.github/actions/setup-nix@01d931b0455a754d12e7143cc54a5a3521a8f6f6 # setup-nix@0.3.2 + - name: Install latest gomods and modgraph + run: | + nix develop -c go get -tool github.com/jmank88/gomods@latest github.com/jmank88/modgraph@latest + - name: Ensure modules are tidy run: | nix develop -c go tool gomods tidy diff --git a/go.md b/go.md index 3e9180cc6..18b2e3fb4 100644 --- a/go.md +++ b/go.md @@ -81,7 +81,25 @@ flowchart LR click chain-selectors href "https://github.com/smartcontractkit/chain-selectors" chainlink-aptos --> chainlink-common click chainlink-aptos href "https://github.com/smartcontractkit/chainlink-aptos" - chainlink-canton + chainlink-canton --> ccip-contract-examples/chains/evm + chainlink-canton --> chainlink-ccip/deployment + chainlink-canton --> chainlink-ccv + chainlink-canton --> chainlink-ccv/build/devenv + chainlink-canton --> chainlink-ccv/deployment + chainlink-canton --> chainlink-common/keystore + chainlink-canton --> chainlink-framework/multinode + chainlink-canton --> chainlink-protos/chainlink-ccv/committee-verifier + chainlink-canton --> chainlink-protos/chainlink-ccv/heartbeat + chainlink-canton --> chainlink-protos/chainlink-ccv/message-discovery + chainlink-canton --> chainlink-protos/chainlink-ccv/message-rules + chainlink-canton --> chainlink-protos/chainlink-ccv/verifier + chainlink-canton --> chainlink-protos/orchestrator + chainlink-canton --> chainlink-protos/svr + chainlink-canton --> chainlink-testing-framework/lib/grafana + chainlink-canton --> chainlink-testing-framework/wasp + chainlink-canton --> chainlink/deployment + chainlink-canton --> chainlink/v2 + chainlink-canton --> wsrpc click chainlink-canton href "https://github.com/smartcontractkit/chainlink-canton" chainlink-ccip --> chainlink-common chainlink-ccip --> chainlink-protos/rmn/v1.6/go @@ -96,9 +114,6 @@ flowchart LR chainlink-ccip/deployment --> chainlink-evm chainlink-ccip/deployment --> chainlink-evm/gethwrappers chainlink-ccip/deployment --> chainlink-framework/chains - chainlink-ccip/deployment --> chainlink-protos/op-catalog - chainlink-ccip/deployment --> chainlink-testing-framework/seth - chainlink-ccip/deployment --> mcms click chainlink-ccip/deployment href "https://github.com/smartcontractkit/chainlink-ccip" chainlink-ccv click chainlink-ccv href "https://github.com/smartcontractkit/chainlink-ccv" @@ -125,7 +140,11 @@ flowchart LR click chainlink-common/pkg/monitoring href "https://github.com/smartcontractkit/chainlink-common" chainlink-common/pkg/values click chainlink-common/pkg/values href "https://github.com/smartcontractkit/chainlink-common" - chainlink-deployments-framework + chainlink-deployments-framework --> ccip-owner-contracts + chainlink-deployments-framework --> chainlink-ccip/chains/evm + chainlink-deployments-framework --> chainlink-protos/op-catalog + chainlink-deployments-framework --> chainlink-testing-framework/seth + chainlink-deployments-framework --> mcms click chainlink-deployments-framework href "https://github.com/smartcontractkit/chainlink-deployments-framework" chainlink-evm click chainlink-evm href "https://github.com/smartcontractkit/chainlink-evm" diff --git a/go.mod b/go.mod index b9a59128e..7a154b86e 100644 --- a/go.mod +++ b/go.mod @@ -84,8 +84,8 @@ require ( github.com/jackc/pgx/v5 v5.9.2 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/copier v0.4.0 // indirect - github.com/jmank88/gomods v0.1.6 // indirect - github.com/jmank88/modgraph v0.1.1 // indirect + github.com/jmank88/gomods v0.1.7 // indirect + github.com/jmank88/modgraph v0.1.4 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index f4acbd529..e7b5b1be5 100644 --- a/go.sum +++ b/go.sum @@ -195,8 +195,12 @@ github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmank88/gomods v0.1.6 h1:HNHM9x2QPdF7R72pm83MZpori5AlPiXiukTdLqrUJYE= github.com/jmank88/gomods v0.1.6/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= +github.com/jmank88/gomods v0.1.7 h1:NG0ht+Z2wBO1EX6jn8cHa4iLQVqCKwmw426F4T6SBDo= +github.com/jmank88/gomods v0.1.7/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= github.com/jmank88/modgraph v0.1.1 h1:Lz9XlGbsb//zsHRDPq+fbU28NaSgUwUY/1PjbOMLnew= github.com/jmank88/modgraph v0.1.1/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= +github.com/jmank88/modgraph v0.1.4 h1:eNLt3l47NoyySHkgmcQeG/s9d5I2B5S7LQHpvSBU7Ks= +github.com/jmank88/modgraph v0.1.4/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= From a9aa754bafa7911228f5718034c0f7934a10057a Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 18 Jun 2026 08:48:08 -0400 Subject: [PATCH 3/4] mod --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index e7b5b1be5..9b2e474ca 100644 --- a/go.sum +++ b/go.sum @@ -193,12 +193,8 @@ github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5Xum github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= -github.com/jmank88/gomods v0.1.6 h1:HNHM9x2QPdF7R72pm83MZpori5AlPiXiukTdLqrUJYE= -github.com/jmank88/gomods v0.1.6/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= github.com/jmank88/gomods v0.1.7 h1:NG0ht+Z2wBO1EX6jn8cHa4iLQVqCKwmw426F4T6SBDo= github.com/jmank88/gomods v0.1.7/go.mod h1:mFFORqytinYpCj2zbyAqAka1R8LZOG9N34uvMzKVSyA= -github.com/jmank88/modgraph v0.1.1 h1:Lz9XlGbsb//zsHRDPq+fbU28NaSgUwUY/1PjbOMLnew= -github.com/jmank88/modgraph v0.1.1/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= github.com/jmank88/modgraph v0.1.4 h1:eNLt3l47NoyySHkgmcQeG/s9d5I2B5S7LQHpvSBU7Ks= github.com/jmank88/modgraph v0.1.4/go.mod h1:wECy/lrullAgq5p3K1CK0KvLlnIkxTc1V2u6p0bdT4s= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= From 900137a127aa6cdfbe414943e88e2f09a5629965 Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Thu, 18 Jun 2026 08:59:16 -0400 Subject: [PATCH 4/4] format --- bindings/generated/function_info.go | 122 ++++++++++++++-------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/bindings/generated/function_info.go b/bindings/generated/function_info.go index c1f3561b5..c8c395f0e 100644 --- a/bindings/generated/function_info.go +++ b/bindings/generated/function_info.go @@ -3,67 +3,67 @@ package generated import ( - module_fee_quoter "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/fee_quoter" - module_nonce_manager "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/nonce_manager" - module_offramp_state_helper "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/offramp_state_helper" - module_receiver_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/receiver_registry" - module_rmn_remote "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/rmn_remote" - module_state_object "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/state_object" - module_token_admin_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/token_admin_registry" - module_upgrade_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/upgrade_registry" - module_ccip_burn_mint_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_burn_mint_token/ccip_burn_mint_token" - module_dummy_receiver "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_dummy_receiver/ccip_dummy_receiver" - module_offramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_offramp/offramp" - module_onramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/onramp" - module_ownable "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/ownable" - module_router "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_router" - module_burn_mint_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/burn_mint_token_pool" - module_lock_release_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/lock_release_token_pool" - module_managed_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/managed_token_pool" - module_managed_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token/managed_token" - module_faucet "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token_faucet/managed_token_faucet" - module_mock_eth_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_eth_token/mock_eth_token" - module_mock_link_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_link_token/mock_link_token" - module_link "github.com/smartcontractkit/chainlink-sui/bindings/generated/link/link" - module_mcms "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms" - module_mcms_account "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_account" - module_mcms_deployer "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_deployer" - module_mcms_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_registry" - module_mcms_user "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_user" - module_complex "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/complex" - module_counter "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/counter" - module_generics "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/generics" + module_fee_quoter "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/fee_quoter" + module_nonce_manager "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/nonce_manager" + module_offramp_state_helper "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/offramp_state_helper" + module_receiver_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/receiver_registry" + module_rmn_remote "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/rmn_remote" + module_state_object "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/state_object" + module_token_admin_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/token_admin_registry" + module_upgrade_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip/upgrade_registry" + module_ccip_burn_mint_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_burn_mint_token/ccip_burn_mint_token" + module_dummy_receiver "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_dummy_receiver/ccip_dummy_receiver" + module_offramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_offramp/offramp" + module_onramp "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/onramp" + module_ownable "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_onramp/ownable" + module_router "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_router" + module_burn_mint_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/burn_mint_token_pool" + module_lock_release_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/lock_release_token_pool" + module_managed_token_pool "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/ccip_token_pools/managed_token_pool" + module_managed_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token/managed_token" + module_faucet "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/managed_token_faucet/managed_token_faucet" + module_mock_eth_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_eth_token/mock_eth_token" + module_mock_link_token "github.com/smartcontractkit/chainlink-sui/bindings/generated/ccip/mock_link_token/mock_link_token" + module_link "github.com/smartcontractkit/chainlink-sui/bindings/generated/link/link" + module_mcms "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms" + module_mcms_account "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_account" + module_mcms_deployer "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_deployer" + module_mcms_registry "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_registry" + module_mcms_user "github.com/smartcontractkit/chainlink-sui/bindings/generated/mcms/mcms_user" + module_complex "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/complex" + module_counter "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/counter" + module_generics "github.com/smartcontractkit/chainlink-sui/bindings/generated/test/generics" ) var FunctionInfoByModule = map[string]string{ - "fee_quoter": module_fee_quoter.FunctionInfo, - "nonce_manager": module_nonce_manager.FunctionInfo, - "offramp_state_helper": module_offramp_state_helper.FunctionInfo, - "receiver_registry": module_receiver_registry.FunctionInfo, - "rmn_remote": module_rmn_remote.FunctionInfo, - "state_object": module_state_object.FunctionInfo, - "token_admin_registry": module_token_admin_registry.FunctionInfo, - "upgrade_registry": module_upgrade_registry.FunctionInfo, - "ccip_burn_mint_token": module_ccip_burn_mint_token.FunctionInfo, - "dummy_receiver": module_dummy_receiver.FunctionInfo, - "offramp": module_offramp.FunctionInfo, - "onramp": module_onramp.FunctionInfo, - "ownable": module_ownable.FunctionInfo, - "router": module_router.FunctionInfo, - "burn_mint_token_pool": module_burn_mint_token_pool.FunctionInfo, - "lock_release_token_pool": module_lock_release_token_pool.FunctionInfo, - "managed_token_pool": module_managed_token_pool.FunctionInfo, - "managed_token": module_managed_token.FunctionInfo, - "faucet": module_faucet.FunctionInfo, - "mock_eth_token": module_mock_eth_token.FunctionInfo, - "mock_link_token": module_mock_link_token.FunctionInfo, - "link": module_link.FunctionInfo, - "mcms": module_mcms.FunctionInfo, - "mcms_account": module_mcms_account.FunctionInfo, - "mcms_deployer": module_mcms_deployer.FunctionInfo, - "mcms_registry": module_mcms_registry.FunctionInfo, - "mcms_user": module_mcms_user.FunctionInfo, - "complex": module_complex.FunctionInfo, - "counter": module_counter.FunctionInfo, - "generics": module_generics.FunctionInfo, -} + "fee_quoter": module_fee_quoter.FunctionInfo, + "nonce_manager": module_nonce_manager.FunctionInfo, + "offramp_state_helper": module_offramp_state_helper.FunctionInfo, + "receiver_registry": module_receiver_registry.FunctionInfo, + "rmn_remote": module_rmn_remote.FunctionInfo, + "state_object": module_state_object.FunctionInfo, + "token_admin_registry": module_token_admin_registry.FunctionInfo, + "upgrade_registry": module_upgrade_registry.FunctionInfo, + "ccip_burn_mint_token": module_ccip_burn_mint_token.FunctionInfo, + "dummy_receiver": module_dummy_receiver.FunctionInfo, + "offramp": module_offramp.FunctionInfo, + "onramp": module_onramp.FunctionInfo, + "ownable": module_ownable.FunctionInfo, + "router": module_router.FunctionInfo, + "burn_mint_token_pool": module_burn_mint_token_pool.FunctionInfo, + "lock_release_token_pool": module_lock_release_token_pool.FunctionInfo, + "managed_token_pool": module_managed_token_pool.FunctionInfo, + "managed_token": module_managed_token.FunctionInfo, + "faucet": module_faucet.FunctionInfo, + "mock_eth_token": module_mock_eth_token.FunctionInfo, + "mock_link_token": module_mock_link_token.FunctionInfo, + "link": module_link.FunctionInfo, + "mcms": module_mcms.FunctionInfo, + "mcms_account": module_mcms_account.FunctionInfo, + "mcms_deployer": module_mcms_deployer.FunctionInfo, + "mcms_registry": module_mcms_registry.FunctionInfo, + "mcms_user": module_mcms_user.FunctionInfo, + "complex": module_complex.FunctionInfo, + "counter": module_counter.FunctionInfo, + "generics": module_generics.FunctionInfo, +} \ No newline at end of file