From e09004e816d8e477e25bcb6d7198a67fc9c10fb3 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Mon, 2 Sep 2024 00:30:42 -0400 Subject: [PATCH 01/22] feat: add NFT bridge --- contracts/bridge/NFT/NFTBase.sol | 341 ++++++++++++++++++++++ contracts/bridge/NFT/NFTController.sol | 128 ++++++++ contracts/bridge/NFT/NFTVault.sol | 138 +++++++++ contracts/common/Constants.sol | 5 + contracts/common/NFTStructs.sol | 36 +++ contracts/interfaces/IMintableERC1155.sol | 8 + contracts/interfaces/IMintableERC721.sol | 8 + contracts/interfaces/INFTBridge.sol | 21 ++ contracts/interfaces/INFTHook.sol | 67 +++++ 9 files changed, 752 insertions(+) create mode 100644 contracts/bridge/NFT/NFTBase.sol create mode 100644 contracts/bridge/NFT/NFTController.sol create mode 100644 contracts/bridge/NFT/NFTVault.sol create mode 100644 contracts/common/NFTStructs.sol create mode 100644 contracts/interfaces/IMintableERC1155.sol create mode 100644 contracts/interfaces/IMintableERC721.sol create mode 100644 contracts/interfaces/INFTBridge.sol create mode 100644 contracts/interfaces/INFTHook.sol diff --git a/contracts/bridge/NFT/NFTBase.sol b/contracts/bridge/NFT/NFTBase.sol new file mode 100644 index 00000000..34f6fd98 --- /dev/null +++ b/contracts/bridge/NFT/NFTBase.sol @@ -0,0 +1,341 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import "solmate/utils/ReentrancyGuard.sol"; +import "solmate/tokens/ERC721.sol"; +import "solmate/tokens/ERC1155.sol"; +import {IConnector} from "../../interfaces/IConnector.sol"; +import "../../interfaces/INFTHook.sol"; +import "../../interfaces/INFTBridge.sol"; +import "../../common/Errors.sol"; +import "../../common/Constants.sol"; +import "../../utils/AccessControl.sol"; + +abstract contract NFTBase is ReentrancyGuard, INFTBridge, AccessControl { + address public immutable token; + bytes32 public bridgeType; + INFTHook public hook__; + // message identifier => cache + mapping(bytes32 => bytes) public identifierCache; + + // connector => cache + mapping(address => bytes) public connectorCache; + + mapping(address => bool) public validConnectors; + + event ConnectorStatusUpdated(address connector, bool status); + + event HookUpdated(address newHook); + + event BridgingTokens( + address connector, + address sender, + address receiver, + uint256 tokenId, + uint256 amount, + bytes32 messageId + ); + event TokensBridged( + address connecter, + address receiver, + uint256 tokenId, + uint256 amount, + bytes32 messageId + ); + + constructor(address token_) AccessControl(msg.sender) { + if (token_ != ETH_ADDRESS && token_.code.length == 0) + revert InvalidTokenContract(); + token = token_; + } + + /** + * @notice this function is used to update hook + * @dev it can only be updated by owner + * @dev should be carefully migrated as it can risk user funds + * @param hook_ new hook address + */ + function updateHook( + address hook_, + bool approve_ + ) external virtual onlyOwner { + // remove the approval from the old hook + if (bridgeType == ERC721_VAULT) { + if (ERC721(token).isApprovedForAll(address(this), address(hook__))) { + ERC721(token).setApprovalForAll(address(hook__), false); + } + if (approve_) { + ERC721(token).setApprovalForAll(hook_, approve_); + } + } else { + if (ERC1155(token).isApprovedForAll(address(this), address(hook__))) { + ERC1155(token).setApprovalForAll(address(hook__), false); + } + if (approve_) { + ERC1155(token).setApprovalForAll(hook_, approve_); + } + } + hook__ = INFTHook(hook_); + + emit HookUpdated(hook_); + } + + function updateConnectorStatus( + address[] calldata connectors, + bool[] calldata statuses + ) external onlyOwner { + uint256 length = connectors.length; + for (uint256 i; i < length; i++) { + validConnectors[connectors[i]] = statuses[i]; + emit ConnectorStatusUpdated(connectors[i], statuses[i]); + } + } + + /** + * @notice Executes pre-bridge operations before initiating a token bridge transfer. + * @dev This internal function is called before initiating a token bridge transfer. + * It validates the receiver address and the connector, and if a pre-hook contract is defined, + * it executes the source pre-hook call. + * @param connector_ The address of the connector responsible for the transfer. + * @param transferInfo_ Information about the transfer. + * @return transferInfo Information about the transfer after pre-bridge operations. + * @return postHookData Data returned from the pre-hook call. + * @dev Reverts with `ZeroAddressReceiver` if the receiver address is zero. + * Reverts with `InvalidConnector` if the connector address is not valid. + */ + function _beforeBridge( + address connector_, + NFTTransferInfo memory transferInfo_ + ) + internal + returns (NFTTransferInfo memory transferInfo, bytes memory postHookData) + { + if (transferInfo_.receiver == address(0)) revert ZeroAddressReceiver(); + if (!validConnectors[connector_]) revert InvalidConnector(); + + if (address(hook__) != address(0)) { + (transferInfo, postHookData) = hook__.srcPreHookCall( + SrcPreHookNFTCallParams(connector_, msg.sender, transferInfo_) + ); + } else { + transferInfo = transferInfo_; + } + } + + /** + * @notice Executes post-bridge operations after completing a token bridge transfer. + * @dev This internal function is called after completing a token bridge transfer. + * It executes the source post-hook call if a hook contract is defined, calculates fees, + * calls the outbound function of the connector, and emits an event for tokens withdrawn. + * @param msgGasLimit_ The gas limit for the outbound call. + * @param connector_ The address of the connector responsible for the transfer. + * @param options_ Additional options for the outbound call. + * @param postHookData_ Data returned from the source post-hook call. + * @param transferInfo_ Information about the transfer. + * @dev Reverts with `MessageIdMisMatched` if the returned message ID does not match the expected message ID. + */ + function _afterBridge( + uint256 msgGasLimit_, + address connector_, + bytes memory options_, + bytes memory postHookData_, + NFTTransferInfo memory transferInfo_ + ) internal { + NFTTransferInfo memory transferInfo = transferInfo_; + if (address(hook__) != address(0)) { + transferInfo = hook__.srcPostHookCall( + SrcPostHookNFTCallParams( + connector_, + options_, + postHookData_, + transferInfo_ + ) + ); + } + + uint256 fees = msg.value; + bytes32 messageId = IConnector(connector_).getMessageId(); + bytes32 returnedMessageId = IConnector(connector_).outbound{ + value: fees + }( + msgGasLimit_, + abi.encode( + transferInfo.receiver, + transferInfo.tokenId, + transferInfo.amount, + messageId, + transferInfo.extraData + ), + options_ + ); + if (returnedMessageId != messageId) revert MessageIdMisMatched(); + + emit BridgingTokens( + connector_, + msg.sender, + transferInfo.receiver, + transferInfo.tokenId, + transferInfo.amount, + messageId + ); + } + + /** + * @notice Executes pre-mint operations before minting tokens. + * @dev This internal function is called before minting tokens. + * It validates the caller as a valid connector, checks if the receiver is not this contract, the bridge contract, + * or the token contract, and executes the destination pre-hook call if a hook contract is defined. + * @param transferInfo_ Information about the transfer. + * @return postHookData Data returned from the destination pre-hook call. + * @return transferInfo Information about the transfer after pre-mint operations. + * @dev Reverts with `InvalidConnector` if the caller is not a valid connector. + * Reverts with `CannotTransferOrExecuteOnBridgeContracts` if the receiver is this contract, the bridge contract, + * or the token contract. + */ + function _beforeMint( + uint32, + NFTTransferInfo memory transferInfo_ + ) + internal + returns (bytes memory postHookData, NFTTransferInfo memory transferInfo) + { + if (!validConnectors[msg.sender]) revert InvalidConnector(); + + // no need of source check here, as if invalid caller, will revert with InvalidPoolId + if ( + transferInfo_.receiver == address(this) || + // transferInfo_.receiver == address(bridge__) || + transferInfo_.receiver == token + ) revert CannotTransferOrExecuteOnBridgeContracts(); + + if (address(hook__) != address(0)) { + (postHookData, transferInfo) = hook__.dstPreHookCall( + DstPreHookNFTCallParams( + msg.sender, + connectorCache[msg.sender], + transferInfo_ + ) + ); + } else { + transferInfo = transferInfo_; + } + } + + /** + * @notice Executes post-mint operations after minting tokens. + * @dev This internal function is called after minting tokens. + * It executes the destination post-hook call if a hook contract is defined and updates cache data. + * @param messageId_ The unique identifier for the mint transaction. + * @param postHookData_ Data returned from the destination pre-hook call. + * @param transferInfo_ Information about the mint transaction. + */ + function _afterMint( + uint256, + bytes32 messageId_, + bytes memory postHookData_, + NFTTransferInfo memory transferInfo_ + ) internal { + if (address(hook__) != address(0)) { + CacheData memory cacheData = hook__.dstPostHookCall( + DstPostHookNFTCallParams( + msg.sender, + messageId_, + connectorCache[msg.sender], + postHookData_, + transferInfo_ + ) + ); + + identifierCache[messageId_] = cacheData.identifierCache; + connectorCache[msg.sender] = cacheData.connectorCache; + } + + emit TokensBridged( + msg.sender, + transferInfo_.receiver, + transferInfo_.tokenId, + transferInfo_.amount, + messageId_ + ); + } + + /** + * @notice Executes pre-retry operations before retrying a failed transaction. + * @dev This internal function is called before retrying a failed transaction. + * It validates the connector, retrieves cache data for the given message ID, + * and executes the pre-retry hook if defined. + * @param connector_ The address of the connector responsible for the failed transaction. + * @param messageId_ The unique identifier for the failed transaction. + * @return postHookData Data returned from the pre-retry hook call. + * @return transferInfo Information about the transfer. + * @dev Reverts with `InvalidConnector` if the connector is not valid. + * Reverts with `NoPendingData` if there is no pending data for the given message ID. + */ + function _beforeRetry( + address connector_, + bytes32 messageId_ + ) + internal + returns (bytes memory postHookData, NFTTransferInfo memory transferInfo) + { + if (!validConnectors[connector_]) revert InvalidConnector(); + + CacheData memory cacheData = CacheData( + identifierCache[messageId_], + connectorCache[connector_] + ); + + if (cacheData.identifierCache.length == 0) revert NoPendingData(); + (postHookData, transferInfo) = hook__.preRetryHook( + PreRetryHookCallParams(connector_, cacheData) + ); + } + + /** + * @notice Executes post-retry operations after retrying a failed transaction. + * @dev This internal function is called after retrying a failed transaction. + * It retrieves cache data for the given message ID, executes the post-retry hook if defined, + * and updates cache data. + * @param connector_ The address of the connector responsible for the failed transaction. + * @param messageId_ The unique identifier for the failed transaction. + * @param postHookData Data returned from the pre-retry hook call. + */ + function _afterRetry( + address connector_, + bytes32 messageId_, + bytes memory postHookData + ) internal { + CacheData memory cacheData = CacheData( + identifierCache[messageId_], + connectorCache[connector_] + ); + + (cacheData) = hook__.postRetryHook( + PostRetryHookCallParams( + connector_, + messageId_, + postHookData, + cacheData + ) + ); + identifierCache[messageId_] = cacheData.identifierCache; + connectorCache[connector_] = cacheData.connectorCache; + } + + /** + * @notice Retrieves the minimum fees required for a transaction from a connector. + * @dev This function returns the minimum fees required for a transaction from the specified connector, + * based on the provided message gas limit and payload size. + * @param connector_ The address of the connector. + * @param msgGasLimit_ The gas limit for the transaction. + * @param payloadSize_ The size of the payload for the transaction. + * @return totalFees The total minimum fees required for the transaction. + */ + function getMinFees( + address connector_, + uint256 msgGasLimit_, + uint256 payloadSize_ + ) external view returns (uint256 totalFees) { + return IConnector(connector_).getMinFees(msgGasLimit_, payloadSize_); + } +} diff --git a/contracts/bridge/NFT/NFTController.sol b/contracts/bridge/NFT/NFTController.sol new file mode 100644 index 00000000..0d209f49 --- /dev/null +++ b/contracts/bridge/NFT/NFTController.sol @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import "./NFTBase.sol"; +import {IMintableERC721} from "../../interfaces/IMintableERC721.sol"; +import {IMintableERC1155} from "../../interfaces/IMintableERC1155.sol"; + +contract NFTController is NFTBase { + bytes4 private interfaceId; + + constructor(address token_, bytes4 interfaceId_) NFTBase(token_) { + if (interfaceId_ != ID_ERC721 && interfaceId_ != ID_ERC1155) + revert InvalidTokenContract(); + bridgeType = NORMAL_CONTROLLER; + interfaceId = interfaceId_; + } + + /** + * @notice Bridges tokens between chains. + * @dev This function allows bridging tokens between different chains. + * @param receiver_ The address to receive the bridged tokens. + * @param tokenId_ The id of token to bridge. + * @param amount_ The amount of tokens to bridge. + * @param msgGasLimit_ The gas limit for the execution of the bridging process. + * @param connector_ The address of the connector contract responsible for the bridge. + * @param extraData_ The extra data passed to hook functions. + * @param options_ Additional options for the bridging process. + */ + function bridge( + address receiver_, + uint256 tokenId_, + uint256 amount_, + uint256 msgGasLimit_, + address connector_, + bytes calldata extraData_, + bytes calldata options_ + ) external payable nonReentrant { + ( + NFTTransferInfo memory transferInfo, + bytes memory postHookData + ) = _beforeBridge( + connector_, + NFTTransferInfo(receiver_, tokenId_, amount_, extraData_) + ); + + // to maintain socket dl specific accounting for super token + _burn(msg.sender, transferInfo.tokenId, transferInfo.amount); + _afterBridge( + msgGasLimit_, + connector_, + options_, + postHookData, + transferInfo + ); + } + + /** + * @notice Receives inbound tokens from another chain. + * @dev This function is used to receive tokens from another chain. + * @param siblingChainSlug_ The identifier of the sibling chain. + * @param payload_ The payload containing the inbound tokens. + */ + function receiveInbound( + uint32 siblingChainSlug_, + bytes memory payload_ + ) external payable override nonReentrant { + ( + address receiver, + uint256 tokenId, + uint256 lockAmount, + bytes32 messageId, + bytes memory extraData + ) = abi.decode(payload_, (address, uint256, uint256, bytes32, bytes)); + + // convert to shares + NFTTransferInfo memory transferInfo = NFTTransferInfo( + receiver, + tokenId, + lockAmount, + extraData + ); + bytes memory postHookData; + (postHookData, transferInfo) = _beforeMint( + siblingChainSlug_, + transferInfo + ); + + _mint(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + + _afterMint(lockAmount, messageId, postHookData, transferInfo); + } + + /** + * @notice Retry a failed transaction. + * @dev This function allows retrying a failed transaction sent through a connector. + * @param connector_ The address of the connector contract responsible for the failed transaction. + * @param messageId_ The unique identifier of the failed transaction. + */ + function retry( + address connector_, + bytes32 messageId_ + ) external nonReentrant { + ( + bytes memory postHookData, + NFTTransferInfo memory transferInfo + ) = _beforeRetry(connector_, messageId_); + _mint(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + + _afterRetry(connector_, messageId_, postHookData); + } + + function _burn(address user_, uint256 burnTokenId_, uint256 burnAmount_) internal virtual { + if (interfaceId == ID_ERC721) { + IMintableERC721(token).burn(user_, burnTokenId_); + } else { + IMintableERC1155(token).burn(user_, burnTokenId_, burnAmount_); + } + } + + function _mint(address user_, uint256 mintTokenId_, uint256 mintAmount_) internal virtual { + if (mintAmount_ == 0) return; + if (interfaceId == ID_ERC721) { + IMintableERC721(token).mint(user_, mintTokenId_); + } else { + IMintableERC1155(token).mint(user_, mintTokenId_, mintAmount_); + } + } +} diff --git a/contracts/bridge/NFT/NFTVault.sol b/contracts/bridge/NFT/NFTVault.sol new file mode 100644 index 00000000..4971717a --- /dev/null +++ b/contracts/bridge/NFT/NFTVault.sol @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import "./NFTBase.sol"; +import "../../interfaces/IConnector.sol"; +import "solmate/tokens/ERC721.sol"; +import "solmate/tokens/ERC1155.sol"; + +/** + * @title SuperToken + * @notice A contract which enables bridging a token to its sibling chains. + * @dev This contract implements ISuperTokenOrVault to support message bridging through IMessageBridge compliant contracts. + */ +contract NFTVault is NFTBase { + /** + * @notice constructor for creating a new SuperTokenVault. + * @param token_ token contract address which is to be bridged. + * @param interfaceId_ EIP-165 interface id of token contract which is to be bridged. + */ + + constructor(address token_, bytes4 interfaceId_) NFTBase(token_) { + if (interfaceId_ != ID_ERC721 && interfaceId_ != ID_ERC1155) + revert InvalidTokenContract(); + bridgeType = interfaceId_ == ID_ERC721 ? ERC721_VAULT : ERC1155_VAULT; + } + + /** + * @notice Bridges tokens between chains. + * @dev This function allows bridging tokens between different chains. + * @param receiver_ The address to receive the bridged tokens. + * @param tokenId_ The id of token to bridge. + * @param amount_ The amount of tokens to bridge. + * @param msgGasLimit_ The gas limit for the execution of the bridging process. + * @param connector_ The address of the connector contract responsible for the bridge. + * @param extraData_ The extra data passed to hook functions. + * @param options_ Additional options for the bridging process. + */ + function bridge( + address receiver_, + uint256 tokenId_, + uint256 amount_, + uint256 msgGasLimit_, + address connector_, + bytes calldata extraData_, + bytes calldata options_ + ) external payable nonReentrant { + ( + NFTTransferInfo memory transferInfo, + bytes memory postHookData + ) = _beforeBridge( + connector_, + NFTTransferInfo(receiver_, tokenId_, amount_, extraData_) + ); + + _receiveTokens(transferInfo.tokenId, transferInfo.amount); + + _afterBridge( + msgGasLimit_, + connector_, + options_, + postHookData, + transferInfo + ); + } + + /** + * @notice Receives inbound tokens from another chain. + * @dev This function is used to receive tokens from another chain. + * @param siblingChainSlug_ The identifier of the sibling chain. + * @param payload_ The payload containing the inbound tokens. + */ + function receiveInbound( + uint32 siblingChainSlug_, + bytes memory payload_ + ) external payable override nonReentrant { + ( + address receiver, + uint256 tokenId, + uint256 unlockAmount, + bytes32 messageId, + bytes memory extraData + ) = abi.decode(payload_, (address, uint256, uint256, bytes32, bytes)); + + NFTTransferInfo memory transferInfo = NFTTransferInfo( + receiver, + tokenId, + unlockAmount, + extraData + ); + + bytes memory postHookData; + (postHookData, transferInfo) = _beforeMint( + siblingChainSlug_, + transferInfo + ); + + _transferTokens(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + + _afterMint(unlockAmount, messageId, postHookData, transferInfo); + } + + /** + * @notice Retry a failed transaction. + * @dev This function allows retrying a failed transaction sent through a connector. + * @param connector_ The address of the connector contract responsible for the failed transaction. + * @param messageId_ The unique identifier of the failed transaction. + */ + function retry( + address connector_, + bytes32 messageId_ + ) external nonReentrant { + ( + bytes memory postHookData, + NFTTransferInfo memory transferInfo + ) = _beforeRetry(connector_, messageId_); + _transferTokens(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + + _afterRetry(connector_, messageId_, postHookData); + } + + function _transferTokens(address receiver_, uint256 tokenId_, uint256 amount_) internal { + if (amount_ == 0) return; + if (bridgeType == ERC721_VAULT) { + ERC721(token).safeTransferFrom(address(this), receiver_, tokenId_); + } else { + ERC1155(token).safeTransferFrom(address(this), receiver_, tokenId_, amount_, new bytes(0)); + } + } + + function _receiveTokens(uint256 tokenId_, uint256 amount_) internal { + if (amount_ == 0) return; + if (bridgeType == ERC721_VAULT) { + ERC721(token).safeTransferFrom(msg.sender, address(this), tokenId_); + } else { + ERC1155(token).safeTransferFrom(msg.sender, address(this), tokenId_, amount_, new bytes(0)); + } + } +} diff --git a/contracts/common/Constants.sol b/contracts/common/Constants.sol index d381dd4f..a7251dfe 100644 --- a/contracts/common/Constants.sol +++ b/contracts/common/Constants.sol @@ -19,3 +19,8 @@ bytes32 constant LIMIT_EXECUTION_YIELD_TOKEN_HOOK = keccak256( bytes32 constant ERC20_VAULT = keccak256("ERC20_VAULT"); bytes32 constant NATIVE_VAULT = keccak256("NATIVE_VAULT"); +bytes32 constant ERC721_VAULT = keccak256("ERC721_VAULT"); +bytes32 constant ERC1155_VAULT = keccak256("ERC1155_VAULT"); + +bytes4 constant ID_ERC721 = 0x80ac58cd; // EIP-165 interface id +bytes4 constant ID_ERC1155 = 0xd9b67a26; // EIP-165 interface id diff --git a/contracts/common/NFTStructs.sol b/contracts/common/NFTStructs.sol new file mode 100644 index 00000000..8ead2ca1 --- /dev/null +++ b/contracts/common/NFTStructs.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +struct SrcPreHookNFTCallParams { + address connector; + address msgSender; + NFTTransferInfo transferInfo; +} + +struct SrcPostHookNFTCallParams { + address connector; + bytes options; + bytes postHookData; + NFTTransferInfo transferInfo; +} + +struct DstPreHookNFTCallParams { + address connector; + bytes connectorCache; + NFTTransferInfo transferInfo; +} + +struct DstPostHookNFTCallParams { + address connector; + bytes32 messageId; + bytes connectorCache; + bytes postHookData; + NFTTransferInfo transferInfo; +} + +struct NFTTransferInfo { + address receiver; + uint256 tokenId; + uint256 amount; + bytes extraData; +} diff --git a/contracts/interfaces/IMintableERC1155.sol b/contracts/interfaces/IMintableERC1155.sol new file mode 100644 index 00000000..1b4c73ff --- /dev/null +++ b/contracts/interfaces/IMintableERC1155.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +interface IMintableERC1155 { + function mint(address receiver_, uint256 id_, uint256 amount_) external; + + function burn(address burner_, uint256 id_, uint256 amount_) external; +} diff --git a/contracts/interfaces/IMintableERC721.sol b/contracts/interfaces/IMintableERC721.sol new file mode 100644 index 00000000..c6e8a7d7 --- /dev/null +++ b/contracts/interfaces/IMintableERC721.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +interface IMintableERC721 { + function mint(address receiver_, uint256 id_) external; + + function burn(address burner_, uint256 id_) external; +} diff --git a/contracts/interfaces/INFTBridge.sol b/contracts/interfaces/INFTBridge.sol new file mode 100644 index 00000000..43356bee --- /dev/null +++ b/contracts/interfaces/INFTBridge.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.3; + +interface INFTBridge { + function bridge( + address receiver_, + uint256 tokenId_, + uint256 amount_, + uint256 msgGasLimit_, + address connector_, + bytes calldata extraData_, + bytes calldata options_ + ) external payable; + + function receiveInbound( + uint32 siblingChainSlug_, + bytes memory payload_ + ) external payable; + + function retry(address connector_, bytes32 messageId_) external; +} diff --git a/contracts/interfaces/INFTHook.sol b/contracts/interfaces/INFTHook.sol new file mode 100644 index 00000000..13d5bccc --- /dev/null +++ b/contracts/interfaces/INFTHook.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.3; +import "../common/Structs.sol"; +import "../common/NFTStructs.sol"; + +interface INFTHook { + /** + * @notice Executes pre-hook call for source underlyingAsset. + * @dev This function is used to execute a pre-hook call for the source underlyingAsset before initiating a transfer. + * @param params_ Parameters for the pre-hook call. + * @return transferInfo Information about the transfer. + * @return postHookData returned from the pre-hook call. + */ + function srcPreHookCall( + SrcPreHookNFTCallParams calldata params_ + ) + external + returns (NFTTransferInfo memory transferInfo, bytes memory postHookData); + + function srcPostHookCall( + SrcPostHookNFTCallParams calldata params_ + ) external returns (NFTTransferInfo memory transferInfo); + + /** + * @notice Executes pre-hook call for destination underlyingAsset. + * @dev This function is used to execute a pre-hook call for the destination underlyingAsset before initiating a transfer. + * @param params_ Parameters for the pre-hook call. + */ + function dstPreHookCall( + DstPreHookNFTCallParams calldata params_ + ) + external + returns (bytes memory postHookData, NFTTransferInfo memory transferInfo); + + /** + * @notice Executes post-hook call for destination underlyingAsset. + * @dev This function is used to execute a post-hook call for the destination underlyingAsset after completing a transfer. + * @param params_ Parameters for the post-hook call. + * @return cacheData Cached data for the post-hook call. + */ + function dstPostHookCall( + DstPostHookNFTCallParams calldata params_ + ) external returns (CacheData memory cacheData); + + /** + * @notice Executes a pre-retry hook for a failed transaction. + * @dev This function is used to execute a pre-retry hook for a failed transaction. + * @param params_ Parameters for the pre-retry hook. + * @return postHookData Data from the post-retry hook. + * @return transferInfo Information about the transfer. + */ + function preRetryHook( + PreRetryHookCallParams calldata params_ + ) + external + returns (bytes memory postHookData, NFTTransferInfo memory transferInfo); + + /** + * @notice Executes a post-retry hook for a failed transaction. + * @dev This function is used to execute a post-retry hook for a failed transaction. + * @param params_ Parameters for the post-retry hook. + * @return cacheData Cached data for the post-retry hook. + */ + function postRetryHook( + PostRetryHookCallParams calldata params_ + ) external returns (CacheData memory cacheData); +} From 47bfac27bbabf1668cf3f6690db8a9454af7e7dd Mon Sep 17 00:00:00 2001 From: orionstardust Date: Mon, 2 Sep 2024 00:32:17 -0400 Subject: [PATCH 02/22] feat:add new cli for new NFT project --- package.json | 1 + script/script.ts | 6 +- script/setup/addNewNFT.ts | 149 +++++++++++++++++++++ script/setup/common.ts | 13 ++ script/setup/configUtils.ts | 47 +++++-- script/setup/enumMaps.ts | 9 +- script/setup/updateExistingNFTAddresses.ts | 43 ++++++ src/enums/existing-nft-addresses.ts | 14 ++ src/enums/index.ts | 3 + src/enums/nftName.ts | 9 ++ src/enums/nfts.ts | 7 + 11 files changed, 290 insertions(+), 11 deletions(-) create mode 100644 script/setup/addNewNFT.ts create mode 100644 script/setup/updateExistingNFTAddresses.ts create mode 100644 src/enums/existing-nft-addresses.ts create mode 100644 src/enums/nftName.ts create mode 100644 src/enums/nfts.ts diff --git a/package.json b/package.json index f65cb046..32378bf2 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "project:new": "npx ts-node script/script.ts new", "project:edit": "npx ts-node script/script.ts edit", "project:addToken": "npx ts-node script/script.ts addToken", + "project:addNFT": "npx ts-node script/script.ts addNFT", "bridge": "npx hardhat run script/bridge/bridge.ts" }, "pre-commit": [ diff --git a/script/script.ts b/script/script.ts index e0302769..e43d2cd1 100755 --- a/script/script.ts +++ b/script/script.ts @@ -4,6 +4,7 @@ import { initDeploymentConfig } from "./constants"; import { addProject } from "./setup/newProject/main"; import { addNewToken } from "./setup/addNewToken"; import { editProject } from "./setup/editProject"; +import { addNewNFT } from "./setup/addNewNFT"; async function main() { const args = process.argv.slice(2); @@ -16,9 +17,12 @@ async function main() { case "edit": await editProject(); break; - case "add_token": + case "addToken": await addNewToken(); break; + case "addNFT": + await addNewNFT(); + break; default: console.log("Unknown command"); } diff --git a/script/setup/addNewNFT.ts b/script/setup/addNewNFT.ts new file mode 100644 index 00000000..6192aad5 --- /dev/null +++ b/script/setup/addNewNFT.ts @@ -0,0 +1,149 @@ +import prompts from "prompts"; +import { appendToEnvFile, updateNFTEnums } from "./configUtils"; +import { ChainSlug, MainnetIds, TestnetIds } from "@socket.tech/dl-core"; +import { ExistingNFTAddresses, NFTs } from "../../src/enums"; +import { generateNFTAddressesFile } from "./updateExistingNFTAddresses"; +import { + NewNFTInfo, + NFTType, + validateEmptyValue, + validateEthereumAddress, + validateRPC, +} from "./common"; +import { chainSlugReverseMap } from "./enumMaps"; +import { rpcKeys } from "../helpers"; + +export const addNewNFT = async () => { + let chainOptions = [...MainnetIds, ...TestnetIds].map((chain) => ({ + title: chainSlugReverseMap.get(String(chain)), + value: chain, + })); + let newNFTInfo: NewNFTInfo = await getNewNFTInfo(chainOptions); + console.log("newNFTInfo", newNFTInfo); + if (!newNFTInfo.name) return; + console.log("Adding new token: ", newNFTInfo); + if (!Object.keys(NFTs).includes(newNFTInfo.symbol.toUpperCase())) { + await updateNFTEnums(newNFTInfo); + } + + const newNFTsEnum = { + ...NFTs, + [newNFTInfo.symbol.toUpperCase()]: newNFTInfo.symbol.toUpperCase(), + }; + + generateNFTAddressesFile( + [ + { + chainSlug: newNFTInfo.chainSlug as ChainSlug, + token: newNFTInfo.symbol.toUpperCase() as NFTs, + address: newNFTInfo.address, + }, + ], + newNFTsEnum + ); +}; + +export const getNewNFTInfo = async ( + chainOptions: { title: string; value: number }[] +) => { + let newNFTInfo: NewNFTInfo = { + name: "", + symbol: "", + type: NFTType.ERC721, + address: "", + chainSlug: 0 as ChainSlug, + }; + + const { name, symbol, type, chainSlug, address } = await prompts([ + { + name: "name", + type: "text", + message: "Enter NFT name", + validate: (value) => validateEmptyValue(value.trim()), + }, + { + name: "type", + type: "select", + message: "Select NFT type", + choices: [ + { + title: "ERC721", + value: NFTType.ERC721, + }, + { + title: "ERC1155", + value: NFTType.ERC1155, + }, + ], + }, + { + name: "symbol", + type: "text", + message: "Enter NFT symbol", + validate: (value) => validateEmptyValue(value.trim()), + }, + { + name: "chainSlug", + type: "select", + message: "Select chain where token is deployed", + choices: chainOptions, + }, + { + name: "address", + type: "text", + message: "Enter token address", + validate: (value) => validateEthereumAddress(value.trim()), + }, + ]); + newNFTInfo.name = name; + newNFTInfo.symbol = symbol; + newNFTInfo.type = type; + newNFTInfo.chainSlug = chainSlug as ChainSlug; + newNFTInfo.address = address.trim(); + + if (ExistingNFTAddresses[chainSlug]) { + for (let [symbol, address] of Object.entries( + ExistingNFTAddresses[newNFTInfo.chainSlug] + )) { + if (address.toLowerCase() === newNFTInfo.address.toLowerCase()) { + console.log( + `NFT already present in the repo as ${symbol} on chain ${chainSlugReverseMap.get( + String(chainSlug) + )}` + ); + return newNFTInfo; + } + } + } + + let rpcKey = rpcKeys(chainSlug); + let rpc = process.env[rpcKey]; + if (!rpc) { + const rpcInfo = await prompts([ + { + name: "rpc", + type: "text", + message: `Enter RPC url for the chain ${chainSlug} (for fetching token metadata)`, + validate: (value) => validateRPC(chainSlug, value.trim()), + }, + ]); + rpc = rpcInfo.rpc.trim(); + appendToEnvFile(rpcKey, rpc); + } + + newNFTInfo.address = newNFTInfo.address.trim(); + if ( + ExistingNFTAddresses[chainSlug]?.[ + newNFTInfo.symbol.toUpperCase() + ]?.toLowerCase() === newNFTInfo.address.toLowerCase() + ) { + console.log("Token already present in the list"); + return newNFTInfo; + } + newNFTInfo = { + ...newNFTInfo, + symbol: newNFTInfo.symbol.toUpperCase(), + chainSlug, + }; + return newNFTInfo; +}; diff --git a/script/setup/common.ts b/script/setup/common.ts index a95e4550..3706890f 100644 --- a/script/setup/common.ts +++ b/script/setup/common.ts @@ -26,6 +26,19 @@ export type NewTokenInfo = { address: string; }; +export enum NFTType { + ERC721 = "erc721", + ERC1155 = "erc1155", +} + +export type NewNFTInfo = { + name: string; + type: NFTType; + symbol: string; + chainSlug: ChainSlug; + address: string; +}; + type TokenRateLimits = Record< string, { sendingLimit: number; receivingLimit: number } diff --git a/script/setup/configUtils.ts b/script/setup/configUtils.ts index ce2680fb..b69a45ed 100644 --- a/script/setup/configUtils.ts +++ b/script/setup/configUtils.ts @@ -2,7 +2,7 @@ import path from "path"; import fs, { appendFile, appendFileSync, writeFileSync } from "fs"; import { writeFile } from "fs/promises"; import { ChainSlug } from "@socket.tech/dl-core"; -import { Tokens } from "../../src/enums"; +import { NFTs, Tokens } from "../../src/enums"; import { chainSlugReverseMap, getEnumMaps, @@ -154,6 +154,28 @@ export const updateTokenEnums = async (newTokenInfo: { console.log(`✔ Updated Enums : Tokens, Symbols, Decimals, Token Names`); }; +export const updateNFTEnums = async (newNFTInfo: { + name: string; + symbol: string; +}) => { + if (!newNFTInfo.name) return; + + let { name, symbol } = newNFTInfo; + await updateFile( + "nfts.ts", + `,\n ${symbol.toUpperCase()} = "${symbol.toUpperCase()}",\n}\n`, + ",\n}" + ); + + await updateFile( + "nftName.ts", + `,\n [NFTs.${symbol.toUpperCase()}]: "${name}",\n};\n`, + ",\n};" + ); + + console.log(`✔ Updated Enums : NFTs`); +}; + const updateFile = async (fileName, newChainDetails, replaceWith) => { const filePath = enumFolderPath + fileName; const outputExists = fs.existsSync(filePath); @@ -169,18 +191,25 @@ const updateFile = async (fileName, newChainDetails, replaceWith) => { fs.writeFileSync(filePath, newDataString); }; -const checkValueIfEnum = (value: any, tokensEnum: object = Tokens) => { +const checkValueIfEnum = ( + value: any, + tokensEnum: object = Tokens, + nftsEnum: object = NFTs +) => { const { chainSlugMap, tokensMap, + nftsMap, integrationTypesMap, deploymentModeMap, hookMap, - } = getEnumMaps(tokensEnum); + } = getEnumMaps(tokensEnum, nftsEnum); if (chainSlugMap.has(value)) { return "ChainSlug." + chainSlugMap.get(value); } else if (tokensMap.has(value)) { return "Tokens." + tokensMap.get(value); + } else if (nftsMap.has(value)) { + return "NFTs." + nftsMap.get(value); } else if (integrationTypesMap.has(value)) { return "IntegrationTypes." + integrationTypesMap.get(value); } else if (deploymentModeMap.has(value)) { @@ -194,30 +223,32 @@ const checkValueIfEnum = (value: any, tokensEnum: object = Tokens) => { export const serializeConstants = ( constants: any, depth: number = 0, - tokensEnum: object = Tokens + tokensEnum: object = Tokens, + nftsEnum: object = NFTs ): string => { const indent = " ".repeat(depth * 2); // Increase indent by 2 spaces per depth level const entries = Object.entries(constants); const serializedEntries = entries.map(([key, value]) => { - const enumKey = checkValueIfEnum(key, tokensEnum); + const enumKey = checkValueIfEnum(key, tokensEnum, nftsEnum); const newKey = enumKey ? `[${enumKey}]` : String(key); if (typeof value === "object" && !Array.isArray(value) && value !== null) { return `${indent}${newKey}: {\n${serializeConstants( value, depth + 1, - tokensEnum + tokensEnum, + nftsEnum )}\n${indent}}`; } else if (Array.isArray(value)) { return `${indent}${newKey}: [${value .map((v) => { - const enumValue = checkValueIfEnum(String(v), tokensEnum); + const enumValue = checkValueIfEnum(String(v), tokensEnum, nftsEnum); return enumValue ? `${enumValue}` : JSON.stringify(v); }) .join(", ")}]`; } else { - let valueEnum = checkValueIfEnum(String(value), tokensEnum); + let valueEnum = checkValueIfEnum(String(value), tokensEnum, nftsEnum); let newValue = valueEnum ? valueEnum : JSON.stringify(value); // Currently we don't have chain slugs as values, so can avoid them for now. This is a fix // for the case when we have chain slugs as values, for example sendingLimit = 1. diff --git a/script/setup/enumMaps.ts b/script/setup/enumMaps.ts index ce9fa913..217ab1aa 100644 --- a/script/setup/enumMaps.ts +++ b/script/setup/enumMaps.ts @@ -4,7 +4,7 @@ import { DeploymentMode, IntegrationTypes, } from "@socket.tech/dl-core"; -import { Project, Tokens } from "../../src/enums"; +import { NFTs, Project, Tokens } from "../../src/enums"; import { Hooks } from "../../src"; export const chainSlugReverseMap = createReverseEnumMap(ChainSlug); @@ -25,12 +25,17 @@ function createReverseEnumMap(enumObj: any) { return reverseMap; } -export const getEnumMaps = (tokensEnum: object = Tokens) => { +export const getEnumMaps = ( + tokensEnum: object = Tokens, + nftsEnum: object = NFTs +) => { // tokens is calculating separately because it is updated during setupScript with new token const tokensMap = createReverseEnumMap(tokensEnum); + const nftsMap = createReverseEnumMap(nftsEnum); return { chainSlugMap: chainSlugReverseMap, tokensMap, + nftsMap, integrationTypesMap: integrationTypesreverseMap, deploymentModeMap: deploymentModeReverseMap, hookMap: hookReverseMap, diff --git a/script/setup/updateExistingNFTAddresses.ts b/script/setup/updateExistingNFTAddresses.ts new file mode 100644 index 00000000..74248262 --- /dev/null +++ b/script/setup/updateExistingNFTAddresses.ts @@ -0,0 +1,43 @@ +import fs from "fs"; +import { ChainSlug } from "../../src"; +import { enumFolderPath, serializeConstants } from "./configUtils"; +import { NFTs } from "../../src/enums"; +import { ExistingNFTAddresses } from "../../src/enums"; + +export type NFTAddressObj = { + chainSlug: ChainSlug; + token: NFTs | string; + address: string; +}; +export const generateNFTAddressesFile = ( + tokenAddresses: NFTAddressObj[], + nftsEnum: object = NFTs +) => { + for (const tokenAddressObj of tokenAddresses) { + const { chainSlug, token, address } = tokenAddressObj; + if (!ExistingNFTAddresses[chainSlug]) ExistingNFTAddresses[chainSlug] = {}; + ExistingNFTAddresses[chainSlug][token] = address; + } + const serializedContent = serializeConstants( + ExistingNFTAddresses, + 0, + {}, + nftsEnum + ); + const content = ` + import { ChainSlug } from "@socket.tech/dl-core"; + import { NFTs } from "./nfts"; + + export const ExistingNFTAddresses: { + [key in ChainSlug]?: { [key in NFTs]?: string }; + } = { + ${serializedContent} +}; +`; + fs.writeFileSync(enumFolderPath + "existing-nft-addresses.ts", content); + console.log( + `✔ existing nft addresses file updated : ${ + enumFolderPath + "existing-nft-addresses.ts" + }` + ); +}; diff --git a/src/enums/existing-nft-addresses.ts b/src/enums/existing-nft-addresses.ts new file mode 100644 index 00000000..37ba4d8f --- /dev/null +++ b/src/enums/existing-nft-addresses.ts @@ -0,0 +1,14 @@ +import { ChainSlug } from "@socket.tech/dl-core"; +import { NFTs } from "./nfts"; + +export const ExistingNFTAddresses: { + [key in ChainSlug]?: { [key in NFTs]?: string }; +} = { + [ChainSlug.POLYGON_MAINNET]: { + [NFTs.GOTCHI]: "0x86935F11C86623deC8a25696E1C19a8659CbF95d", + [NFTs.GOTCHI_ITEM]: "0x58de9AaBCaeEC0f69883C94318810ad79Cc6a44f", + [NFTs.FORGE]: "0x4fDfc1B53Fd1D80d969C984ba7a8CE4c7bAaD442", + [NFTs.REALM]: "0x1D0360BaC7299C86Ec8E99d0c1C9A95FEfaF2a11", + [NFTs.INSTALLATION]: "0x19f870bD94A34b3adAa9CaA439d333DA18d6812A", + }, +}; diff --git a/src/enums/index.ts b/src/enums/index.ts index 2e98d740..098cd0fa 100644 --- a/src/enums/index.ts +++ b/src/enums/index.ts @@ -4,3 +4,6 @@ export * from "./existing-token-addresses"; export * from "./tokenSymbol"; export * from "./tokenName"; export * from "./tokenDecimals"; +export * from "./nfts"; +export * from "./nftName"; +export * from "./existing-nft-addresses"; diff --git a/src/enums/nftName.ts b/src/enums/nftName.ts new file mode 100644 index 00000000..1c301450 --- /dev/null +++ b/src/enums/nftName.ts @@ -0,0 +1,9 @@ +import { NFTs } from "./nfts"; + +export const nftName: { [key in NFTs]: string } = { + [NFTs.GOTCHI]: "Aavegotchi", + [NFTs.GOTCHI_ITEM]: "Aavegotchi Item", + [NFTs.FORGE]: "Aavegotchi Forge", + [NFTs.REALM]: "Gotchiverse Realm", + [NFTs.INSTALLATION]: "Gotchiverse Installation", +}; diff --git a/src/enums/nfts.ts b/src/enums/nfts.ts new file mode 100644 index 00000000..de8ef222 --- /dev/null +++ b/src/enums/nfts.ts @@ -0,0 +1,7 @@ +export enum NFTs { + GOTCHI = "GOTCHI", + GOTCHI_ITEM = "GOTCHI_ITEM", + FORGE = "FORGE", + REALM = "REALM", + INSTALLATION = "INSTALLATION", +} From ba9739acfc6802f728eb4f53493acdcd5b923b36 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Mon, 2 Sep 2024 00:32:46 -0400 Subject: [PATCH 03/22] fix: lint --- contracts/bridge/NFT/NFTBase.sol | 8 +++-- contracts/bridge/NFT/NFTController.sol | 12 +++++-- contracts/bridge/NFT/NFTVault.sol | 44 ++++++++++++++++++++------ contracts/interfaces/INFTHook.sol | 15 +++++++-- 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/contracts/bridge/NFT/NFTBase.sol b/contracts/bridge/NFT/NFTBase.sol index 34f6fd98..e600e9b6 100644 --- a/contracts/bridge/NFT/NFTBase.sol +++ b/contracts/bridge/NFT/NFTBase.sol @@ -61,14 +61,18 @@ abstract contract NFTBase is ReentrancyGuard, INFTBridge, AccessControl { ) external virtual onlyOwner { // remove the approval from the old hook if (bridgeType == ERC721_VAULT) { - if (ERC721(token).isApprovedForAll(address(this), address(hook__))) { + if ( + ERC721(token).isApprovedForAll(address(this), address(hook__)) + ) { ERC721(token).setApprovalForAll(address(hook__), false); } if (approve_) { ERC721(token).setApprovalForAll(hook_, approve_); } } else { - if (ERC1155(token).isApprovedForAll(address(this), address(hook__))) { + if ( + ERC1155(token).isApprovedForAll(address(this), address(hook__)) + ) { ERC1155(token).setApprovalForAll(address(hook__), false); } if (approve_) { diff --git a/contracts/bridge/NFT/NFTController.sol b/contracts/bridge/NFT/NFTController.sol index 0d209f49..e5692398 100644 --- a/contracts/bridge/NFT/NFTController.sol +++ b/contracts/bridge/NFT/NFTController.sol @@ -109,7 +109,11 @@ contract NFTController is NFTBase { _afterRetry(connector_, messageId_, postHookData); } - function _burn(address user_, uint256 burnTokenId_, uint256 burnAmount_) internal virtual { + function _burn( + address user_, + uint256 burnTokenId_, + uint256 burnAmount_ + ) internal virtual { if (interfaceId == ID_ERC721) { IMintableERC721(token).burn(user_, burnTokenId_); } else { @@ -117,7 +121,11 @@ contract NFTController is NFTBase { } } - function _mint(address user_, uint256 mintTokenId_, uint256 mintAmount_) internal virtual { + function _mint( + address user_, + uint256 mintTokenId_, + uint256 mintAmount_ + ) internal virtual { if (mintAmount_ == 0) return; if (interfaceId == ID_ERC721) { IMintableERC721(token).mint(user_, mintTokenId_); diff --git a/contracts/bridge/NFT/NFTVault.sol b/contracts/bridge/NFT/NFTVault.sol index 4971717a..d9704cb2 100644 --- a/contracts/bridge/NFT/NFTVault.sol +++ b/contracts/bridge/NFT/NFTVault.sol @@ -12,11 +12,11 @@ import "solmate/tokens/ERC1155.sol"; * @dev This contract implements ISuperTokenOrVault to support message bridging through IMessageBridge compliant contracts. */ contract NFTVault is NFTBase { - /** - * @notice constructor for creating a new SuperTokenVault. - * @param token_ token contract address which is to be bridged. - * @param interfaceId_ EIP-165 interface id of token contract which is to be bridged. - */ + /** + * @notice constructor for creating a new SuperTokenVault. + * @param token_ token contract address which is to be bridged. + * @param interfaceId_ EIP-165 interface id of token contract which is to be bridged. + */ constructor(address token_, bytes4 interfaceId_) NFTBase(token_) { if (interfaceId_ != ID_ERC721 && interfaceId_ != ID_ERC1155) @@ -94,7 +94,11 @@ contract NFTVault is NFTBase { transferInfo ); - _transferTokens(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + _transferTokens( + transferInfo.receiver, + transferInfo.tokenId, + transferInfo.amount + ); _afterMint(unlockAmount, messageId, postHookData, transferInfo); } @@ -113,17 +117,31 @@ contract NFTVault is NFTBase { bytes memory postHookData, NFTTransferInfo memory transferInfo ) = _beforeRetry(connector_, messageId_); - _transferTokens(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + _transferTokens( + transferInfo.receiver, + transferInfo.tokenId, + transferInfo.amount + ); _afterRetry(connector_, messageId_, postHookData); } - function _transferTokens(address receiver_, uint256 tokenId_, uint256 amount_) internal { + function _transferTokens( + address receiver_, + uint256 tokenId_, + uint256 amount_ + ) internal { if (amount_ == 0) return; if (bridgeType == ERC721_VAULT) { ERC721(token).safeTransferFrom(address(this), receiver_, tokenId_); } else { - ERC1155(token).safeTransferFrom(address(this), receiver_, tokenId_, amount_, new bytes(0)); + ERC1155(token).safeTransferFrom( + address(this), + receiver_, + tokenId_, + amount_, + new bytes(0) + ); } } @@ -132,7 +150,13 @@ contract NFTVault is NFTBase { if (bridgeType == ERC721_VAULT) { ERC721(token).safeTransferFrom(msg.sender, address(this), tokenId_); } else { - ERC1155(token).safeTransferFrom(msg.sender, address(this), tokenId_, amount_, new bytes(0)); + ERC1155(token).safeTransferFrom( + msg.sender, + address(this), + tokenId_, + amount_, + new bytes(0) + ); } } } diff --git a/contracts/interfaces/INFTHook.sol b/contracts/interfaces/INFTHook.sol index 13d5bccc..acb12c37 100644 --- a/contracts/interfaces/INFTHook.sol +++ b/contracts/interfaces/INFTHook.sol @@ -15,7 +15,10 @@ interface INFTHook { SrcPreHookNFTCallParams calldata params_ ) external - returns (NFTTransferInfo memory transferInfo, bytes memory postHookData); + returns ( + NFTTransferInfo memory transferInfo, + bytes memory postHookData + ); function srcPostHookCall( SrcPostHookNFTCallParams calldata params_ @@ -30,7 +33,10 @@ interface INFTHook { DstPreHookNFTCallParams calldata params_ ) external - returns (bytes memory postHookData, NFTTransferInfo memory transferInfo); + returns ( + bytes memory postHookData, + NFTTransferInfo memory transferInfo + ); /** * @notice Executes post-hook call for destination underlyingAsset. @@ -53,7 +59,10 @@ interface INFTHook { PreRetryHookCallParams calldata params_ ) external - returns (bytes memory postHookData, NFTTransferInfo memory transferInfo); + returns ( + bytes memory postHookData, + NFTTransferInfo memory transferInfo + ); /** * @notice Executes a post-retry hook for a failed transaction. From 96758e0ba0f3b7236c406528a9f7a36638ba1d60 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Tue, 3 Sep 2024 23:05:43 -0400 Subject: [PATCH 04/22] feat: add script for new NFT project --- script/setup/common.ts | 3 +- script/setup/configUtils.ts | 4 +- script/setup/generateConstants.ts | 9 ++- script/setup/newProject/main.ts | 101 +++++++++++++++++-------- script/setup/newProject/nftInfo.ts | 67 ++++++++++++++++ script/setup/newProject/projectInfo.ts | 21 ++++- script/setup/newProject/utils.ts | 30 +++++++- src/enum.ts | 6 ++ src/types.ts | 4 +- 9 files changed, 202 insertions(+), 43 deletions(-) create mode 100644 script/setup/newProject/nftInfo.ts diff --git a/script/setup/common.ts b/script/setup/common.ts index 3706890f..14819c81 100644 --- a/script/setup/common.ts +++ b/script/setup/common.ts @@ -5,7 +5,7 @@ import { isContractAtAddress, rpcKeys, } from "../helpers"; -import { Hooks, ProjectType } from "../../src"; +import { Hooks, ProjectType, TokenType } from "../../src"; import { StaticJsonRpcProvider } from "@ethersproject/providers"; import { Tokens } from "../../src/enums"; @@ -14,6 +14,7 @@ export type ProjectConfig = { projectName: string; hookType: Hooks; owner: string; + tokenType: TokenType; isMainnet: boolean; newToken?: boolean; }; diff --git a/script/setup/configUtils.ts b/script/setup/configUtils.ts index b69a45ed..615cbd03 100644 --- a/script/setup/configUtils.ts +++ b/script/setup/configUtils.ts @@ -19,7 +19,7 @@ export const buildEnvFile = async ( projectName: string, projectType: ProjectType, ownerAddress: string, - tokens: Tokens[], + tokens: Tokens[] | NFTs[], chains: ChainSlug[] ) => { let { publicEnvData, privateEnvData } = getProjectEnvData( @@ -60,7 +60,7 @@ export const getProjectEnvData = ( projectName: string, projectType: ProjectType, ownerAddress: string, - tokens: Tokens[], + tokens: Tokens[] | NFTs[], chains: ChainSlug[] ) => { let publicEnvData: Record = { diff --git a/script/setup/generateConstants.ts b/script/setup/generateConstants.ts index d238c056..9f7851c8 100644 --- a/script/setup/generateConstants.ts +++ b/script/setup/generateConstants.ts @@ -2,13 +2,14 @@ import fs from "fs"; import { ProjectConstants, ProjectType } from "../../src"; import path from "path"; import { serializeConstants } from "./configUtils"; -import { Tokens } from "../../src/enums"; +import { NFTs, Tokens } from "../../src/enums"; export const generateConstantsFile = ( projectType: ProjectType, projectName: string, projectConstants: ProjectConstants, - tokensEnum: object = Tokens + tokensEnum: object = Tokens, + nftsEnum: object = NFTs ) => { let filePath = path.join( __dirname, @@ -22,11 +23,11 @@ import { IntegrationTypes, } from "@socket.tech/dl-core"; import { Hooks, ProjectConstants } from "../../../../src"; -import { Tokens } from "../../../../src/enums"; +import { NFTs, Tokens } from "../../../../src/enums"; // For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. export const pc: ProjectConstants = { -${serializeConstants(projectConstants, 1, tokensEnum)} +${serializeConstants(projectConstants, 1, tokensEnum, nftsEnum)} }; `; fs.writeFileSync(filePath, content); diff --git a/script/setup/newProject/main.ts b/script/setup/newProject/main.ts index 97639955..83fd4df6 100644 --- a/script/setup/newProject/main.ts +++ b/script/setup/newProject/main.ts @@ -1,12 +1,14 @@ import { ChainSlug } from "@socket.tech/dl-core"; -import { Tokens } from "../../../src/enums"; +import { NFTs, Tokens } from "../../../src/enums"; import { buildEnvFile, updateProjectEnums } from "../configUtils"; import { generateConstantsFile } from "../generateConstants"; import { getChainsInfo } from "./chainInfo"; import { getHookRelatedInfo } from "./hookInfo"; import { getProjectInfo } from "./projectInfo"; import { getProjectTokenListInfo } from "./tokenInfo"; -import { buildProjectConstants } from "./utils"; +import { buildNFTProjectConstants, buildProjectConstants } from "./utils"; +import { TokenType } from "../../../src"; +import { getProjectNFTInfo } from "./nftInfo"; export type TokenRateLimits = Record< string, @@ -37,11 +39,21 @@ export type TokenInfo = { }; }; +export type NFTInfo = { + nft: NFTs; + nftAddresses?: { + [key in NFTs]?: { + [chainslug in ChainSlug]?: string; + }; + }; +}; + export type ChainsInfo = { vaultChains: ChainSlug[]; controllerChains: ChainSlug[]; }; export const tokenEnum = Tokens; +export const nftEnum = NFTs; export const addProject = async () => { const projectConfig = await getProjectInfo(); @@ -50,6 +62,7 @@ export const addProject = async () => { projectType, hookType, owner, + tokenType, isLimitsRequired, chainOptions, } = projectConfig; @@ -58,38 +71,62 @@ export const addProject = async () => { const { vaultChains, controllerChains } = chainsInfo; const allChains = [...chainsInfo.vaultChains, ...chainsInfo.controllerChains]; - const tokenInfo: TokenInfo = await getProjectTokenListInfo( - projectType, - owner, - vaultChains, - controllerChains - ); - const { tokenLimitInfo } = await getHookRelatedInfo( - projectType, - isLimitsRequired, - tokenInfo.tokens, - tokenInfo.superTokenInfoMap - ); - await updateProjectEnums(projectConfig.projectName, projectType); - console.log(`✔ Updated Enums :Project`); - await buildEnvFile( - projectConfig.projectName, - projectConfig.projectType, - projectConfig.owner, - tokenInfo.tokens, - allChains - ); + if (tokenType === TokenType.ERC20) { + const tokenInfo: TokenInfo = await getProjectTokenListInfo( + projectType, + owner, + vaultChains, + controllerChains + ); + const { tokenLimitInfo } = await getHookRelatedInfo( + projectType, + isLimitsRequired, + tokenInfo.tokens, + tokenInfo.superTokenInfoMap + ); + await updateProjectEnums(projectConfig.projectName, projectType); + console.log(`✔ Updated Enums :Project`); + await buildEnvFile( + projectConfig.projectName, + projectConfig.projectType, + projectConfig.owner, + tokenInfo.tokens, + allChains + ); - const projectConstants = await buildProjectConstants( - tokenInfo, - chainsInfo, - hookType, - isLimitsRequired, - tokenLimitInfo, - allChains - ); - generateConstantsFile(projectType, projectName, projectConstants); + const projectConstants = await buildProjectConstants( + tokenInfo, + chainsInfo, + hookType, + isLimitsRequired, + tokenLimitInfo, + allChains + ); + generateConstantsFile(projectType, projectName, projectConstants); + } else { + // ERC721, 1155 + const nftInfo: NFTInfo = await getProjectNFTInfo( + projectType, + vaultChains, + controllerChains + ); + await updateProjectEnums(projectConfig.projectName, projectType); + console.log(`✔ Updated Enums :Project`); + await buildEnvFile( + projectConfig.projectName, + projectConfig.projectType, + projectConfig.owner, + [nftInfo.nft], + allChains + ); + const projectConstants = await buildNFTProjectConstants( + nftInfo, + chainsInfo, + hookType + ); + generateConstantsFile(projectType, projectName, projectConstants); + } console.log( `✔ Setup done! You can run this script again to add new projects, add new tokens, or edit project` ); diff --git a/script/setup/newProject/nftInfo.ts b/script/setup/newProject/nftInfo.ts new file mode 100644 index 00000000..c357c648 --- /dev/null +++ b/script/setup/newProject/nftInfo.ts @@ -0,0 +1,67 @@ +import { ChainSlug } from "@socket.tech/dl-core"; +import prompts from "prompts"; +import { ProjectType } from "../../../src"; +import { ExistingNFTAddresses, NFTs } from "../../../src/enums"; +import { validateEthereumAddress } from "../common"; +import { nftEnum, NFTInfo } from "./main"; +import { getChainName } from "../../constants"; + +export const getProjectNFTInfo = async ( + projectType: ProjectType, + vaultChains: ChainSlug[], + controllerChains: ChainSlug[] +): Promise => { + const nftChoices = Object.keys(nftEnum).map((nft) => ({ + title: nft, + value: nftEnum[nft], + })); + if (projectType == ProjectType.SUPERBRIDGE) { + const response = await prompts([ + { + name: "nft", + type: "select", + message: + "Select the NFT to connect (the NFT we want to allow users to bridge to app chain)", + choices: nftChoices, + }, + ]); + const nft = response.nft as NFTs; + const nftAddresses = await getSuperbridgeMissingNFTAddresses(nft, [ + ...vaultChains, + ...controllerChains, + ]); + + return { nft, nftAddresses }; + } else if (projectType === ProjectType.SUPERTOKEN) { + console.log(`SUPERTOKEN project not supported for NFT now`); + } +}; + +export const getSuperbridgeMissingNFTAddresses = async ( + nft: NFTs, + chainList: number[] +) => { + const nftAddresses: { + [key in NFTs]?: { + [chainslug: number]: string; + }; + } = {}; + + nftAddresses[nft] = {}; + for (const chain of chainList) { + const currentAddress = ExistingNFTAddresses[chain]?.[nft]; + if (currentAddress) continue; + const response = await prompts([ + { + name: "address", + type: "text", + message: `Enter the address of the deployed NFT ${nft} on the chain ${getChainName( + chain + )}`, + validate: (value) => validateEthereumAddress(value.trim()), + }, + ]); + nftAddresses[nft][chain] = response.address; + } + return nftAddresses; +}; diff --git a/script/setup/newProject/projectInfo.ts b/script/setup/newProject/projectInfo.ts index 7ec5041f..120b2d9b 100644 --- a/script/setup/newProject/projectInfo.ts +++ b/script/setup/newProject/projectInfo.ts @@ -1,5 +1,5 @@ import prompts from "prompts"; -import { DeploymentMode, Hooks, ProjectType } from "../../../src"; +import { DeploymentMode, Hooks, ProjectType, TokenType } from "../../../src"; import { getChainName, getMainnetIds, @@ -60,6 +60,25 @@ export const getProjectInfo = async () => { ], message: "Select Hook type (Recommended: Limit Hook)", }, + { + name: "tokenType", + type: "select", + choices: [ + { + title: "ERC20", + value: TokenType.ERC20, + }, + { + title: "ERC721", + value: TokenType.ERC721, + }, + { + title: "ERC1155", + value: TokenType.ERC1155, + }, + ], + message: "Select Token type", + }, { name: "isMainnet", type: "toggle", diff --git a/script/setup/newProject/utils.ts b/script/setup/newProject/utils.ts index 4f116251..1635cf61 100644 --- a/script/setup/newProject/utils.ts +++ b/script/setup/newProject/utils.ts @@ -8,7 +8,13 @@ import { import { Tokens } from "../../../src/enums"; import { getMode } from "../../constants"; import { initialLimitsForSuperbridge } from "../common"; -import { ChainsInfo, SuperTokenInfo, TokenInfo, TokenRateLimits } from "./main"; +import { + ChainsInfo, + NFTInfo, + SuperTokenInfo, + TokenInfo, + TokenRateLimits, +} from "./main"; export const buildProjectConstants = async ( tokenInfo: TokenInfo, @@ -57,6 +63,28 @@ export const buildProjectConstants = async ( return JSON.parse(JSON.stringify(projectConstants)); // stringify and parse to remove undefined values }; +export const buildNFTProjectConstants = async ( + nftInfo: NFTInfo, + chainsInfo: ChainsInfo, + hookType: Hooks +) => { + const deploymentMode = getMode(); + const projectConstants: ProjectConstants = { + [deploymentMode]: {}, + }; + + const { nft, nftAddresses } = nftInfo; + projectConstants[deploymentMode][nft] = { + vaultChains: chainsInfo.vaultChains, + controllerChains: chainsInfo.controllerChains, + tokenAddresses: nftAddresses?.[nft], + hook: { + hookType, + }, + }; + return JSON.parse(JSON.stringify(projectConstants)); // stringify and parse to remove undefined values +}; + export const getInitialLimitValue = async ( projectType: ProjectType, token: Tokens, diff --git a/src/enum.ts b/src/enum.ts index 23c87dda..a7d735bf 100644 --- a/src/enum.ts +++ b/src/enum.ts @@ -45,3 +45,9 @@ export enum SuperTokenContracts { NonSuperToken = "NonSuperToken", SuperToken = "SuperToken", } + +export enum TokenType { + ERC20 = "ERC20", + ERC721 = "ERC721", + ERC1155 = "ERC1155", +} diff --git a/src/types.ts b/src/types.ts index 7db6d979..a67331e6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,7 +8,7 @@ import { SuperBridgeContracts, SuperTokenContracts, } from "./enum"; -import { Project, Tokens } from "./enums"; +import { NFTs, Project, Tokens } from "./enums"; export type ProjectConstantsMap = { [key in Project]: ProjectConstants; @@ -16,7 +16,7 @@ export type ProjectConstantsMap = { export type ProjectConstants = { [key in DeploymentMode]?: { - [key in Tokens]?: TokenConstants; + [key in Tokens | NFTs]?: TokenConstants; }; }; From 82d66f18f355ca6302cce05f310e37755522717d Mon Sep 17 00:00:00 2001 From: orionstardust Date: Thu, 5 Sep 2024 23:50:06 -0400 Subject: [PATCH 05/22] fix --- script/constants/config.ts | 32 ++++++++++++++++++++++---------- script/setup/configUtils.ts | 6 +++++- script/setup/newProject/main.ts | 18 ++++++++++-------- src/types.ts | 6 +++--- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/script/constants/config.ts b/script/constants/config.ts index 5f85871c..a7a52221 100644 --- a/script/constants/config.ts +++ b/script/constants/config.ts @@ -1,11 +1,12 @@ import { config as dotenvConfig } from "dotenv"; -dotenvConfig(); - import { DeploymentMode } from "@socket.tech/dl-core"; -import { Project, Tokens } from "../../src/enums"; -import { ProjectType } from "../../src"; +import { NFTs, Project, Tokens } from "../../src/enums"; +import { ProjectType, TokenType } from "../../src"; import { ProjectTypeMap } from "../../src/enums/projectType"; import { ProdTestnetProjects } from "../../src/enums/prodTestnetProjects"; + +dotenvConfig(); + // import { Project, ProjectType, Tokens } from "../../src"; export const getOwner = () => { @@ -73,16 +74,24 @@ export const isSuperToken = () => getProjectType() === ProjectType.SUPERTOKEN; export const getTokens = () => { if (!process.env.TOKENS) throw new Error("TOKENS not mentioned"); - let tokens = process.env.TOKENS.split(",").map( - (token) => token.trim() as Tokens - ); + let tokens = process.env.TOKENS.split(",").map((token) => token.trim()); tokens.forEach((token) => { - if (!Object.values(Tokens).includes(token as Tokens)) + if ( + !Object.values(Tokens).includes(token as Tokens) && + !Object.values(NFTs).includes(token as NFTs) + ) throw new Error("TOKENS are invalid"); }); return tokens; }; +export const getTokenTypes = () => { + if (!process.env.TOKEN_TYPES) throw new Error("TOKEN_TYPES not mentioned"); + return process.env.TOKEN_TYPES.split(",").map( + (tokenType) => tokenType.trim() as TokenType + ); +}; + export const getDryRun = () => { if (!process.env.DRY_RUN) return false; if (process.env.DRY_RUN !== "true" && process.env.DRY_RUN !== "false") @@ -94,17 +103,20 @@ export const getConfigs = () => { let projectType = getProjectType(); let projectName = getProjectName(); let tokens = getTokens(); + let tokenTypes = getTokenTypes(); let mode = getMode(); let socketOwner = getOwner(); - return { projectType, projectName, tokens, mode, socketOwner }; + return { projectType, projectName, tokens, tokenTypes, mode, socketOwner }; }; export const printConfigs = () => { - let { projectType, projectName, tokens, mode, socketOwner } = getConfigs(); + let { projectType, projectName, tokens, tokenTypes, mode, socketOwner } = + getConfigs(); console.log("========================================================"); console.log("PROJECT", projectName); console.log("PROJECT_TYPE", projectType); console.log("TOKENS", tokens); + console.log("TOKEN_TYPES", tokenTypes); console.log("MODE", mode); console.log( `Make sure ${mode}_${projectName}_addresses.json and ${mode}_${projectName}_verification.json is cleared for given networks if redeploying!!` diff --git a/script/setup/configUtils.ts b/script/setup/configUtils.ts index 615cbd03..d8196cf8 100644 --- a/script/setup/configUtils.ts +++ b/script/setup/configUtils.ts @@ -8,7 +8,7 @@ import { getEnumMaps, projectReverseMap, } from "./enumMaps"; -import { ProjectType } from "../../src"; +import { ProjectType, TokenType } from "../../src"; import { NewTokenInfo } from "./common"; import { getChainName } from "../constants"; @@ -20,6 +20,7 @@ export const buildEnvFile = async ( projectType: ProjectType, ownerAddress: string, tokens: Tokens[] | NFTs[], + tokenTypes: TokenType[], chains: ChainSlug[] ) => { let { publicEnvData, privateEnvData } = getProjectEnvData( @@ -27,6 +28,7 @@ export const buildEnvFile = async ( projectType, ownerAddress, tokens, + tokenTypes, chains ); let finalEnvData: Record; @@ -61,11 +63,13 @@ export const getProjectEnvData = ( projectType: ProjectType, ownerAddress: string, tokens: Tokens[] | NFTs[], + tokenTypes: TokenType[], chains: ChainSlug[] ) => { let publicEnvData: Record = { PROJECT: projectName, TOKENS: tokens.join(","), + TOKEN_TYPES: tokenTypes.join(","), OWNER_ADDRESS: ownerAddress, DRY_RUN: "false", }; diff --git a/script/setup/newProject/main.ts b/script/setup/newProject/main.ts index 83fd4df6..d2358e0c 100644 --- a/script/setup/newProject/main.ts +++ b/script/setup/newProject/main.ts @@ -84,13 +84,14 @@ export const addProject = async () => { tokenInfo.tokens, tokenInfo.superTokenInfoMap ); - await updateProjectEnums(projectConfig.projectName, projectType); + await updateProjectEnums(projectName, projectType); console.log(`✔ Updated Enums :Project`); await buildEnvFile( - projectConfig.projectName, - projectConfig.projectType, - projectConfig.owner, + projectName, + projectType, + owner, tokenInfo.tokens, + new Array(tokenInfo.tokens.length).fill(tokenType), allChains ); @@ -110,13 +111,14 @@ export const addProject = async () => { vaultChains, controllerChains ); - await updateProjectEnums(projectConfig.projectName, projectType); + await updateProjectEnums(projectName, projectType); console.log(`✔ Updated Enums :Project`); await buildEnvFile( - projectConfig.projectName, - projectConfig.projectType, - projectConfig.owner, + projectName, + projectType, + owner, [nftInfo.nft], + [tokenType], allChains ); diff --git a/src/types.ts b/src/types.ts index a67331e6..7cdc4d0d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -101,7 +101,7 @@ export type SBTokenAddresses = AppChainAddresses | NonAppChainAddresses; export type SBAddresses = { [chainSlug in ChainSlug]?: { - [token in Tokens]?: SBTokenAddresses; + [token in Tokens | NFTs]?: SBTokenAddresses; }; }; @@ -121,7 +121,7 @@ export type STTokenAddresses = export type STAddresses = { [chainSlug in ChainSlug]?: { - [token in Tokens]?: STTokenAddresses; + [token in Tokens | NFTs]?: STTokenAddresses; }; }; @@ -129,7 +129,7 @@ export interface DeployParams { addresses: SBTokenAddresses | STTokenAddresses; signer: Wallet; currentChainSlug: number; - currentToken: Tokens; + currentToken: Tokens | NFTs; hookType?: Hooks; mergeInboundWithTokens: Tokens[]; tc: TokenConstants; From d3ad866d4ccb5cdb9ddfa4daa01d7c9874c5701d Mon Sep 17 00:00:00 2001 From: orionstardust Date: Fri, 6 Sep 2024 02:31:27 -0400 Subject: [PATCH 06/22] feat: add deploy script for NFT Superbridge --- script/deploy/deploy.ts | 104 ++++++++++++++++++++++++++-------------- src/enum.ts | 2 + src/types.ts | 2 + 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/script/deploy/deploy.ts b/script/deploy/deploy.ts index e6730df4..3618862c 100644 --- a/script/deploy/deploy.ts +++ b/script/deploy/deploy.ts @@ -1,19 +1,15 @@ import { config as dotenvConfig } from "dotenv"; -dotenvConfig(); - import { EventEmitter } from "events"; -EventEmitter.defaultMaxListeners = 20; - -import { Contract, Wallet } from "ethers"; +import { constants, Contract, Wallet } from "ethers"; import { getSignerFromChainSlug } from "../helpers/networks"; import { ChainSlug, IntegrationTypes } from "@socket.tech/dl-core"; import { + getConfigs, + getDryRun, getMode, isSuperBridge, isSuperToken, - getConfigs, printConfigs, - getDryRun, } from "../constants/config"; import { createObj, @@ -24,47 +20,54 @@ import { storeTokenAddresses, } from "../helpers"; import { - SuperBridgeContracts, + CommonContracts, + DeployParams, Hooks, ProjectType, - TokenContracts, - CommonContracts, - SuperTokenContracts, - TokenConstants, - STTokenAddresses, - SBTokenAddresses, + ReturnObj, SBAddresses, + SBTokenAddresses, STAddresses, - DeployParams, - ReturnObj, + STTokenAddresses, + SuperBridgeContracts, + SuperTokenContracts, + TokenConstants, + TokenContracts, + TokenType, } from "../../src"; -import { isSBAppChain, getTokenConstants } from "../helpers/projectConstants"; +import { getTokenConstants, isSBAppChain } from "../helpers/projectConstants"; import { ExistingTokenAddresses } from "../../src/enums/existing-token-addresses"; import { deployHookContracts } from "./deployHook"; import { verifyConstants } from "../helpers/verifyConstants"; import { getBridgeContract } from "../helpers/common"; -import { Project, Tokens } from "../../src/enums"; +import { NFTs, Project, Tokens } from "../../src/enums"; import { parseUnits } from "ethers/lib/utils"; - -import { constants } from "ethers"; import { getAddresses } from "../constants"; + +dotenvConfig(); + +EventEmitter.defaultMaxListeners = 20; + const { AddressZero } = constants; let projectType: ProjectType; let pc: { [token: string]: TokenConstants } = {}; let projectName: string; -let tokens: Tokens[]; +let tokens: string[]; +let tokenTypes: TokenType[]; /** * Deploys contracts for all networks */ export const deploy = async () => { await verifyConstants(); - ({ projectName, projectType, tokens } = getConfigs()); + ({ projectName, projectType, tokens, tokenTypes } = getConfigs()); printConfigs(); let allAddresses: SBAddresses | STAddresses = {}; - for (let token of tokens) { + for (let index = 0; index < tokens.length; index++) { + const token = tokens[index]; + const tokenType = tokenTypes[index]; console.log(`Deploying contracts for ${token}...`); pc[token] = getTokenConstants(token); @@ -109,6 +112,7 @@ export const deploy = async () => { signer, chain, token, + tokenType, siblings, hookType, tokenAddresses, @@ -134,7 +138,8 @@ const deployChainContracts = async ( isVaultChain: boolean, socketSigner: Wallet, chainSlug: number, - token: Tokens, + token: Tokens | NFTs, + tokenType: TokenType, siblings: number[], hookType: Hooks, deployedAddresses: SBTokenAddresses | STTokenAddresses, @@ -148,6 +153,7 @@ const deployChainContracts = async ( signer: socketSigner, currentChainSlug: chainSlug, currentToken: token, + currentTokenType: tokenType, hookType, mergeInboundWithTokens: tc.mergeInboundWithTokens ?? [], tc, @@ -281,7 +287,8 @@ export const deployControllerChainContracts = async ( controller: Contract, contractName: string = "", controllerAddress: string = "", - contractPath: string = ""; + contractPath: string = "", + contractArgs: any[]; if (isSuperToken()) { deployParams = await deploySuperToken(deployParams); @@ -308,13 +315,26 @@ export const deployControllerChainContracts = async ( deployParams.addresses[SuperBridgeContracts.MintableToken] = mintableToken; - contractName = deployParams.tc.isFiatTokenV2_1 - ? SuperBridgeContracts.FiatTokenV2_1_Controller - : SuperBridgeContracts.Controller; - contractPath = deployParams.tc.isFiatTokenV2_1 - ? "contracts/bridge/FiatTokenV2_1/FiatTokenV2_1_Controller.sol" - : "contracts/bridge/Controller.sol"; + contractName = + deployParams.currentTokenType === TokenType.ERC20 + ? deployParams.tc.isFiatTokenV2_1 + ? SuperBridgeContracts.FiatTokenV2_1_Controller + : SuperBridgeContracts.Controller + : SuperBridgeContracts.NFTController; + contractPath = + deployParams.currentTokenType === TokenType.ERC20 + ? deployParams.tc.isFiatTokenV2_1 + ? "contracts/bridge/FiatTokenV2_1/FiatTokenV2_1_Controller.sol" + : "contracts/bridge/Controller.sol" + : "contracts/bridge/NFT/NFTController.sol"; + contractArgs = + deployParams.currentTokenType === TokenType.ERC721 + ? [mintableToken, "0x73ad2146"] + : deployParams.currentTokenType === TokenType.ERC1155 + ? [mintableToken, "0x973bb640"] + : [mintableToken]; } + if (!contractArgs) contractArgs = [mintableToken]; // If controller address is already in addresses object, skip // If mergeInboundWithTokens is provided, pick the first token's controller address which is present. @@ -345,7 +365,7 @@ export const deployControllerChainContracts = async ( controller = await getOrDeploy( contractName, contractPath, - [mintableToken], + contractArgs, deployParams ); @@ -389,10 +409,24 @@ export const deployVaultChainContracts = async ( deployParams.addresses[SuperBridgeContracts.NonMintableToken] = nonMintableToken; + const contractName = + deployParams.currentTokenType === TokenType.ERC20 + ? SuperBridgeContracts.Vault + : SuperBridgeContracts.NFTVault; + const contractPath = + deployParams.currentTokenType === TokenType.ERC20 + ? "contracts/bridge/Vault.sol" + : "contracts/bridge/NFT/NFTVault.sol"; + const contractArgs = + deployParams.currentTokenType === TokenType.ERC721 + ? [nonMintableToken, "0x73ad2146"] + : deployParams.currentTokenType === TokenType.ERC1155 + ? [nonMintableToken, "0x973bb640"] + : [nonMintableToken]; const vault: Contract = await getOrDeploy( - SuperBridgeContracts.Vault, - "contracts/bridge/Vault.sol", - [nonMintableToken], + contractName, + contractPath, + contractArgs, deployParams ); diff --git a/src/enum.ts b/src/enum.ts index a7d735bf..d584a827 100644 --- a/src/enum.ts +++ b/src/enum.ts @@ -32,6 +32,8 @@ export enum SuperBridgeContracts { FiatTokenV2_1_Controller = "FiatTokenV2_1_Controller", ExchangeRate = "ExchangeRate", ConnectorPlug = "ConnectorPlug", + NFTVault = "NFTVault", + NFTController = "NFTController", } export enum HookContracts { diff --git a/src/types.ts b/src/types.ts index 7cdc4d0d..c17270a9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -7,6 +7,7 @@ import { ProjectType, SuperBridgeContracts, SuperTokenContracts, + TokenType, } from "./enum"; import { NFTs, Project, Tokens } from "./enums"; @@ -130,6 +131,7 @@ export interface DeployParams { signer: Wallet; currentChainSlug: number; currentToken: Tokens | NFTs; + currentTokenType: TokenType; hookType?: Hooks; mergeInboundWithTokens: Tokens[]; tc: TokenConstants; From 9dd3ce6f60cc89cb95d7ae17eb14ef1e4796cbd1 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Wed, 11 Sep 2024 14:56:20 -0400 Subject: [PATCH 07/22] feat: add totalMinted for new NFT project --- contracts/bridge/NFT/NFTController.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/bridge/NFT/NFTController.sol b/contracts/bridge/NFT/NFTController.sol index e5692398..1c60b249 100644 --- a/contracts/bridge/NFT/NFTController.sol +++ b/contracts/bridge/NFT/NFTController.sol @@ -6,6 +6,7 @@ import {IMintableERC721} from "../../interfaces/IMintableERC721.sol"; import {IMintableERC1155} from "../../interfaces/IMintableERC1155.sol"; contract NFTController is NFTBase { + mapping(uint256 => uint256) public totalMinted; bytes4 private interfaceId; constructor(address token_, bytes4 interfaceId_) NFTBase(token_) { @@ -44,6 +45,7 @@ contract NFTController is NFTBase { ); // to maintain socket dl specific accounting for super token + totalMinted[transferInfo.tokenId] -= transferInfo.amount; _burn(msg.sender, transferInfo.tokenId, transferInfo.amount); _afterBridge( msgGasLimit_, @@ -86,6 +88,7 @@ contract NFTController is NFTBase { ); _mint(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + totalMinted[transferInfo.tokenId] += transferInfo.amount; _afterMint(lockAmount, messageId, postHookData, transferInfo); } @@ -105,6 +108,7 @@ contract NFTController is NFTBase { NFTTransferInfo memory transferInfo ) = _beforeRetry(connector_, messageId_); _mint(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); + totalMinted[transferInfo.tokenId] += transferInfo.amount; _afterRetry(connector_, messageId_, postHookData); } From e53dbfa92fa503765c17c928e181d9cc8ddf46f8 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Thu, 19 Sep 2024 10:30:47 -0400 Subject: [PATCH 08/22] feat: add interface for NFT metadata --- contracts/bridge/NFT/NFTBase.sol | 8 ++++++++ contracts/interfaces/INFTMetadata.sol | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 contracts/interfaces/INFTMetadata.sol diff --git a/contracts/bridge/NFT/NFTBase.sol b/contracts/bridge/NFT/NFTBase.sol index e600e9b6..db7b7bef 100644 --- a/contracts/bridge/NFT/NFTBase.sol +++ b/contracts/bridge/NFT/NFTBase.sol @@ -7,6 +7,7 @@ import "solmate/tokens/ERC1155.sol"; import {IConnector} from "../../interfaces/IConnector.sol"; import "../../interfaces/INFTHook.sol"; import "../../interfaces/INFTBridge.sol"; +import "../../interfaces/INFTMetadata.sol"; import "../../common/Errors.sol"; import "../../common/Constants.sol"; import "../../utils/AccessControl.sol"; @@ -254,6 +255,13 @@ abstract contract NFTBase is ReentrancyGuard, INFTBridge, AccessControl { connectorCache[msg.sender] = cacheData.connectorCache; } + if (transferInfo_.extraData.length > 0) { + INFTMetadata(token).setMetadata( + transferInfo_.tokenId, + transferInfo_.extraData + ); + } + emit TokensBridged( msg.sender, transferInfo_.receiver, diff --git a/contracts/interfaces/INFTMetadata.sol b/contracts/interfaces/INFTMetadata.sol new file mode 100644 index 00000000..c4fad67e --- /dev/null +++ b/contracts/interfaces/INFTMetadata.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.3; + +interface INFTMetadata { + function setMetadata(uint256 tokenId, bytes memory data) external; +} From 95dae49dfa0083fa80f02cabfb6fc6bc534b8419 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Fri, 20 Sep 2024 08:39:53 -0400 Subject: [PATCH 09/22] fix: nft bridge --- contracts/bridge/NFT/NFTController.sol | 4 +++- contracts/bridge/NFT/NFTVault.sol | 18 ++++++++++++++---- contracts/interfaces/INFTBridge.sol | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/contracts/bridge/NFT/NFTController.sol b/contracts/bridge/NFT/NFTController.sol index 1c60b249..1aaf4258 100644 --- a/contracts/bridge/NFT/NFTController.sol +++ b/contracts/bridge/NFT/NFTController.sol @@ -20,6 +20,7 @@ contract NFTController is NFTBase { * @notice Bridges tokens between chains. * @dev This function allows bridging tokens between different chains. * @param receiver_ The address to receive the bridged tokens. + * @param tokenOwner_ The owner address of tokens to bridge. * @param tokenId_ The id of token to bridge. * @param amount_ The amount of tokens to bridge. * @param msgGasLimit_ The gas limit for the execution of the bridging process. @@ -29,6 +30,7 @@ contract NFTController is NFTBase { */ function bridge( address receiver_, + address tokenOwner_, uint256 tokenId_, uint256 amount_, uint256 msgGasLimit_, @@ -46,7 +48,7 @@ contract NFTController is NFTBase { // to maintain socket dl specific accounting for super token totalMinted[transferInfo.tokenId] -= transferInfo.amount; - _burn(msg.sender, transferInfo.tokenId, transferInfo.amount); + _burn(tokenOwner_, transferInfo.tokenId, transferInfo.amount); _afterBridge( msgGasLimit_, connector_, diff --git a/contracts/bridge/NFT/NFTVault.sol b/contracts/bridge/NFT/NFTVault.sol index d9704cb2..d701db43 100644 --- a/contracts/bridge/NFT/NFTVault.sol +++ b/contracts/bridge/NFT/NFTVault.sol @@ -28,6 +28,7 @@ contract NFTVault is NFTBase { * @notice Bridges tokens between chains. * @dev This function allows bridging tokens between different chains. * @param receiver_ The address to receive the bridged tokens. + * @param tokenOwner_ The owner address of tokens to bridge. * @param tokenId_ The id of token to bridge. * @param amount_ The amount of tokens to bridge. * @param msgGasLimit_ The gas limit for the execution of the bridging process. @@ -37,6 +38,7 @@ contract NFTVault is NFTBase { */ function bridge( address receiver_, + address tokenOwner_, uint256 tokenId_, uint256 amount_, uint256 msgGasLimit_, @@ -52,7 +54,7 @@ contract NFTVault is NFTBase { NFTTransferInfo(receiver_, tokenId_, amount_, extraData_) ); - _receiveTokens(transferInfo.tokenId, transferInfo.amount); + _receiveTokens(tokenOwner_, transferInfo.tokenId, transferInfo.amount); _afterBridge( msgGasLimit_, @@ -145,13 +147,21 @@ contract NFTVault is NFTBase { } } - function _receiveTokens(uint256 tokenId_, uint256 amount_) internal { + function _receiveTokens( + address tokenOwner_, + uint256 tokenId_, + uint256 amount_ + ) internal { if (amount_ == 0) return; if (bridgeType == ERC721_VAULT) { - ERC721(token).safeTransferFrom(msg.sender, address(this), tokenId_); + ERC721(token).safeTransferFrom( + tokenOwner_, + address(this), + tokenId_ + ); } else { ERC1155(token).safeTransferFrom( - msg.sender, + tokenOwner_, address(this), tokenId_, amount_, diff --git a/contracts/interfaces/INFTBridge.sol b/contracts/interfaces/INFTBridge.sol index 43356bee..cb57a111 100644 --- a/contracts/interfaces/INFTBridge.sol +++ b/contracts/interfaces/INFTBridge.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.3; interface INFTBridge { function bridge( address receiver_, + address tokenOwner_, uint256 tokenId_, uint256 amount_, uint256 msgGasLimit_, From bacb3fe291af60ec6dbece596862bbe74667aec7 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Mon, 23 Sep 2024 22:50:55 -0400 Subject: [PATCH 10/22] fix: build --- contracts/utils/Faucet.sol | 40 +-------------------------- script/admin/updateConnectorStatus.ts | 2 +- script/admin/updateLimits.ts | 4 +-- script/deploy/configure.ts | 6 ++-- script/deploy/deploy.ts | 2 +- script/helpers/common.ts | 4 +-- script/helpers/deployUtils.ts | 2 +- script/helpers/verifyConstants.ts | 2 +- src/types.ts | 2 +- 9 files changed, 13 insertions(+), 51 deletions(-) diff --git a/contracts/utils/Faucet.sol b/contracts/utils/Faucet.sol index 2f6d4ea6..db23ef78 100644 --- a/contracts/utils/Faucet.sol +++ b/contracts/utils/Faucet.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.13; import "solmate/tokens/ERC20.sol"; +import {RescueFundsLib} from "../libraries/RescueFundsLib.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) @@ -151,45 +152,6 @@ library SafeTransferLib { error ZeroAddress(); -/** - * @title RescueFundsLib - * @dev A library that provides a function to rescue funds from a contract. - */ - -library RescueFundsLib { - /** - * @dev The address used to identify ETH. - */ - address public constant ETH_ADDRESS = - address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); - - /** - * @dev thrown when the given token address don't have any code - */ - error InvalidTokenAddress(); - - /** - * @dev Rescues funds from a contract. - * @param token_ The address of the token contract. - * @param rescueTo_ The address of the user. - * @param amount_ The amount of tokens to be rescued. - */ - function rescueFunds( - address token_, - address rescueTo_, - uint256 amount_ - ) internal { - if (rescueTo_ == address(0)) revert ZeroAddress(); - - if (token_ == ETH_ADDRESS) { - SafeTransferLib.safeTransferETH(rescueTo_, amount_); - } else { - if (token_.code.length == 0) revert InvalidTokenAddress(); - SafeTransferLib.safeTransfer(ERC20(token_), rescueTo_, amount_); - } - } -} - /** * @title Ownable * @dev The Ownable contract provides a simple way to manage ownership of a contract diff --git a/script/admin/updateConnectorStatus.ts b/script/admin/updateConnectorStatus.ts index cefea896..98e73941 100644 --- a/script/admin/updateConnectorStatus.ts +++ b/script/admin/updateConnectorStatus.ts @@ -25,7 +25,7 @@ export enum ConnectorStatus { let projectType: ProjectType; let pc: { [token: string]: TokenConstants } = {}; let projectName: string; -let tokens: Tokens[]; +let tokens: string[]; export const main = async () => { try { diff --git a/script/admin/updateLimits.ts b/script/admin/updateLimits.ts index 7e4dd333..1b875f5e 100644 --- a/script/admin/updateLimits.ts +++ b/script/admin/updateLimits.ts @@ -22,7 +22,7 @@ import { import { Tokens } from "../../src/enums"; let pc: { [token: string]: TokenConstants } = {}; -let tokens: Tokens[]; +let tokens: string[]; export const main = async () => { try { @@ -75,7 +75,7 @@ export const main = async () => { ) { await updateLimitsAndPoolId( chain, - token, + token as Tokens, siblingSlugs, addr, connectors, diff --git a/script/deploy/configure.ts b/script/deploy/configure.ts index 5680b421..07a4b391 100644 --- a/script/deploy/configure.ts +++ b/script/deploy/configure.ts @@ -43,7 +43,7 @@ import { getAddresses } from "../constants"; let projectType: ProjectType; let pc: { [token: string]: TokenConstants } = {}; let projectName: string; -let tokens: Tokens[]; +let tokens: string[]; let socketSignerAddress: string; @@ -126,7 +126,7 @@ export const configure = async (allAddresses: SBAddresses | STAddresses) => { await configureHooks( chain, - token, + token as Tokens, bridgeContract, socketSigner, siblingSlugs, @@ -161,7 +161,7 @@ const connect = async ( addr: SBTokenAddresses | STTokenAddresses, addresses: SBAddresses | STAddresses, chain: ChainSlug, - token: Tokens, + token: string, siblingSlugs: ChainSlug[], socketSigner: Wallet ) => { diff --git a/script/deploy/deploy.ts b/script/deploy/deploy.ts index 3618862c..db681193 100644 --- a/script/deploy/deploy.ts +++ b/script/deploy/deploy.ts @@ -138,7 +138,7 @@ const deployChainContracts = async ( isVaultChain: boolean, socketSigner: Wallet, chainSlug: number, - token: Tokens | NFTs, + token: string, tokenType: TokenType, siblings: number[], hookType: Hooks, diff --git a/script/helpers/common.ts b/script/helpers/common.ts index 62b0c777..324e43f6 100644 --- a/script/helpers/common.ts +++ b/script/helpers/common.ts @@ -81,7 +81,7 @@ export const updateConnectorStatus = async ( export const getBridgeContract = async ( chain: ChainSlug, - token: Tokens, + token: string, addr: SBTokenAddresses | STTokenAddresses ) => { const socketSigner = getSignerFromChainSlug(chain); @@ -161,7 +161,7 @@ export const getTokenContract = async ( export const getHookContract = async ( chain: ChainSlug, - token: Tokens, + token: string, addr: SBTokenAddresses | STTokenAddresses ) => { const socketSigner = getSignerFromChainSlug(chain); diff --git a/script/helpers/deployUtils.ts b/script/helpers/deployUtils.ts index 2a9b1896..159f9add 100644 --- a/script/helpers/deployUtils.ts +++ b/script/helpers/deployUtils.ts @@ -219,7 +219,7 @@ export const getSocket = (chain: ChainSlug, signer: Wallet): Contract => { export const storeTokenAddresses = async ( addresses: SBTokenAddresses, chainSlug: ChainSlug, - tokenName: Tokens + tokenName: string ) => { if (getDryRun()) return; diff --git a/script/helpers/verifyConstants.ts b/script/helpers/verifyConstants.ts index 6c226c20..194f2a32 100644 --- a/script/helpers/verifyConstants.ts +++ b/script/helpers/verifyConstants.ts @@ -11,7 +11,7 @@ import { Tokens } from "../../src/enums"; let projectType: ProjectType; let pc: { [token: string]: TokenConstants } = {}; let projectName: string; -let tokens: Tokens[]; +let tokens: string[]; export const verifyConstants = async () => { ({ projectName, projectType, tokens } = getConfigs()); diff --git a/src/types.ts b/src/types.ts index c17270a9..108b9a94 100644 --- a/src/types.ts +++ b/src/types.ts @@ -130,7 +130,7 @@ export interface DeployParams { addresses: SBTokenAddresses | STTokenAddresses; signer: Wallet; currentChainSlug: number; - currentToken: Tokens | NFTs; + currentToken: string; currentTokenType: TokenType; hookType?: Hooks; mergeInboundWithTokens: Tokens[]; From 18626ad022f132d394e058e270cd032de94849ff Mon Sep 17 00:00:00 2001 From: orionstardust Date: Thu, 26 Sep 2024 22:10:22 -0400 Subject: [PATCH 11/22] fix: issues --- script/deploy/deploy.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/script/deploy/deploy.ts b/script/deploy/deploy.ts index db681193..1466c1e4 100644 --- a/script/deploy/deploy.ts +++ b/script/deploy/deploy.ts @@ -329,9 +329,9 @@ export const deployControllerChainContracts = async ( : "contracts/bridge/NFT/NFTController.sol"; contractArgs = deployParams.currentTokenType === TokenType.ERC721 - ? [mintableToken, "0x73ad2146"] + ? [mintableToken, "0x80ac58cd"] : deployParams.currentTokenType === TokenType.ERC1155 - ? [mintableToken, "0x973bb640"] + ? [mintableToken, "0xd9b67a26"] : [mintableToken]; } if (!contractArgs) contractArgs = [mintableToken]; @@ -419,9 +419,9 @@ export const deployVaultChainContracts = async ( : "contracts/bridge/NFT/NFTVault.sol"; const contractArgs = deployParams.currentTokenType === TokenType.ERC721 - ? [nonMintableToken, "0x73ad2146"] + ? [nonMintableToken, "0x80ac58cd"] : deployParams.currentTokenType === TokenType.ERC1155 - ? [nonMintableToken, "0x973bb640"] + ? [nonMintableToken, "0xd9b67a26"] : [nonMintableToken]; const vault: Contract = await getOrDeploy( contractName, From da29b9b99f9fbffdaf3d2148552798f3ff7138ad Mon Sep 17 00:00:00 2001 From: orionstardust Date: Thu, 26 Sep 2024 22:12:08 -0400 Subject: [PATCH 12/22] feat: add script for new NFT project --- ...e_aavegotchi_bridge_testnet_addresses.json | 26 ++++++++++ ...avegotchi_bridge_testnet_verification.json | 52 +++++++++++++++++++ deployments/superbridge/surge_addresses.json | 26 ++++++++++ .../superbridge/aavegotchi_bridge_testnet.ts | 24 +++++++++ socket-plugs-details.json | 5 +- src/enums/projectType.ts | 1 + src/enums/projects.ts | 1 + 7 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json create mode 100644 deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json create mode 100644 script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json new file mode 100644 index 00000000..7c21f4ff --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json @@ -0,0 +1,26 @@ +{ + "80002": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", + "Vault": "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", + "connectors": { + "398274": { + "FAST": "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c" + } + } + } + }, + "398274": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", + "Controller": "0xEa4BE882A0105E44DEF336F8B2d4FB2E317e6877", + "connectors": { + "80002": { + "FAST": "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609" + } + } + } + } +} diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json new file mode 100644 index 00000000..3d38ef36 --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json @@ -0,0 +1,52 @@ +{ + "80002": [ + [ + "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 398274, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + ["0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", "0x80ac58cd"] + ] + ], + "398274": [ + [ + "0xEa4BE882A0105E44DEF336F8B2d4FB2E317e6877", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] + ], + [ + "0x1D19bA288802A1029a6523F5Ff2eb20A4E77bF78", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] + ], + [ + "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x917F1B9Dc82018b10644C4199580c657c81dAbC2", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 80002, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x917F1B9Dc82018b10644C4199580c657c81dAbC2", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] + ] + ] +} diff --git a/deployments/superbridge/surge_addresses.json b/deployments/superbridge/surge_addresses.json index 4feb2952..180d4b66 100644 --- a/deployments/superbridge/surge_addresses.json +++ b/deployments/superbridge/surge_addresses.json @@ -26,5 +26,31 @@ } } } + }, + "aavegotchi_bridge_testnet": { + "80002": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", + "Vault": "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", + "connectors": { + "398274": { + "FAST": "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c" + } + } + } + }, + "398274": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", + "Controller": "0xEa4BE882A0105E44DEF336F8B2d4FB2E317e6877", + "connectors": { + "80002": { + "FAST": "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609" + } + } + } + } } } diff --git a/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts new file mode 100644 index 00000000..c5c7c832 --- /dev/null +++ b/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts @@ -0,0 +1,24 @@ +import { + ChainSlug, + DeploymentMode, + IntegrationTypes, +} from "@socket.tech/dl-core"; +import { Hooks, ProjectConstants } from "../../../../src"; +import { Tokens, NFTs } from "../../../../src/enums"; + +// For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. +export const pc: ProjectConstants = { + [DeploymentMode.SURGE]: { + [NFTs.GOTCHI]: { + vaultChains: [80002], + controllerChains: [398274], + tokenAddresses: { + 80002: "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", + 398274: "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", + }, + hook: { + hookType: Hooks.NO_HOOK, + }, + }, + }, +}; diff --git a/socket-plugs-details.json b/socket-plugs-details.json index 073ec5e8..2ff6d2f9 100644 --- a/socket-plugs-details.json +++ b/socket-plugs-details.json @@ -158,7 +158,8 @@ "timeswap_test_mainnet", "testing_testnet", "magic_mainnet", - "polter_testnet" + "polter_testnet", + "aavegotchi_bridge_testnet" ], "tokens": [ "USDC.e", @@ -183,4 +184,4 @@ "MAGIC", "SUSDE" ] -} \ No newline at end of file +} diff --git a/src/enums/projectType.ts b/src/enums/projectType.ts index 4b91c851..4a7023e5 100644 --- a/src/enums/projectType.ts +++ b/src/enums/projectType.ts @@ -23,4 +23,5 @@ export const ProjectTypeMap: Record = { [Project.TESTING_TESTNET]: ProjectType.SUPERTOKEN, [Project.MAGIC_MAINNET]: ProjectType.SUPERTOKEN, [Project.POLTER_TESTNET]: ProjectType.SUPERBRIDGE, + [Project.AAVEGOTCHI_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, }; diff --git a/src/enums/projects.ts b/src/enums/projects.ts index 04ec0f2f..8b693d64 100644 --- a/src/enums/projects.ts +++ b/src/enums/projects.ts @@ -20,4 +20,5 @@ export enum Project { TESTING_TESTNET = "testing_testnet", MAGIC_MAINNET = "magic_mainnet", POLTER_TESTNET = "polter_testnet", + AAVEGOTCHI_BRIDGE_TESTNET = "aavegotchi_bridge_testnet", } From 49ee3e9f8ae3f43ad5a2c995b7b3d1fce6bc13cf Mon Sep 17 00:00:00 2001 From: orionstardust Date: Tue, 1 Oct 2024 07:06:41 -0400 Subject: [PATCH 13/22] fix: redeploy --- contracts/bridge/NFT/NFTBase.sol | 8 ++++- ...e_aavegotchi_bridge_testnet_addresses.json | 4 +-- ...avegotchi_bridge_testnet_verification.json | 36 +++++++++++++++++++ deployments/superbridge/surge_addresses.json | 4 +-- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/contracts/bridge/NFT/NFTBase.sol b/contracts/bridge/NFT/NFTBase.sol index db7b7bef..57bf93bf 100644 --- a/contracts/bridge/NFT/NFTBase.sol +++ b/contracts/bridge/NFT/NFTBase.sol @@ -12,7 +12,13 @@ import "../../common/Errors.sol"; import "../../common/Constants.sol"; import "../../utils/AccessControl.sol"; -abstract contract NFTBase is ReentrancyGuard, INFTBridge, AccessControl { +abstract contract NFTBase is + ReentrancyGuard, + INFTBridge, + ERC721TokenReceiver, + ERC1155TokenReceiver, + AccessControl +{ address public immutable token; bytes32 public bridgeType; INFTHook public hook__; diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json index 7c21f4ff..56a74187 100644 --- a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json +++ b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json @@ -3,7 +3,7 @@ "GOTCHI": { "isAppChain": false, "NonMintableToken": "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", - "Vault": "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", + "Vault": "0xe07bCa11D493c6f151AE35DdC31EA0Ce1B54Fe9E", "connectors": { "398274": { "FAST": "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c" @@ -15,7 +15,7 @@ "GOTCHI": { "isAppChain": true, "MintableToken": "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", - "Controller": "0xEa4BE882A0105E44DEF336F8B2d4FB2E317e6877", + "Controller": "0x9C7e1dc50c944272a69Ff900E3cB9A59b33E9042", "connectors": { "80002": { "FAST": "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609" diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json index 3d38ef36..8f658dac 100644 --- a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json +++ b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json @@ -1,5 +1,17 @@ { "80002": [ + [ + "0xe07bCa11D493c6f151AE35DdC31EA0Ce1B54Fe9E", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + ["0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", "0x80ac58cd"] + ], + [ + "0x719C25CAdd17534D77e68f2864df5C9465485c46", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + ["0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", "0x80ac58cd"] + ], [ "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c", "ConnectorPlug", @@ -19,6 +31,30 @@ ] ], "398274": [ + [ + "0x9C7e1dc50c944272a69Ff900E3cB9A59b33E9042", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] + ], + [ + "0xc79B1F531DdFd8121CE1E987C30aAC2ae0947ceb", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] + ], + [ + "0x6a5D0A7FF14b9603DaD9cDc84fea1212E3055825", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] + ], + [ + "0x71926eB6ce66949c0b0F078b4Fc88efeE236e563", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] + ], [ "0xEa4BE882A0105E44DEF336F8B2d4FB2E317e6877", "NFTController", diff --git a/deployments/superbridge/surge_addresses.json b/deployments/superbridge/surge_addresses.json index 180d4b66..2348579e 100644 --- a/deployments/superbridge/surge_addresses.json +++ b/deployments/superbridge/surge_addresses.json @@ -32,7 +32,7 @@ "GOTCHI": { "isAppChain": false, "NonMintableToken": "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", - "Vault": "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", + "Vault": "0xe07bCa11D493c6f151AE35DdC31EA0Ce1B54Fe9E", "connectors": { "398274": { "FAST": "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c" @@ -44,7 +44,7 @@ "GOTCHI": { "isAppChain": true, "MintableToken": "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", - "Controller": "0xEa4BE882A0105E44DEF336F8B2d4FB2E317e6877", + "Controller": "0x9C7e1dc50c944272a69Ff900E3cB9A59b33E9042", "connectors": { "80002": { "FAST": "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609" From 9702a595d8b6b999e3d8299a8070b1e1b569844d Mon Sep 17 00:00:00 2001 From: orionstardust Date: Tue, 1 Oct 2024 07:15:36 -0400 Subject: [PATCH 14/22] fix: deployed addresses --- ...avegotchi_bridge_testnet_verification.json | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json index 8f658dac..46e9b9bf 100644 --- a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json +++ b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json @@ -6,12 +6,6 @@ "contracts/bridge/NFT/NFTVault.sol", ["0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", "0x80ac58cd"] ], - [ - "0x719C25CAdd17534D77e68f2864df5C9465485c46", - "NFTVault", - "contracts/bridge/NFT/NFTVault.sol", - ["0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", "0x80ac58cd"] - ], [ "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c", "ConnectorPlug", @@ -22,12 +16,6 @@ 398274, "0x0000000000000000000000000000000000000000000000000000000000000000" ] - ], - [ - "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", - "NFTVault", - "contracts/bridge/NFT/NFTVault.sol", - ["0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", "0x80ac58cd"] ] ], "398274": [ @@ -37,36 +25,6 @@ "contracts/bridge/NFT/NFTController.sol", ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] ], - [ - "0xc79B1F531DdFd8121CE1E987C30aAC2ae0947ceb", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] - ], - [ - "0x6a5D0A7FF14b9603DaD9cDc84fea1212E3055825", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] - ], - [ - "0x71926eB6ce66949c0b0F078b4Fc88efeE236e563", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] - ], - [ - "0xEa4BE882A0105E44DEF336F8B2d4FB2E317e6877", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] - ], - [ - "0x1D19bA288802A1029a6523F5Ff2eb20A4E77bF78", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] - ], [ "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609", "ConnectorPlug", @@ -77,12 +35,6 @@ 80002, "0x0000000000000000000000000000000000000000000000000000000000000000" ] - ], - [ - "0x917F1B9Dc82018b10644C4199580c657c81dAbC2", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] ] ] } From de1df1355c261f38884e611f66432adcc0c7c6ad Mon Sep 17 00:00:00 2001 From: orionstardust Date: Tue, 1 Oct 2024 15:55:58 -0400 Subject: [PATCH 15/22] fix: deployed addresses --- ...e_aavegotchi_bridge_testnet_addresses.json | 26 ------------ ...avegotchi_bridge_testnet_verification.json | 40 ------------------- deployments/superbridge/surge_addresses.json | 10 ++--- 3 files changed, 5 insertions(+), 71 deletions(-) delete mode 100644 deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json delete mode 100644 deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json deleted file mode 100644 index 56a74187..00000000 --- a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "80002": { - "GOTCHI": { - "isAppChain": false, - "NonMintableToken": "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", - "Vault": "0xe07bCa11D493c6f151AE35DdC31EA0Ce1B54Fe9E", - "connectors": { - "398274": { - "FAST": "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c" - } - } - } - }, - "398274": { - "GOTCHI": { - "isAppChain": true, - "MintableToken": "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", - "Controller": "0x9C7e1dc50c944272a69Ff900E3cB9A59b33E9042", - "connectors": { - "80002": { - "FAST": "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609" - } - } - } - } -} diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json deleted file mode 100644 index 46e9b9bf..00000000 --- a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "80002": [ - [ - "0xe07bCa11D493c6f151AE35DdC31EA0Ce1B54Fe9E", - "NFTVault", - "contracts/bridge/NFT/NFTVault.sol", - ["0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", "0x80ac58cd"] - ], - [ - "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c", - "ConnectorPlug", - "contracts/ConnectorPlug.sol", - [ - "0xfc1a9d9898e7a48D75EF6f18F5c042f8fc2E9055", - "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", - 398274, - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - ] - ], - "398274": [ - [ - "0x9C7e1dc50c944272a69Ff900E3cB9A59b33E9042", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", "0x80ac58cd"] - ], - [ - "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609", - "ConnectorPlug", - "contracts/ConnectorPlug.sol", - [ - "0x917F1B9Dc82018b10644C4199580c657c81dAbC2", - "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", - 80002, - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - ] - ] -} diff --git a/deployments/superbridge/surge_addresses.json b/deployments/superbridge/surge_addresses.json index 2348579e..5f0f8c1a 100644 --- a/deployments/superbridge/surge_addresses.json +++ b/deployments/superbridge/surge_addresses.json @@ -32,10 +32,10 @@ "GOTCHI": { "isAppChain": false, "NonMintableToken": "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", - "Vault": "0xe07bCa11D493c6f151AE35DdC31EA0Ce1B54Fe9E", + "Vault": "0x09011fcA980Df5d22E5ff2262051Bc28C430E11c", "connectors": { "398274": { - "FAST": "0x04e77F231c933df16B4cd24fC8B4F33713E8e79c" + "FAST": "0x6f1978CF0D213eFBF4A173d499219AbeEa01e597" } } } @@ -44,13 +44,13 @@ "GOTCHI": { "isAppChain": true, "MintableToken": "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", - "Controller": "0x9C7e1dc50c944272a69Ff900E3cB9A59b33E9042", + "Controller": "0x38161F1a033D86aea6D222AEdE57702046414CA5", "connectors": { "80002": { - "FAST": "0x672ebFd9dC326211cAC7f91465a576cf0B0aB609" + "FAST": "0xCfDA1E919F0b9B9fAbb6863dBF662B7fa688D2fD" } } } } } -} +} \ No newline at end of file From 46d379e09eb003b18f0b02f1560fca40e5b2b95e Mon Sep 17 00:00:00 2001 From: orionstardust Date: Wed, 16 Oct 2024 16:15:15 -0400 Subject: [PATCH 16/22] fix: mint wearables --- contracts/bridge/NFT/NFTBase.sol | 7 +++++-- contracts/bridge/NFT/NFTController.sol | 2 +- contracts/bridge/NFT/NFTVault.sol | 2 +- contracts/interfaces/INFTMetadata.sol | 6 +++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/contracts/bridge/NFT/NFTBase.sol b/contracts/bridge/NFT/NFTBase.sol index 57bf93bf..6c7e400d 100644 --- a/contracts/bridge/NFT/NFTBase.sol +++ b/contracts/bridge/NFT/NFTBase.sol @@ -239,12 +239,14 @@ abstract contract NFTBase is * @param messageId_ The unique identifier for the mint transaction. * @param postHookData_ Data returned from the destination pre-hook call. * @param transferInfo_ Information about the mint transaction. + * @param isMint_ mint or transfer */ function _afterMint( uint256, bytes32 messageId_, bytes memory postHookData_, - NFTTransferInfo memory transferInfo_ + NFTTransferInfo memory transferInfo_, + bool isMint_ ) internal { if (address(hook__) != address(0)) { CacheData memory cacheData = hook__.dstPostHookCall( @@ -264,7 +266,8 @@ abstract contract NFTBase is if (transferInfo_.extraData.length > 0) { INFTMetadata(token).setMetadata( transferInfo_.tokenId, - transferInfo_.extraData + transferInfo_.extraData, + isMint_ ); } diff --git a/contracts/bridge/NFT/NFTController.sol b/contracts/bridge/NFT/NFTController.sol index 1aaf4258..0944b5a4 100644 --- a/contracts/bridge/NFT/NFTController.sol +++ b/contracts/bridge/NFT/NFTController.sol @@ -92,7 +92,7 @@ contract NFTController is NFTBase { _mint(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); totalMinted[transferInfo.tokenId] += transferInfo.amount; - _afterMint(lockAmount, messageId, postHookData, transferInfo); + _afterMint(lockAmount, messageId, postHookData, transferInfo, true); } /** diff --git a/contracts/bridge/NFT/NFTVault.sol b/contracts/bridge/NFT/NFTVault.sol index d701db43..78f6f9a9 100644 --- a/contracts/bridge/NFT/NFTVault.sol +++ b/contracts/bridge/NFT/NFTVault.sol @@ -102,7 +102,7 @@ contract NFTVault is NFTBase { transferInfo.amount ); - _afterMint(unlockAmount, messageId, postHookData, transferInfo); + _afterMint(unlockAmount, messageId, postHookData, transferInfo, false); } /** diff --git a/contracts/interfaces/INFTMetadata.sol b/contracts/interfaces/INFTMetadata.sol index c4fad67e..1a466773 100644 --- a/contracts/interfaces/INFTMetadata.sol +++ b/contracts/interfaces/INFTMetadata.sol @@ -2,5 +2,9 @@ pragma solidity ^0.8.3; interface INFTMetadata { - function setMetadata(uint256 tokenId, bytes memory data) external; + function setMetadata( + uint256 tokenId, + bytes memory data, + bool isMint + ) external; } From 3684045d463ef7023c9b9efe3804377f547c9b11 Mon Sep 17 00:00:00 2001 From: orionstardust Date: Fri, 25 Oct 2024 23:19:05 -0400 Subject: [PATCH 17/22] Revert "fix: mint wearables" This reverts commit 46d379e09eb003b18f0b02f1560fca40e5b2b95e. --- contracts/bridge/NFT/NFTBase.sol | 7 ++----- contracts/bridge/NFT/NFTController.sol | 2 +- contracts/bridge/NFT/NFTVault.sol | 2 +- contracts/interfaces/INFTMetadata.sol | 6 +----- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/contracts/bridge/NFT/NFTBase.sol b/contracts/bridge/NFT/NFTBase.sol index 6c7e400d..57bf93bf 100644 --- a/contracts/bridge/NFT/NFTBase.sol +++ b/contracts/bridge/NFT/NFTBase.sol @@ -239,14 +239,12 @@ abstract contract NFTBase is * @param messageId_ The unique identifier for the mint transaction. * @param postHookData_ Data returned from the destination pre-hook call. * @param transferInfo_ Information about the mint transaction. - * @param isMint_ mint or transfer */ function _afterMint( uint256, bytes32 messageId_, bytes memory postHookData_, - NFTTransferInfo memory transferInfo_, - bool isMint_ + NFTTransferInfo memory transferInfo_ ) internal { if (address(hook__) != address(0)) { CacheData memory cacheData = hook__.dstPostHookCall( @@ -266,8 +264,7 @@ abstract contract NFTBase is if (transferInfo_.extraData.length > 0) { INFTMetadata(token).setMetadata( transferInfo_.tokenId, - transferInfo_.extraData, - isMint_ + transferInfo_.extraData ); } diff --git a/contracts/bridge/NFT/NFTController.sol b/contracts/bridge/NFT/NFTController.sol index 0944b5a4..1aaf4258 100644 --- a/contracts/bridge/NFT/NFTController.sol +++ b/contracts/bridge/NFT/NFTController.sol @@ -92,7 +92,7 @@ contract NFTController is NFTBase { _mint(transferInfo.receiver, transferInfo.tokenId, transferInfo.amount); totalMinted[transferInfo.tokenId] += transferInfo.amount; - _afterMint(lockAmount, messageId, postHookData, transferInfo, true); + _afterMint(lockAmount, messageId, postHookData, transferInfo); } /** diff --git a/contracts/bridge/NFT/NFTVault.sol b/contracts/bridge/NFT/NFTVault.sol index 78f6f9a9..d701db43 100644 --- a/contracts/bridge/NFT/NFTVault.sol +++ b/contracts/bridge/NFT/NFTVault.sol @@ -102,7 +102,7 @@ contract NFTVault is NFTBase { transferInfo.amount ); - _afterMint(unlockAmount, messageId, postHookData, transferInfo, false); + _afterMint(unlockAmount, messageId, postHookData, transferInfo); } /** diff --git a/contracts/interfaces/INFTMetadata.sol b/contracts/interfaces/INFTMetadata.sol index 1a466773..c4fad67e 100644 --- a/contracts/interfaces/INFTMetadata.sol +++ b/contracts/interfaces/INFTMetadata.sol @@ -2,9 +2,5 @@ pragma solidity ^0.8.3; interface INFTMetadata { - function setMetadata( - uint256 tokenId, - bytes memory data, - bool isMint - ) external; + function setMetadata(uint256 tokenId, bytes memory data) external; } From d019431b411e380371f2641511b4f3051bd6b0df Mon Sep 17 00:00:00 2001 From: orionstardust Date: Mon, 4 Nov 2024 00:04:34 -0500 Subject: [PATCH 18/22] fix: test gotchi and items --- ...e_aavegotchi_bridge_testnet_addresses.json | 26 ++++++++++ ...avegotchi_bridge_testnet_verification.json | 40 ++++++++++++++++ ...egotchi_item_bridge_testnet_addresses.json | 26 ++++++++++ ...tchi_item_bridge_testnet_verification.json | 40 ++++++++++++++++ deployments/superbridge/surge_addresses.json | 48 ++++++++++++++----- .../superbridge/aavegotchi_bridge_testnet.ts | 10 ++-- .../aavegotchi_item_bridge_testnet.ts | 24 ++++++++++ src/enums/projectType.ts | 1 + src/enums/projects.ts | 1 + 9 files changed, 200 insertions(+), 16 deletions(-) create mode 100644 deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json create mode 100644 deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json create mode 100644 deployments/superbridge/surge_aavegotchi_item_bridge_testnet_addresses.json create mode 100644 deployments/superbridge/surge_aavegotchi_item_bridge_testnet_verification.json create mode 100644 script/constants/projectConstants/superbridge/aavegotchi_item_bridge_testnet.ts diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json new file mode 100644 index 00000000..273053f6 --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json @@ -0,0 +1,26 @@ +{ + "84532": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "Vault": "0x110A646276961C2d8a54b951bbC8B169E0F573c4", + "connectors": { + "631571": { + "FAST": "0xd912F40C27E317db2334e210de892e9dc92816af" + } + } + } + }, + "631571": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", + "Controller": "0x5ABB7E28160f82A84e389aDcc9d8CE3F7a0C8D92", + "connectors": { + "84532": { + "FAST": "0xE7af5160334aded39DD9826cBcBa0B51A1B184e9" + } + } + } + } +} diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json new file mode 100644 index 00000000..4ace912b --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json @@ -0,0 +1,40 @@ +{ + "84532": [ + [ + "0xd912F40C27E317db2334e210de892e9dc92816af", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x110A646276961C2d8a54b951bbC8B169E0F573c4", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 631571, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x110A646276961C2d8a54b951bbC8B169E0F573c4", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + ["0x87C969d083189927049f8fF3747703FB9f7a8AEd", "0x80ac58cd"] + ] + ], + "631571": [ + [ + "0xE7af5160334aded39DD9826cBcBa0B51A1B184e9", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x5ABB7E28160f82A84e389aDcc9d8CE3F7a0C8D92", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 84532, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x5ABB7E28160f82A84e389aDcc9d8CE3F7a0C8D92", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", "0x80ac58cd"] + ] + ] +} diff --git a/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_addresses.json new file mode 100644 index 00000000..a641785e --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_addresses.json @@ -0,0 +1,26 @@ +{ + "84532": { + "GOTCHI_ITEM": { + "isAppChain": false, + "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "Vault": "0x130119B300049A80C20B2D3bfdFCfd021373E5e7", + "connectors": { + "631571": { + "FAST": "0xb8388b23222876FAC04b464fA0d6A064c67A14FC" + } + } + } + }, + "631571": { + "GOTCHI_ITEM": { + "isAppChain": true, + "MintableToken": "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", + "Controller": "0x10Cf0D5C1986a7Aa98aDb3bfa3529c1BBDa59FB9", + "connectors": { + "84532": { + "FAST": "0x27fA28c1f241E5dEA9AA583751E5D968a28FD9D5" + } + } + } + } +} diff --git a/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_verification.json new file mode 100644 index 00000000..ee1b0c77 --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_verification.json @@ -0,0 +1,40 @@ +{ + "84532": [ + [ + "0xb8388b23222876FAC04b464fA0d6A064c67A14FC", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x130119B300049A80C20B2D3bfdFCfd021373E5e7", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 631571, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x130119B300049A80C20B2D3bfdFCfd021373E5e7", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + ["0x87C969d083189927049f8fF3747703FB9f7a8AEd", "0xd9b67a26"] + ] + ], + "631571": [ + [ + "0x27fA28c1f241E5dEA9AA583751E5D968a28FD9D5", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x10Cf0D5C1986a7Aa98aDb3bfa3529c1BBDa59FB9", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 84532, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x10Cf0D5C1986a7Aa98aDb3bfa3529c1BBDa59FB9", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + ["0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", "0xd9b67a26"] + ] + ] +} diff --git a/deployments/superbridge/surge_addresses.json b/deployments/superbridge/surge_addresses.json index 5f0f8c1a..8d64820b 100644 --- a/deployments/superbridge/surge_addresses.json +++ b/deployments/superbridge/surge_addresses.json @@ -28,29 +28,55 @@ } }, "aavegotchi_bridge_testnet": { - "80002": { + "84532": { "GOTCHI": { "isAppChain": false, - "NonMintableToken": "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", - "Vault": "0x09011fcA980Df5d22E5ff2262051Bc28C430E11c", + "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "Vault": "0x110A646276961C2d8a54b951bbC8B169E0F573c4", "connectors": { - "398274": { - "FAST": "0x6f1978CF0D213eFBF4A173d499219AbeEa01e597" + "631571": { + "FAST": "0xd912F40C27E317db2334e210de892e9dc92816af" } } } }, - "398274": { + "631571": { "GOTCHI": { "isAppChain": true, - "MintableToken": "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", - "Controller": "0x38161F1a033D86aea6D222AEdE57702046414CA5", + "MintableToken": "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", + "Controller": "0x5ABB7E28160f82A84e389aDcc9d8CE3F7a0C8D92", + "connectors": { + "84532": { + "FAST": "0xE7af5160334aded39DD9826cBcBa0B51A1B184e9" + } + } + } + } + }, + "aavegotchi_item_bridge_testnet": { + "84532": { + "GOTCHI_ITEM": { + "isAppChain": false, + "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "Vault": "0x130119B300049A80C20B2D3bfdFCfd021373E5e7", + "connectors": { + "631571": { + "FAST": "0xb8388b23222876FAC04b464fA0d6A064c67A14FC" + } + } + } + }, + "631571": { + "GOTCHI_ITEM": { + "isAppChain": true, + "MintableToken": "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", + "Controller": "0x10Cf0D5C1986a7Aa98aDb3bfa3529c1BBDa59FB9", "connectors": { - "80002": { - "FAST": "0xCfDA1E919F0b9B9fAbb6863dBF662B7fa688D2fD" + "84532": { + "FAST": "0x27fA28c1f241E5dEA9AA583751E5D968a28FD9D5" } } } } } -} \ No newline at end of file +} diff --git a/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts index c5c7c832..ca4d0b9c 100644 --- a/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts +++ b/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts @@ -4,17 +4,17 @@ import { IntegrationTypes, } from "@socket.tech/dl-core"; import { Hooks, ProjectConstants } from "../../../../src"; -import { Tokens, NFTs } from "../../../../src/enums"; +import { NFTs, Tokens } from "../../../../src/enums"; // For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. export const pc: ProjectConstants = { [DeploymentMode.SURGE]: { [NFTs.GOTCHI]: { - vaultChains: [80002], - controllerChains: [398274], + vaultChains: [84532], + controllerChains: [631571], tokenAddresses: { - 80002: "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb", - 398274: "0x6b54b36A54b068152f0f39FdA0Bf96e02176D95B", + 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + 631571: "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", }, hook: { hookType: Hooks.NO_HOOK, diff --git a/script/constants/projectConstants/superbridge/aavegotchi_item_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_item_bridge_testnet.ts new file mode 100644 index 00000000..a02fa9e8 --- /dev/null +++ b/script/constants/projectConstants/superbridge/aavegotchi_item_bridge_testnet.ts @@ -0,0 +1,24 @@ +import { + ChainSlug, + DeploymentMode, + IntegrationTypes, +} from "@socket.tech/dl-core"; +import { Hooks, ProjectConstants } from "../../../../src"; +import { NFTs, Tokens } from "../../../../src/enums"; + +// For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. +export const pc: ProjectConstants = { + [DeploymentMode.SURGE]: { + [NFTs.GOTCHI_ITEM]: { + vaultChains: [84532], + controllerChains: [631571], + tokenAddresses: { + 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + 631571: "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", + }, + hook: { + hookType: Hooks.NO_HOOK, + }, + }, + }, +}; diff --git a/src/enums/projectType.ts b/src/enums/projectType.ts index 4a7023e5..992156f5 100644 --- a/src/enums/projectType.ts +++ b/src/enums/projectType.ts @@ -24,4 +24,5 @@ export const ProjectTypeMap: Record = { [Project.MAGIC_MAINNET]: ProjectType.SUPERTOKEN, [Project.POLTER_TESTNET]: ProjectType.SUPERBRIDGE, [Project.AAVEGOTCHI_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, + [Project.AAVEGOTCHI_ITEM_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, }; diff --git a/src/enums/projects.ts b/src/enums/projects.ts index 8b693d64..45f3abff 100644 --- a/src/enums/projects.ts +++ b/src/enums/projects.ts @@ -21,4 +21,5 @@ export enum Project { MAGIC_MAINNET = "magic_mainnet", POLTER_TESTNET = "polter_testnet", AAVEGOTCHI_BRIDGE_TESTNET = "aavegotchi_bridge_testnet", + AAVEGOTCHI_ITEM_BRIDGE_TESTNET = "aavegotchi_item_bridge_testnet", } From 4155e7412a02548be435087918b05b0810a43458 Mon Sep 17 00:00:00 2001 From: Coderdan Date: Wed, 20 Nov 2024 11:56:16 +0800 Subject: [PATCH 19/22] chore: add scripts and update address --- ...otchi_gotchi_bridge_testnet_addresses.json | 26 +++ ...i_gotchi_bridge_testnet_verification.json} | 24 ++- ...otchi_items_bridge_testnet_addresses.json} | 12 +- ...chi_items_bridge_testnet_verification.json | 46 +++++ deployments/superbridge/surge_addresses.json | 54 +++++- package.json | 4 +- script/bridge/bridgeERC1155.ts | 182 ++++++++++++++++++ script/bridge/bridgeERC721.ts | 181 +++++++++++++++++ script/constants/deploymentConfig.ts | 2 + .../aavegotchi_gotchi_bridge_testnet.ts | 25 +++ ....ts => aavegotchi_items_bridge_testnet.ts} | 11 +- script/helpers/common.ts | 26 ++- script/helpers/networks.ts | 6 + src/enums/projectType.ts | 4 +- src/enums/projects.ts | 4 +- 15 files changed, 576 insertions(+), 31 deletions(-) create mode 100644 deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json rename deployments/superbridge/{surge_aavegotchi_item_bridge_testnet_verification.json => surge_aavegotchi_gotchi_bridge_testnet_verification.json} (57%) rename deployments/superbridge/{surge_aavegotchi_item_bridge_testnet_addresses.json => surge_aavegotchi_items_bridge_testnet_addresses.json} (51%) create mode 100644 deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json create mode 100644 script/bridge/bridgeERC1155.ts create mode 100644 script/bridge/bridgeERC721.ts create mode 100644 script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts rename script/constants/projectConstants/superbridge/{aavegotchi_item_bridge_testnet.ts => aavegotchi_items_bridge_testnet.ts} (85%) diff --git a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json new file mode 100644 index 00000000..fa55d457 --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json @@ -0,0 +1,26 @@ +{ + "84532": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "Vault": "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", + "connectors": { + "631571": { + "FAST": "0x3C43820A77d3Ff7Df81f212851857c46684f8b2F" + } + } + } + }, + "631571": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0xD66C6C61D5a535eD69E3769582895daec28a4651", + "Controller": "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", + "connectors": { + "84532": { + "FAST": "0x3A643fc25C721971314119a50a7fdF18385b7eD9" + } + } + } + } +} \ No newline at end of file diff --git a/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json similarity index 57% rename from deployments/superbridge/surge_aavegotchi_item_bridge_testnet_verification.json rename to deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json index ee1b0c77..5b23ddef 100644 --- a/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_verification.json +++ b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json @@ -1,40 +1,46 @@ { "84532": [ [ - "0xb8388b23222876FAC04b464fA0d6A064c67A14FC", + "0x3C43820A77d3Ff7Df81f212851857c46684f8b2F", "ConnectorPlug", "contracts/ConnectorPlug.sol", [ - "0x130119B300049A80C20B2D3bfdFCfd021373E5e7", + "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", 631571, "0x0000000000000000000000000000000000000000000000000000000000000000" ] ], [ - "0x130119B300049A80C20B2D3bfdFCfd021373E5e7", + "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", "NFTVault", "contracts/bridge/NFT/NFTVault.sol", - ["0x87C969d083189927049f8fF3747703FB9f7a8AEd", "0xd9b67a26"] + [ + "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "0x80ac58cd" + ] ] ], "631571": [ [ - "0x27fA28c1f241E5dEA9AA583751E5D968a28FD9D5", + "0x3A643fc25C721971314119a50a7fdF18385b7eD9", "ConnectorPlug", "contracts/ConnectorPlug.sol", [ - "0x10Cf0D5C1986a7Aa98aDb3bfa3529c1BBDa59FB9", + "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", 84532, "0x0000000000000000000000000000000000000000000000000000000000000000" ] ], [ - "0x10Cf0D5C1986a7Aa98aDb3bfa3529c1BBDa59FB9", + "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", "NFTController", "contracts/bridge/NFT/NFTController.sol", - ["0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", "0xd9b67a26"] + [ + "0xD66C6C61D5a535eD69E3769582895daec28a4651", + "0x80ac58cd" + ] ] ] -} +} \ No newline at end of file diff --git a/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_addresses.json similarity index 51% rename from deployments/superbridge/surge_aavegotchi_item_bridge_testnet_addresses.json rename to deployments/superbridge/surge_aavegotchi_items_bridge_testnet_addresses.json index a641785e..3ecf987b 100644 --- a/deployments/superbridge/surge_aavegotchi_item_bridge_testnet_addresses.json +++ b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_addresses.json @@ -3,10 +3,10 @@ "GOTCHI_ITEM": { "isAppChain": false, "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - "Vault": "0x130119B300049A80C20B2D3bfdFCfd021373E5e7", + "Vault": "0x2709f098E8C641796B495bED28A34F9FEA858ac8", "connectors": { "631571": { - "FAST": "0xb8388b23222876FAC04b464fA0d6A064c67A14FC" + "FAST": "0xB2B948d421Ce7c0eC075a073682236269614D32d" } } } @@ -14,13 +14,13 @@ "631571": { "GOTCHI_ITEM": { "isAppChain": true, - "MintableToken": "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", - "Controller": "0x10Cf0D5C1986a7Aa98aDb3bfa3529c1BBDa59FB9", + "MintableToken": "0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334", + "Controller": "0x60d629c876E455eFdca83e2b4c85DfB9d4C3C58C", "connectors": { "84532": { - "FAST": "0x27fA28c1f241E5dEA9AA583751E5D968a28FD9D5" + "FAST": "0xc14Bc9857A27b428b3eB84cB561412a42C9B9798" } } } } -} +} \ No newline at end of file diff --git a/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json new file mode 100644 index 00000000..5166f569 --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json @@ -0,0 +1,46 @@ +{ + "84532": [ + [ + "0xB2B948d421Ce7c0eC075a073682236269614D32d", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x2709f098E8C641796B495bED28A34F9FEA858ac8", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 631571, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x2709f098E8C641796B495bED28A34F9FEA858ac8", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + [ + "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "0xd9b67a26" + ] + ] + ], + "631571": [ + [ + "0xc14Bc9857A27b428b3eB84cB561412a42C9B9798", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x60d629c876E455eFdca83e2b4c85DfB9d4C3C58C", + "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", + 84532, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x60d629c876E455eFdca83e2b4c85DfB9d4C3C58C", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + [ + "0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334", + "0xd9b67a26" + ] + ] + ] +} \ No newline at end of file diff --git a/deployments/superbridge/surge_addresses.json b/deployments/superbridge/surge_addresses.json index 8d64820b..68b80f89 100644 --- a/deployments/superbridge/surge_addresses.json +++ b/deployments/superbridge/surge_addresses.json @@ -78,5 +78,57 @@ } } } + }, + "aavegotchi_gotchi_bridge_testnet": { + "84532": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "Vault": "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", + "connectors": { + "631571": { + "FAST": "0x3C43820A77d3Ff7Df81f212851857c46684f8b2F" + } + } + } + }, + "631571": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0xD66C6C61D5a535eD69E3769582895daec28a4651", + "Controller": "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", + "connectors": { + "84532": { + "FAST": "0x3A643fc25C721971314119a50a7fdF18385b7eD9" + } + } + } + } + }, + "aavegotchi_items_bridge_testnet": { + "84532": { + "GOTCHI_ITEM": { + "isAppChain": false, + "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + "Vault": "0x2709f098E8C641796B495bED28A34F9FEA858ac8", + "connectors": { + "631571": { + "FAST": "0xB2B948d421Ce7c0eC075a073682236269614D32d" + } + } + } + }, + "631571": { + "GOTCHI_ITEM": { + "isAppChain": true, + "MintableToken": "0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334", + "Controller": "0x60d629c876E455eFdca83e2b4c85DfB9d4C3C58C", + "connectors": { + "84532": { + "FAST": "0xc14Bc9857A27b428b3eB84cB561412a42C9B9798" + } + } + } + } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index fac34c38..88715160 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,9 @@ "project:edit": "npx ts-node script/script.ts edit", "project:addToken": "npx ts-node script/script.ts addToken", "project:addNFT": "npx ts-node script/script.ts addNFT", - "bridge": "npx hardhat run script/bridge/bridge.ts" + "bridge": "npx hardhat run script/bridge/bridge.ts", + "bridgeERC721": "npx hardhat run script/bridge/bridgeERC721.ts", + "bridgeERC1155": "npx hardhat run script/bridge/bridgeERC1155.ts" }, "pre-commit": [ "lint", diff --git a/script/bridge/bridgeERC1155.ts b/script/bridge/bridgeERC1155.ts new file mode 100644 index 00000000..4296582d --- /dev/null +++ b/script/bridge/bridgeERC1155.ts @@ -0,0 +1,182 @@ +import { BigNumber, utils } from "ethers"; + +import { ChainSlug } from "@socket.tech/dl-core"; +import yargs from "yargs"; +import { + SBAddresses, + SBTokenAddresses, + STAddresses, + STTokenAddresses, +} from "../../src"; +import { Tokens, tokenDecimals } from "../../src/enums"; +import { getProjectAddresses } from "../helpers"; +import { getBridgeContract, getTokenContract } from "../helpers/common"; +import { getOverrides, getSignerFromChainSlug } from "../helpers/networks"; +import { checkSendingLimit, getDLAPIBaseUrl } from "./utils"; + +const gasLimit = 500_000; + +export const main = async () => { + try { + // const argv = await yargs + // .option({ + // srcChain: { + // description: "srcChainSlug", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // dstChain: { + // description: "dstChainSlug", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // amount: { + // description: "token amount to bridge (formatted value)", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // tokenId: { + // description: "tokenId", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // token: { + // description: "token", + // type: "string", + // demandOption: true, + // }, + // }).argv; + + const srcChain = 84532 as ChainSlug; //Number(argv.srcChain) as ChainSlug; + const dstChain = 631571 as ChainSlug; //Number(argv.dstChain) as ChainSlug; + const amount = 1; + const token = "GOTCHI_ITEM" as Tokens; + const tokenId = "151"; //argv.tokenId; + + // if (!Object.values(Tokens).includes(token)) + // throw Error("token not allowed"); + + const amountBN = utils.parseUnits(amount.toString(), tokenDecimals[token]); + + let addresses: SBAddresses | STAddresses | undefined = + getProjectAddresses(); + + console.log("addresses:", addresses); + + const srcAddresses: SBTokenAddresses | STTokenAddresses | undefined = + addresses[srcChain]?.[token]; + + console.log("srcAddresses:", srcAddresses); + + const dstAddresses: SBTokenAddresses | STTokenAddresses | undefined = + addresses[dstChain]?.[token]; + + console.log("dstAddresses:", dstAddresses); + if (!srcAddresses || !dstAddresses) + throw new Error("chain addresses not found"); + + const bridgeContract = await getBridgeContract( + srcChain, + token, + srcAddresses, + "ERC1155" + ); + const tokenContract = await getTokenContract( + srcChain, + token, + srcAddresses, + "ERC1155" + ); + const connectorAddr = srcAddresses.connectors?.[dstChain]?.FAST; + + if (!connectorAddr) throw new Error("connector contract addresses missing"); + + const socketSigner = getSignerFromChainSlug(srcChain); + + console.log("checking balance and approval..."); + // approve + const balance: BigNumber = await tokenContract.balanceOf( + socketSigner.address, + tokenId + ); + + console.log("balance:", balance); + + // if (balance.lt(amountBN)) throw new Error("Not enough balance"); + + const currentApproval: boolean = await tokenContract.isApprovedForAll( + socketSigner.address, + bridgeContract.address + ); + if (!currentApproval) { + const approveTx = await tokenContract.setApprovalForAll( + bridgeContract.address, + true, + { + ...getOverrides(srcChain), + } + ); + console.log("Tokens approved: ", approveTx.hash); + await approveTx.wait(); + } + + console.log("checking sending limit..."); + await checkSendingLimit( + srcChain, + token, + srcAddresses, + connectorAddr, + amountBN + ); + + // deposit + console.log(`depositing ${amount} to ${dstChain} from ${srcChain}`); + const fees = await bridgeContract.getMinFees(connectorAddr, gasLimit, 0); + + // address receiver_, + // address tokenOwner_, + // uint256 tokenId_, + // uint256 amount_, + // uint256 msgGasLimit_, + // address connector_, + + console.log("address:", socketSigner.address); + + const depositTx = await bridgeContract.bridge( + "0xC3c2e1Cf099Bc6e1fA94ce358562BCbD5cc59FE5", + "0xC3c2e1Cf099Bc6e1fA94ce358562BCbD5cc59FE5", + tokenId, + amount, + gasLimit, + connectorAddr, + "0x", + "0x", + + { ...getOverrides(srcChain), value: fees } + ); + console.log("Tokens deposited: ", depositTx.hash); + console.log( + `Track message here: ${getDLAPIBaseUrl()}/messages-from-tx?srcChainSlug=${srcChain}&srcTxHash=${ + depositTx.hash + }` + ); + await depositTx.wait(); + } catch (error) { + console.log("Error while sending transaction", error); + } +}; + +main() + .then(() => process.exit(0)) + .catch((error: Error) => { + console.error(error); + process.exit(1); + }); diff --git a/script/bridge/bridgeERC721.ts b/script/bridge/bridgeERC721.ts new file mode 100644 index 00000000..d903eaaf --- /dev/null +++ b/script/bridge/bridgeERC721.ts @@ -0,0 +1,181 @@ +import { BigNumber, utils } from "ethers"; + +import { ChainSlug } from "@socket.tech/dl-core"; +import yargs from "yargs"; +import { + SBAddresses, + SBTokenAddresses, + STAddresses, + STTokenAddresses, +} from "../../src"; +import { Tokens, tokenDecimals } from "../../src/enums"; +import { getProjectAddresses } from "../helpers"; +import { getBridgeContract, getTokenContract } from "../helpers/common"; +import { getOverrides, getSignerFromChainSlug } from "../helpers/networks"; +import { checkSendingLimit, getDLAPIBaseUrl } from "./utils"; + +const gasLimit = 500_000; + +export const main = async () => { + try { + // const argv = await yargs + // .option({ + // srcChain: { + // description: "srcChainSlug", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // dstChain: { + // description: "dstChainSlug", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // amount: { + // description: "token amount to bridge (formatted value)", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // tokenId: { + // description: "tokenId", + // type: "string", + // demandOption: true, + // }, + // }) + // .option({ + // token: { + // description: "token", + // type: "string", + // demandOption: true, + // }, + // }).argv; + + const srcChain = 84532 as ChainSlug; //Number(argv.srcChain) as ChainSlug; + const dstChain = 631571 as ChainSlug; //Number(argv.dstChain) as ChainSlug; + const amount = 1; + const token = "GOTCHI" as Tokens; + const tokenId = "511"; //argv.tokenId; + + // if (!Object.values(Tokens).includes(token)) + // throw Error("token not allowed"); + + const amountBN = utils.parseUnits(amount.toString(), tokenDecimals[token]); + + let addresses: SBAddresses | STAddresses | undefined = + getProjectAddresses(); + + console.log("addresses:", addresses); + + const srcAddresses: SBTokenAddresses | STTokenAddresses | undefined = + addresses[srcChain]?.[token]; + + console.log("srcAddresses:", srcAddresses); + + const dstAddresses: SBTokenAddresses | STTokenAddresses | undefined = + addresses[dstChain]?.[token]; + + console.log("dstAddresses:", dstAddresses); + if (!srcAddresses || !dstAddresses) + throw new Error("chain addresses not found"); + + const bridgeContract = await getBridgeContract( + srcChain, + token, + srcAddresses, + "ERC721" + ); + const tokenContract = await getTokenContract( + srcChain, + token, + srcAddresses, + "ERC721" + ); + const connectorAddr = srcAddresses.connectors?.[dstChain]?.FAST; + + if (!connectorAddr) throw new Error("connector contract addresses missing"); + + const socketSigner = getSignerFromChainSlug(srcChain); + + console.log("checking balance and approval..."); + // approve + const balance: BigNumber = await tokenContract.balanceOf( + socketSigner.address + ); + + console.log("balance:", balance); + + // if (balance.lt(amountBN)) throw new Error("Not enough balance"); + + const currentApproval: boolean = await tokenContract.isApprovedForAll( + socketSigner.address, + bridgeContract.address + ); + if (!currentApproval) { + const approveTx = await tokenContract.setApprovalForAll( + bridgeContract.address, + true, + { + ...getOverrides(srcChain), + } + ); + console.log("Tokens approved: ", approveTx.hash); + await approveTx.wait(); + } + + console.log("checking sending limit..."); + await checkSendingLimit( + srcChain, + token, + srcAddresses, + connectorAddr, + amountBN + ); + + // deposit + console.log(`depositing ${amount} to ${dstChain} from ${srcChain}`); + const fees = await bridgeContract.getMinFees(connectorAddr, gasLimit, 0); + + // address receiver_, + // address tokenOwner_, + // uint256 tokenId_, + // uint256 amount_, + // uint256 msgGasLimit_, + // address connector_, + + console.log("address:", socketSigner.address); + + const depositTx = await bridgeContract.bridge( + "0xC3c2e1Cf099Bc6e1fA94ce358562BCbD5cc59FE5", + "0xC3c2e1Cf099Bc6e1fA94ce358562BCbD5cc59FE5", + tokenId, + amount, + gasLimit, + connectorAddr, + "0x", + "0x", + + { ...getOverrides(srcChain), value: fees } + ); + console.log("Tokens deposited: ", depositTx.hash); + console.log( + `Track message here: ${getDLAPIBaseUrl()}/messages-from-tx?srcChainSlug=${srcChain}&srcTxHash=${ + depositTx.hash + }` + ); + await depositTx.wait(); + } catch (error) { + console.log("Error while sending transaction", error); + } +}; + +main() + .then(() => process.exit(0)) + .catch((error: Error) => { + console.error(error); + process.exit(1); + }); diff --git a/script/constants/deploymentConfig.ts b/script/constants/deploymentConfig.ts index 2a624e99..88e3c485 100644 --- a/script/constants/deploymentConfig.ts +++ b/script/constants/deploymentConfig.ts @@ -54,6 +54,8 @@ export const getAddresses = (chainSlug: number, mode: DeploymentMode) => { }; export const getChainName = (chainSlug: number) => { + if (chainSlug === 84532) return "BASE_SEPOLIA"; + let chainName = chainSlugReverseMap.get(String(chainSlug)) ?? chains[chainSlug].chainName; return chainName.toUpperCase().replace(/[\s-]/g, "_"); // convert to uppercase, replace space and - with _ diff --git a/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts new file mode 100644 index 00000000..9ae19a4f --- /dev/null +++ b/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts @@ -0,0 +1,25 @@ + +import { + ChainSlug, + DeploymentMode, + IntegrationTypes, +} from "@socket.tech/dl-core"; +import { Hooks, ProjectConstants } from "../../../../src"; +import { NFTs, Tokens } from "../../../../src/enums"; + +// For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. +export const pc: ProjectConstants = { + [DeploymentMode.SURGE]: { + [NFTs.GOTCHI]: { + vaultChains: [84532], + controllerChains: [631571], + tokenAddresses: { + 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", + 631571: "0xD66C6C61D5a535eD69E3769582895daec28a4651" + }, + hook: { + hookType: Hooks.NO_HOOK + } + } + } +}; diff --git a/script/constants/projectConstants/superbridge/aavegotchi_item_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_testnet.ts similarity index 85% rename from script/constants/projectConstants/superbridge/aavegotchi_item_bridge_testnet.ts rename to script/constants/projectConstants/superbridge/aavegotchi_items_bridge_testnet.ts index a02fa9e8..938c4bc5 100644 --- a/script/constants/projectConstants/superbridge/aavegotchi_item_bridge_testnet.ts +++ b/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_testnet.ts @@ -1,3 +1,4 @@ + import { ChainSlug, DeploymentMode, @@ -14,11 +15,11 @@ export const pc: ProjectConstants = { controllerChains: [631571], tokenAddresses: { 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - 631571: "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", + 631571: "0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334" }, hook: { - hookType: Hooks.NO_HOOK, - }, - }, - }, + hookType: Hooks.NO_HOOK + } + } + } }; diff --git a/script/helpers/common.ts b/script/helpers/common.ts index 324e43f6..01c961bb 100644 --- a/script/helpers/common.ts +++ b/script/helpers/common.ts @@ -82,21 +82,36 @@ export const updateConnectorStatus = async ( export const getBridgeContract = async ( chain: ChainSlug, token: string, - addr: SBTokenAddresses | STTokenAddresses + addr: SBTokenAddresses | STTokenAddresses, + tokenType?: "ERC20" | "ERC721" | "ERC1155" ) => { const socketSigner = getSignerFromChainSlug(chain); let bridgeContract: Contract, bridgeAddress: string = "", bridgeContractName: string = ""; + + if (!tokenType) tokenType = "ERC20"; + if (isSuperBridge()) { if (isSBAppChain(chain, token)) { const a = addr as AppChainAddresses; bridgeAddress = a.Controller; - bridgeContractName = SuperBridgeContracts.Controller; + + if (["ERC721", "ERC1155"].includes(tokenType)) { + bridgeContractName = SuperBridgeContracts.NFTController; + } else { + bridgeContractName = SuperBridgeContracts.Controller; + } } else { const a = addr as NonAppChainAddresses; bridgeAddress = a.Vault; - bridgeContractName = SuperBridgeContracts.Vault; + + if (["ERC721", "ERC1155"].includes(tokenType)) { + console.log("use nft vault"); + bridgeContractName = SuperBridgeContracts.NFTVault; + } else { + bridgeContractName = SuperBridgeContracts.Vault; + } } } if (isSuperToken()) { @@ -124,12 +139,13 @@ export const getBridgeContract = async ( export const getTokenContract = async ( chain: ChainSlug, token: Tokens, - addr: SBTokenAddresses | STTokenAddresses + addr: SBTokenAddresses | STTokenAddresses, + tokenType?: "ERC20" | "ERC721" | "ERC1155" ) => { const socketSigner = getSignerFromChainSlug(chain); let tokenContract: Contract, tokenAddress: string = "", - tokenContractName: string = "ERC20"; + tokenContractName: string = tokenType ? tokenType : "ERC20"; if (isSuperBridge()) { if (isSBAppChain(chain, token)) { const a = addr as AppChainAddresses; diff --git a/script/helpers/networks.ts b/script/helpers/networks.ts index 60b8e6a4..e9625355 100644 --- a/script/helpers/networks.ts +++ b/script/helpers/networks.ts @@ -93,6 +93,7 @@ export const overrides: { // gasLimit: 5_000_000, // gasPrice, }, + [ChainSlug.REYA_CRONOS]: { type: 1, // gasLimit, @@ -108,6 +109,11 @@ export const overrides: { gasLimit: 1_000_000_000, gasPrice: 100_000, }, + 84532: { + type: 1, + gasLimit: 20_000_000, + gasPrice, + }, }; export const getOverrides = (chainSlug: ChainSlug): Overrides => { diff --git a/src/enums/projectType.ts b/src/enums/projectType.ts index 992156f5..011053cc 100644 --- a/src/enums/projectType.ts +++ b/src/enums/projectType.ts @@ -23,6 +23,6 @@ export const ProjectTypeMap: Record = { [Project.TESTING_TESTNET]: ProjectType.SUPERTOKEN, [Project.MAGIC_MAINNET]: ProjectType.SUPERTOKEN, [Project.POLTER_TESTNET]: ProjectType.SUPERBRIDGE, - [Project.AAVEGOTCHI_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, - [Project.AAVEGOTCHI_ITEM_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, + [Project.AAVEGOTCHI_GOTCHI_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, + [Project.AAVEGOTCHI_ITEMS_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, }; diff --git a/src/enums/projects.ts b/src/enums/projects.ts index 45f3abff..6f6a3aa1 100644 --- a/src/enums/projects.ts +++ b/src/enums/projects.ts @@ -20,6 +20,6 @@ export enum Project { TESTING_TESTNET = "testing_testnet", MAGIC_MAINNET = "magic_mainnet", POLTER_TESTNET = "polter_testnet", - AAVEGOTCHI_BRIDGE_TESTNET = "aavegotchi_bridge_testnet", - AAVEGOTCHI_ITEM_BRIDGE_TESTNET = "aavegotchi_item_bridge_testnet", + AAVEGOTCHI_GOTCHI_BRIDGE_TESTNET = "aavegotchi_gotchi_bridge_testnet", + AAVEGOTCHI_ITEMS_BRIDGE_TESTNET = "aavegotchi_items_bridge_testnet", } From 35b62dc1db5220ba146d01a6c2fb2aa01cd23ec5 Mon Sep 17 00:00:00 2001 From: Coderdan Date: Wed, 20 Nov 2024 11:56:40 +0800 Subject: [PATCH 20/22] chore: formatting --- ...e_aavegotchi_gotchi_bridge_testnet_addresses.json | 2 +- ...avegotchi_gotchi_bridge_testnet_verification.json | 12 +++--------- ...ge_aavegotchi_items_bridge_testnet_addresses.json | 2 +- ...aavegotchi_items_bridge_testnet_verification.json | 12 +++--------- deployments/superbridge/surge_addresses.json | 2 +- .../superbridge/aavegotchi_gotchi_bridge_testnet.ts | 11 +++++------ .../superbridge/aavegotchi_items_bridge_testnet.ts | 11 +++++------ 7 files changed, 19 insertions(+), 33 deletions(-) diff --git a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json index fa55d457..8c9c8565 100644 --- a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json +++ b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json @@ -23,4 +23,4 @@ } } } -} \ No newline at end of file +} diff --git a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json index 5b23ddef..c22d7509 100644 --- a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json +++ b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json @@ -15,10 +15,7 @@ "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", "NFTVault", "contracts/bridge/NFT/NFTVault.sol", - [ - "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - "0x80ac58cd" - ] + ["0x87C969d083189927049f8fF3747703FB9f7a8AEd", "0x80ac58cd"] ] ], "631571": [ @@ -37,10 +34,7 @@ "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", "NFTController", "contracts/bridge/NFT/NFTController.sol", - [ - "0xD66C6C61D5a535eD69E3769582895daec28a4651", - "0x80ac58cd" - ] + ["0xD66C6C61D5a535eD69E3769582895daec28a4651", "0x80ac58cd"] ] ] -} \ No newline at end of file +} diff --git a/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_addresses.json index 3ecf987b..cd0ca293 100644 --- a/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_addresses.json +++ b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_addresses.json @@ -23,4 +23,4 @@ } } } -} \ No newline at end of file +} diff --git a/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json index 5166f569..a7ec93d2 100644 --- a/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json +++ b/deployments/superbridge/surge_aavegotchi_items_bridge_testnet_verification.json @@ -15,10 +15,7 @@ "0x2709f098E8C641796B495bED28A34F9FEA858ac8", "NFTVault", "contracts/bridge/NFT/NFTVault.sol", - [ - "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - "0xd9b67a26" - ] + ["0x87C969d083189927049f8fF3747703FB9f7a8AEd", "0xd9b67a26"] ] ], "631571": [ @@ -37,10 +34,7 @@ "0x60d629c876E455eFdca83e2b4c85DfB9d4C3C58C", "NFTController", "contracts/bridge/NFT/NFTController.sol", - [ - "0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334", - "0xd9b67a26" - ] + ["0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334", "0xd9b67a26"] ] ] -} \ No newline at end of file +} diff --git a/deployments/superbridge/surge_addresses.json b/deployments/superbridge/surge_addresses.json index 68b80f89..3f7dc2d2 100644 --- a/deployments/superbridge/surge_addresses.json +++ b/deployments/superbridge/surge_addresses.json @@ -131,4 +131,4 @@ } } } -} \ No newline at end of file +} diff --git a/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts index 9ae19a4f..39c5c4e8 100644 --- a/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts +++ b/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts @@ -1,4 +1,3 @@ - import { ChainSlug, DeploymentMode, @@ -15,11 +14,11 @@ export const pc: ProjectConstants = { controllerChains: [631571], tokenAddresses: { 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - 631571: "0xD66C6C61D5a535eD69E3769582895daec28a4651" + 631571: "0xD66C6C61D5a535eD69E3769582895daec28a4651", }, hook: { - hookType: Hooks.NO_HOOK - } - } - } + hookType: Hooks.NO_HOOK, + }, + }, + }, }; diff --git a/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_testnet.ts index 938c4bc5..0077c255 100644 --- a/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_testnet.ts +++ b/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_testnet.ts @@ -1,4 +1,3 @@ - import { ChainSlug, DeploymentMode, @@ -15,11 +14,11 @@ export const pc: ProjectConstants = { controllerChains: [631571], tokenAddresses: { 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - 631571: "0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334" + 631571: "0x954B9F6DaB28F92c88192E2F52FDa5A6Df4A0334", }, hook: { - hookType: Hooks.NO_HOOK - } - } - } + hookType: Hooks.NO_HOOK, + }, + }, + }, }; From 5e655a61fc61af5db0ed993d1f0ffe7c7f235e0c Mon Sep 17 00:00:00 2001 From: Coderdan Date: Wed, 27 Nov 2024 21:52:33 +0800 Subject: [PATCH 21/22] chore: update project --- ...e_aavegotchi_bridge_testnet_addresses.json | 26 ------------ ...otchi_gotchi_bridge_testnet_addresses.json | 26 ------------ ...hi_gotchi_bridge_testnet_verification.json | 40 ------------------- ...tchi_gotchis_bridge_testnet_addresses.json | 26 ++++++++++++ ..._gotchis_bridge_testnet_verification.json} | 24 ++++++----- deployments/superbridge/surge_addresses.json | 28 ++++++++++++- .../aavegotchi_gotchi_bridge_testnet.ts | 24 ----------- ...s => aavegotchi_gotchis_bridge_testnet.ts} | 13 +++--- src/enums/projectType.ts | 2 +- src/enums/projects.ts | 2 +- 10 files changed, 77 insertions(+), 134 deletions(-) delete mode 100644 deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json delete mode 100644 deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json delete mode 100644 deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json create mode 100644 deployments/superbridge/surge_aavegotchi_gotchis_bridge_testnet_addresses.json rename deployments/superbridge/{surge_aavegotchi_bridge_testnet_verification.json => surge_aavegotchi_gotchis_bridge_testnet_verification.json} (57%) delete mode 100644 script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts rename script/constants/projectConstants/superbridge/{aavegotchi_bridge_testnet.ts => aavegotchi_gotchis_bridge_testnet.ts} (77%) diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json deleted file mode 100644 index 273053f6..00000000 --- a/deployments/superbridge/surge_aavegotchi_bridge_testnet_addresses.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "84532": { - "GOTCHI": { - "isAppChain": false, - "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - "Vault": "0x110A646276961C2d8a54b951bbC8B169E0F573c4", - "connectors": { - "631571": { - "FAST": "0xd912F40C27E317db2334e210de892e9dc92816af" - } - } - } - }, - "631571": { - "GOTCHI": { - "isAppChain": true, - "MintableToken": "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", - "Controller": "0x5ABB7E28160f82A84e389aDcc9d8CE3F7a0C8D92", - "connectors": { - "84532": { - "FAST": "0xE7af5160334aded39DD9826cBcBa0B51A1B184e9" - } - } - } - } -} diff --git a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json deleted file mode 100644 index 8c9c8565..00000000 --- a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_addresses.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "84532": { - "GOTCHI": { - "isAppChain": false, - "NonMintableToken": "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - "Vault": "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", - "connectors": { - "631571": { - "FAST": "0x3C43820A77d3Ff7Df81f212851857c46684f8b2F" - } - } - } - }, - "631571": { - "GOTCHI": { - "isAppChain": true, - "MintableToken": "0xD66C6C61D5a535eD69E3769582895daec28a4651", - "Controller": "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", - "connectors": { - "84532": { - "FAST": "0x3A643fc25C721971314119a50a7fdF18385b7eD9" - } - } - } - } -} diff --git a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json deleted file mode 100644 index c22d7509..00000000 --- a/deployments/superbridge/surge_aavegotchi_gotchi_bridge_testnet_verification.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "84532": [ - [ - "0x3C43820A77d3Ff7Df81f212851857c46684f8b2F", - "ConnectorPlug", - "contracts/ConnectorPlug.sol", - [ - "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", - "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", - 631571, - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - ], - [ - "0xEccF8B72c6A354532F27053e54A5b4b912D1e6D6", - "NFTVault", - "contracts/bridge/NFT/NFTVault.sol", - ["0x87C969d083189927049f8fF3747703FB9f7a8AEd", "0x80ac58cd"] - ] - ], - "631571": [ - [ - "0x3A643fc25C721971314119a50a7fdF18385b7eD9", - "ConnectorPlug", - "contracts/ConnectorPlug.sol", - [ - "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", - "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", - 84532, - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - ], - [ - "0x143B8D0e2b6d7791F571A68bf07da2253C0d52CB", - "NFTController", - "contracts/bridge/NFT/NFTController.sol", - ["0xD66C6C61D5a535eD69E3769582895daec28a4651", "0x80ac58cd"] - ] - ] -} diff --git a/deployments/superbridge/surge_aavegotchi_gotchis_bridge_testnet_addresses.json b/deployments/superbridge/surge_aavegotchi_gotchis_bridge_testnet_addresses.json new file mode 100644 index 00000000..6ebf9ad5 --- /dev/null +++ b/deployments/superbridge/surge_aavegotchi_gotchis_bridge_testnet_addresses.json @@ -0,0 +1,26 @@ +{ + "84532": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0xf81FFb9E2a72574d3C4Cf4E293D4Fec4A708F2B1", + "Vault": "0x92641fDD13A1B2099675fd1F3798fa0d9e6CDAfa", + "connectors": { + "631571": { + "FAST": "0x8Ca0b8D5a04F902171113A4Ac76a8f1F52FCDF6f" + } + } + } + }, + "631571": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0x226625C1B1174e7BaaE8cDC0432Db0e2ED83b7Ba", + "Controller": "0xde3c698E15806384C667b0478C1072867571f6cd", + "connectors": { + "84532": { + "FAST": "0x8Dc7AED7a2A2729D762e63BaDecCd7D50474020B" + } + } + } + } +} \ No newline at end of file diff --git a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json b/deployments/superbridge/surge_aavegotchi_gotchis_bridge_testnet_verification.json similarity index 57% rename from deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json rename to deployments/superbridge/surge_aavegotchi_gotchis_bridge_testnet_verification.json index 4ace912b..ed4ebc45 100644 --- a/deployments/superbridge/surge_aavegotchi_bridge_testnet_verification.json +++ b/deployments/superbridge/surge_aavegotchi_gotchis_bridge_testnet_verification.json @@ -1,40 +1,46 @@ { "84532": [ [ - "0xd912F40C27E317db2334e210de892e9dc92816af", + "0x8Ca0b8D5a04F902171113A4Ac76a8f1F52FCDF6f", "ConnectorPlug", "contracts/ConnectorPlug.sol", [ - "0x110A646276961C2d8a54b951bbC8B169E0F573c4", + "0x92641fDD13A1B2099675fd1F3798fa0d9e6CDAfa", "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", 631571, "0x0000000000000000000000000000000000000000000000000000000000000000" ] ], [ - "0x110A646276961C2d8a54b951bbC8B169E0F573c4", + "0x92641fDD13A1B2099675fd1F3798fa0d9e6CDAfa", "NFTVault", "contracts/bridge/NFT/NFTVault.sol", - ["0x87C969d083189927049f8fF3747703FB9f7a8AEd", "0x80ac58cd"] + [ + "0xf81FFb9E2a72574d3C4Cf4E293D4Fec4A708F2B1", + "0x80ac58cd" + ] ] ], "631571": [ [ - "0xE7af5160334aded39DD9826cBcBa0B51A1B184e9", + "0x8Dc7AED7a2A2729D762e63BaDecCd7D50474020B", "ConnectorPlug", "contracts/ConnectorPlug.sol", [ - "0x5ABB7E28160f82A84e389aDcc9d8CE3F7a0C8D92", + "0xde3c698E15806384C667b0478C1072867571f6cd", "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", 84532, "0x0000000000000000000000000000000000000000000000000000000000000000" ] ], [ - "0x5ABB7E28160f82A84e389aDcc9d8CE3F7a0C8D92", + "0xde3c698E15806384C667b0478C1072867571f6cd", "NFTController", "contracts/bridge/NFT/NFTController.sol", - ["0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", "0x80ac58cd"] + [ + "0x226625C1B1174e7BaaE8cDC0432Db0e2ED83b7Ba", + "0x80ac58cd" + ] ] ] -} +} \ No newline at end of file diff --git a/deployments/superbridge/surge_addresses.json b/deployments/superbridge/surge_addresses.json index 3f7dc2d2..bf269032 100644 --- a/deployments/superbridge/surge_addresses.json +++ b/deployments/superbridge/surge_addresses.json @@ -130,5 +130,31 @@ } } } + }, + "aavegotchi_gotchis_bridge_testnet": { + "84532": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0xf81FFb9E2a72574d3C4Cf4E293D4Fec4A708F2B1", + "Vault": "0x92641fDD13A1B2099675fd1F3798fa0d9e6CDAfa", + "connectors": { + "631571": { + "FAST": "0x8Ca0b8D5a04F902171113A4Ac76a8f1F52FCDF6f" + } + } + } + }, + "631571": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0x226625C1B1174e7BaaE8cDC0432Db0e2ED83b7Ba", + "Controller": "0xde3c698E15806384C667b0478C1072867571f6cd", + "connectors": { + "84532": { + "FAST": "0x8Dc7AED7a2A2729D762e63BaDecCd7D50474020B" + } + } + } + } } -} +} \ No newline at end of file diff --git a/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts deleted file mode 100644 index 39c5c4e8..00000000 --- a/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_testnet.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - ChainSlug, - DeploymentMode, - IntegrationTypes, -} from "@socket.tech/dl-core"; -import { Hooks, ProjectConstants } from "../../../../src"; -import { NFTs, Tokens } from "../../../../src/enums"; - -// For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. -export const pc: ProjectConstants = { - [DeploymentMode.SURGE]: { - [NFTs.GOTCHI]: { - vaultChains: [84532], - controllerChains: [631571], - tokenAddresses: { - 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - 631571: "0xD66C6C61D5a535eD69E3769582895daec28a4651", - }, - hook: { - hookType: Hooks.NO_HOOK, - }, - }, - }, -}; diff --git a/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_gotchis_bridge_testnet.ts similarity index 77% rename from script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts rename to script/constants/projectConstants/superbridge/aavegotchi_gotchis_bridge_testnet.ts index ca4d0b9c..3fa3c6b4 100644 --- a/script/constants/projectConstants/superbridge/aavegotchi_bridge_testnet.ts +++ b/script/constants/projectConstants/superbridge/aavegotchi_gotchis_bridge_testnet.ts @@ -1,3 +1,4 @@ + import { ChainSlug, DeploymentMode, @@ -13,12 +14,12 @@ export const pc: ProjectConstants = { vaultChains: [84532], controllerChains: [631571], tokenAddresses: { - 84532: "0x87C969d083189927049f8fF3747703FB9f7a8AEd", - 631571: "0x1F0eb9099b9c398323dcf2F133dFdAD9dE7cF994", + 84532: "0xf81FFb9E2a72574d3C4Cf4E293D4Fec4A708F2B1", + 631571: "0x226625C1B1174e7BaaE8cDC0432Db0e2ED83b7Ba" }, hook: { - hookType: Hooks.NO_HOOK, - }, - }, - }, + hookType: Hooks.NO_HOOK + } + } + } }; diff --git a/src/enums/projectType.ts b/src/enums/projectType.ts index 011053cc..82e6933d 100644 --- a/src/enums/projectType.ts +++ b/src/enums/projectType.ts @@ -23,6 +23,6 @@ export const ProjectTypeMap: Record = { [Project.TESTING_TESTNET]: ProjectType.SUPERTOKEN, [Project.MAGIC_MAINNET]: ProjectType.SUPERTOKEN, [Project.POLTER_TESTNET]: ProjectType.SUPERBRIDGE, - [Project.AAVEGOTCHI_GOTCHI_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, [Project.AAVEGOTCHI_ITEMS_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, + [Project.AAVEGOTCHI_GOTCHIS_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, }; diff --git a/src/enums/projects.ts b/src/enums/projects.ts index 6f6a3aa1..83c8672a 100644 --- a/src/enums/projects.ts +++ b/src/enums/projects.ts @@ -20,6 +20,6 @@ export enum Project { TESTING_TESTNET = "testing_testnet", MAGIC_MAINNET = "magic_mainnet", POLTER_TESTNET = "polter_testnet", - AAVEGOTCHI_GOTCHI_BRIDGE_TESTNET = "aavegotchi_gotchi_bridge_testnet", AAVEGOTCHI_ITEMS_BRIDGE_TESTNET = "aavegotchi_items_bridge_testnet", + AAVEGOTCHI_GOTCHIS_BRIDGE_TESTNET = "aavegotchi_gotchis_bridge_testnet", } From 97ec00804f9409a65095d1d2afd58c4d6685878d Mon Sep 17 00:00:00 2001 From: Coderdan Date: Sat, 30 Nov 2024 13:58:43 +0800 Subject: [PATCH 22/22] chore: update scripts --- ...otchi_gotchi_bridge_mainnet_addresses.json | 26 +++++++++ ...hi_gotchi_bridge_mainnet_verification.json | 46 ++++++++++++++++ ...gotchi_items_bridge_mainnet_addresses.json | 26 +++++++++ ...chi_items_bridge_mainnet_verification.json | 46 ++++++++++++++++ deployments/superbridge/prod_addresses.json | 54 ++++++++++++++++++- package.json | 2 +- script/bridge/bridgeERC1155.ts | 9 ++-- script/bridge/bridgeERC721.ts | 35 +++++++++--- .../aavegotchi_gotchi_bridge_mainnet.ts | 25 +++++++++ .../aavegotchi_items_bridge_mainnet.ts | 25 +++++++++ src/enums/projectType.ts | 2 + src/enums/projects.ts | 2 + yarn.lock | 8 +-- 13 files changed, 291 insertions(+), 15 deletions(-) create mode 100644 deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_addresses.json create mode 100644 deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_verification.json create mode 100644 deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_addresses.json create mode 100644 deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_verification.json create mode 100644 script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_mainnet.ts create mode 100644 script/constants/projectConstants/superbridge/aavegotchi_items_bridge_mainnet.ts diff --git a/deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_addresses.json b/deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_addresses.json new file mode 100644 index 00000000..c5d3640f --- /dev/null +++ b/deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_addresses.json @@ -0,0 +1,26 @@ +{ + "137": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0x86935F11C86623deC8a25696E1C19a8659CbF95d", + "Vault": "0xF1D1d61EEDDa7a10b494aF7af87D932AC910f3C5", + "connectors": { + "63157": { + "FAST": "0x8992e26290073183DA46aF2589ff3025be3CdF29" + } + } + } + }, + "63157": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0x6Acc828BbbC6874de40Ca20bfeA7Cd2a2DA8DA8c", + "Controller": "0x5964823256B9C8aC7Ba7Dd94807FDF4DFf728215", + "connectors": { + "137": { + "FAST": "0x870cCEc2CB64270cEd3A4BE581Ddc87673882758" + } + } + } + } +} \ No newline at end of file diff --git a/deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_verification.json b/deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_verification.json new file mode 100644 index 00000000..d4638d7a --- /dev/null +++ b/deployments/superbridge/prod_aavegotchi_gotchi_bridge_mainnet_verification.json @@ -0,0 +1,46 @@ +{ + "137": [ + [ + "0x8992e26290073183DA46aF2589ff3025be3CdF29", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0xF1D1d61EEDDa7a10b494aF7af87D932AC910f3C5", + "0xc20687f8dc0ad51d01003013d1c5b02d10DED001", + 63157, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0xF1D1d61EEDDa7a10b494aF7af87D932AC910f3C5", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + [ + "0x86935F11C86623deC8a25696E1C19a8659CbF95d", + "0x80ac58cd" + ] + ] + ], + "63157": [ + [ + "0x870cCEc2CB64270cEd3A4BE581Ddc87673882758", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x5964823256B9C8aC7Ba7Dd94807FDF4DFf728215", + "0x34464194a4aCD38F42060D144BF3729F625Ff047", + 137, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x5964823256B9C8aC7Ba7Dd94807FDF4DFf728215", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + [ + "0x6Acc828BbbC6874de40Ca20bfeA7Cd2a2DA8DA8c", + "0x80ac58cd" + ] + ] + ] +} \ No newline at end of file diff --git a/deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_addresses.json b/deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_addresses.json new file mode 100644 index 00000000..a0bdcccf --- /dev/null +++ b/deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_addresses.json @@ -0,0 +1,26 @@ +{ + "137": { + "GOTCHI_ITEM": { + "isAppChain": false, + "NonMintableToken": "0x58de9AaBCaeEC0f69883C94318810ad79Cc6a44f", + "Vault": "0xA421Ed8a4E3cfbFbFd2F621b27bd3C27D71C8b97", + "connectors": { + "63157": { + "FAST": "0x1A9E2D17122B747871a1088FC38952c7dc5d8334" + } + } + } + }, + "63157": { + "GOTCHI_ITEM": { + "isAppChain": true, + "MintableToken": "0xaC336aB3CFC58698B582205A861A5C6B798c01B9", + "Controller": "0x4924E6B720D7283bF2d90104A480a9CFadAb1b77", + "connectors": { + "137": { + "FAST": "0xaf6b8fbacEec187A954C1e85D3614c58C393AA28" + } + } + } + } +} \ No newline at end of file diff --git a/deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_verification.json b/deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_verification.json new file mode 100644 index 00000000..6a5ed613 --- /dev/null +++ b/deployments/superbridge/prod_aavegotchi_items_bridge_mainnet_verification.json @@ -0,0 +1,46 @@ +{ + "137": [ + [ + "0x1A9E2D17122B747871a1088FC38952c7dc5d8334", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0xA421Ed8a4E3cfbFbFd2F621b27bd3C27D71C8b97", + "0xc20687f8dc0ad51d01003013d1c5b02d10DED001", + 63157, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0xA421Ed8a4E3cfbFbFd2F621b27bd3C27D71C8b97", + "NFTVault", + "contracts/bridge/NFT/NFTVault.sol", + [ + "0x58de9AaBCaeEC0f69883C94318810ad79Cc6a44f", + "0xd9b67a26" + ] + ] + ], + "63157": [ + [ + "0xaf6b8fbacEec187A954C1e85D3614c58C393AA28", + "ConnectorPlug", + "contracts/ConnectorPlug.sol", + [ + "0x4924E6B720D7283bF2d90104A480a9CFadAb1b77", + "0x34464194a4aCD38F42060D144BF3729F625Ff047", + 137, + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + ], + [ + "0x4924E6B720D7283bF2d90104A480a9CFadAb1b77", + "NFTController", + "contracts/bridge/NFT/NFTController.sol", + [ + "0xaC336aB3CFC58698B582205A861A5C6B798c01B9", + "0xd9b67a26" + ] + ] + ] +} \ No newline at end of file diff --git a/deployments/superbridge/prod_addresses.json b/deployments/superbridge/prod_addresses.json index a3f1a7fb..710453ee 100644 --- a/deployments/superbridge/prod_addresses.json +++ b/deployments/superbridge/prod_addresses.json @@ -1228,5 +1228,57 @@ } } } + }, + "aavegotchi_gotchi_bridge_mainnet": { + "137": { + "GOTCHI": { + "isAppChain": false, + "NonMintableToken": "0x86935F11C86623deC8a25696E1C19a8659CbF95d", + "Vault": "0xF1D1d61EEDDa7a10b494aF7af87D932AC910f3C5", + "connectors": { + "63157": { + "FAST": "0x8992e26290073183DA46aF2589ff3025be3CdF29" + } + } + } + }, + "63157": { + "GOTCHI": { + "isAppChain": true, + "MintableToken": "0x6Acc828BbbC6874de40Ca20bfeA7Cd2a2DA8DA8c", + "Controller": "0x5964823256B9C8aC7Ba7Dd94807FDF4DFf728215", + "connectors": { + "137": { + "FAST": "0x870cCEc2CB64270cEd3A4BE581Ddc87673882758" + } + } + } + } + }, + "aavegotchi_items_bridge_mainnet": { + "137": { + "GOTCHI_ITEM": { + "isAppChain": false, + "NonMintableToken": "0x58de9AaBCaeEC0f69883C94318810ad79Cc6a44f", + "Vault": "0xA421Ed8a4E3cfbFbFd2F621b27bd3C27D71C8b97", + "connectors": { + "63157": { + "FAST": "0x1A9E2D17122B747871a1088FC38952c7dc5d8334" + } + } + } + }, + "63157": { + "GOTCHI_ITEM": { + "isAppChain": true, + "MintableToken": "0xaC336aB3CFC58698B582205A861A5C6B798c01B9", + "Controller": "0x4924E6B720D7283bF2d90104A480a9CFadAb1b77", + "connectors": { + "137": { + "FAST": "0xaf6b8fbacEec187A954C1e85D3614c58C393AA28" + } + } + } + } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 88715160..f9c4d9bc 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "dependencies": { "@arbitrum/sdk": "^3.7.0", "@eth-optimism/sdk": "^3.3.2", - "@socket.tech/dl-core": "^2.28.0", + "@socket.tech/dl-core": "^2.35.0", "lodash": "^4.17.21", "prompts": "^2.4.2" } diff --git a/script/bridge/bridgeERC1155.ts b/script/bridge/bridgeERC1155.ts index 4296582d..9b262c6a 100644 --- a/script/bridge/bridgeERC1155.ts +++ b/script/bridge/bridgeERC1155.ts @@ -55,11 +55,11 @@ export const main = async () => { // }, // }).argv; - const srcChain = 84532 as ChainSlug; //Number(argv.srcChain) as ChainSlug; - const dstChain = 631571 as ChainSlug; //Number(argv.dstChain) as ChainSlug; + const srcChain = 63157 as ChainSlug; //Number(argv.srcChain) as ChainSlug; + const dstChain = 137 as ChainSlug; //Number(argv.dstChain) as ChainSlug; const amount = 1; const token = "GOTCHI_ITEM" as Tokens; - const tokenId = "151"; //argv.tokenId; + const tokenId = "228"; //argv.tokenId; // if (!Object.values(Tokens).includes(token)) // throw Error("token not allowed"); @@ -116,6 +116,9 @@ export const main = async () => { socketSigner.address, bridgeContract.address ); + + console.log("currentApproval:", currentApproval); + if (!currentApproval) { const approveTx = await tokenContract.setApprovalForAll( bridgeContract.address, diff --git a/script/bridge/bridgeERC721.ts b/script/bridge/bridgeERC721.ts index d903eaaf..1b093f95 100644 --- a/script/bridge/bridgeERC721.ts +++ b/script/bridge/bridgeERC721.ts @@ -1,7 +1,7 @@ import { BigNumber, utils } from "ethers"; +import { ethers } from "hardhat"; import { ChainSlug } from "@socket.tech/dl-core"; -import yargs from "yargs"; import { SBAddresses, SBTokenAddresses, @@ -13,6 +13,7 @@ import { getProjectAddresses } from "../helpers"; import { getBridgeContract, getTokenContract } from "../helpers/common"; import { getOverrides, getSignerFromChainSlug } from "../helpers/networks"; import { checkSendingLimit, getDLAPIBaseUrl } from "./utils"; +import { network } from "hardhat"; const gasLimit = 500_000; @@ -55,11 +56,17 @@ export const main = async () => { // }, // }).argv; - const srcChain = 84532 as ChainSlug; //Number(argv.srcChain) as ChainSlug; - const dstChain = 631571 as ChainSlug; //Number(argv.dstChain) as ChainSlug; + const srcChain = 137 as ChainSlug; //Number(argv.srcChain) as ChainSlug; + const dstChain = 63157 as ChainSlug; //Number(argv.dstChain) as ChainSlug; const amount = 1; const token = "GOTCHI" as Tokens; - const tokenId = "511"; //argv.tokenId; + const tokenId = "6018"; //argv.tokenId; + + console.log("network:", network.name); + + if (network.name !== "hardhat") { + throw new Error("script can only be run on hardhat network"); + } // if (!Object.values(Tokens).includes(token)) // throw Error("token not allowed"); @@ -99,9 +106,19 @@ export const main = async () => { if (!connectorAddr) throw new Error("connector contract addresses missing"); - const socketSigner = getSignerFromChainSlug(srcChain); + let socketSigner; + if (network.name === "hardhat") { + socketSigner = await ethers.getImpersonatedSigner( + "0xC3c2e1Cf099Bc6e1fA94ce358562BCbD5cc59FE5" + ); + } else { + socketSigner = getSignerFromChainSlug(srcChain); + } - console.log("checking balance and approval..."); + console.log( + "checking balance and approval of account:", + socketSigner.address + ); // approve const balance: BigNumber = await tokenContract.balanceOf( socketSigner.address @@ -109,6 +126,8 @@ export const main = async () => { console.log("balance:", balance); + if (balance.eq(0)) throw new Error("Not enough balance"); + // if (balance.lt(amountBN)) throw new Error("Not enough balance"); const currentApproval: boolean = await tokenContract.isApprovedForAll( @@ -140,6 +159,10 @@ export const main = async () => { console.log(`depositing ${amount} to ${dstChain} from ${srcChain}`); const fees = await bridgeContract.getMinFees(connectorAddr, gasLimit, 0); + console.log("fees:", fees); + + return; + // address receiver_, // address tokenOwner_, // uint256 tokenId_, diff --git a/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_mainnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_mainnet.ts new file mode 100644 index 00000000..1cc3f00b --- /dev/null +++ b/script/constants/projectConstants/superbridge/aavegotchi_gotchi_bridge_mainnet.ts @@ -0,0 +1,25 @@ +import { + ChainSlug, + DeploymentMode, + IntegrationTypes, +} from "@socket.tech/dl-core"; +import { Hooks, ProjectConstants } from "../../../../src"; +import { NFTs, Tokens } from "../../../../src/enums"; + +// For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. +export const pc: ProjectConstants = { + [DeploymentMode.PROD]: { + [NFTs.GOTCHI]: { + vaultChains: [ChainSlug.POLYGON_MAINNET], + controllerChains: [ChainSlug.GEIST], + tokenAddresses: { + [ChainSlug.POLYGON_MAINNET]: + "0x86935F11C86623deC8a25696E1C19a8659CbF95d", + [ChainSlug.GEIST]: "0x6Acc828BbbC6874de40Ca20bfeA7Cd2a2DA8DA8c", + }, + hook: { + hookType: Hooks.NO_HOOK, + }, + }, + }, +}; diff --git a/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_mainnet.ts b/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_mainnet.ts new file mode 100644 index 00000000..50914263 --- /dev/null +++ b/script/constants/projectConstants/superbridge/aavegotchi_items_bridge_mainnet.ts @@ -0,0 +1,25 @@ +import { + ChainSlug, + DeploymentMode, + IntegrationTypes, +} from "@socket.tech/dl-core"; +import { Hooks, ProjectConstants } from "../../../../src"; +import { NFTs, Tokens } from "../../../../src/enums"; + +// For testnet deployments, ChainSlug enum may not have some chains, therefore some keys will look like {421614:{}} instead of {[ChainSlug.ARBITRUM_SEPOLIA]:{}}. This wont affect the functionality of the project. +export const pc: ProjectConstants = { + [DeploymentMode.PROD]: { + [NFTs.GOTCHI_ITEM]: { + vaultChains: [ChainSlug.POLYGON_MAINNET], + controllerChains: [ChainSlug.GEIST], + tokenAddresses: { + [ChainSlug.POLYGON_MAINNET]: + "0x58de9AaBCaeEC0f69883C94318810ad79Cc6a44f", + [ChainSlug.GEIST]: "0xaC336aB3CFC58698B582205A861A5C6B798c01B9", + }, + hook: { + hookType: Hooks.NO_HOOK, + }, + }, + }, +}; diff --git a/src/enums/projectType.ts b/src/enums/projectType.ts index 82e6933d..cc7ecc87 100644 --- a/src/enums/projectType.ts +++ b/src/enums/projectType.ts @@ -25,4 +25,6 @@ export const ProjectTypeMap: Record = { [Project.POLTER_TESTNET]: ProjectType.SUPERBRIDGE, [Project.AAVEGOTCHI_ITEMS_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, [Project.AAVEGOTCHI_GOTCHIS_BRIDGE_TESTNET]: ProjectType.SUPERBRIDGE, + [Project.AAVEGOTCHI_GOTCHI_BRIDGE_MAINNET]: ProjectType.SUPERBRIDGE, + [Project.AAVEGOTCHI_ITEMS_BRIDGE_MAINNET]: ProjectType.SUPERBRIDGE, }; diff --git a/src/enums/projects.ts b/src/enums/projects.ts index 83c8672a..e7243af2 100644 --- a/src/enums/projects.ts +++ b/src/enums/projects.ts @@ -22,4 +22,6 @@ export enum Project { POLTER_TESTNET = "polter_testnet", AAVEGOTCHI_ITEMS_BRIDGE_TESTNET = "aavegotchi_items_bridge_testnet", AAVEGOTCHI_GOTCHIS_BRIDGE_TESTNET = "aavegotchi_gotchis_bridge_testnet", + AAVEGOTCHI_GOTCHI_BRIDGE_MAINNET = "aavegotchi_gotchi_bridge_mainnet", + AAVEGOTCHI_ITEMS_BRIDGE_MAINNET = "aavegotchi_items_bridge_mainnet", } diff --git a/yarn.lock b/yarn.lock index 8909cba3..b23552b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -774,10 +774,10 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" -"@socket.tech/dl-core@^2.28.0": - version "2.28.0" - resolved "https://registry.yarnpkg.com/@socket.tech/dl-core/-/dl-core-2.28.0.tgz#1f62a6d53b362c2c16aed17ab2059c045d502d94" - integrity sha512-muKcbfyXqqQGHFWrCb5NecqeTY5A2zZneSRTFTOhg4lFrHsQ64H51II1iPkjhlUQhD+Gw6Nc/VXU9hwSJ+dG3g== +"@socket.tech/dl-core@^2.35.0": + version "2.35.0" + resolved "https://registry.yarnpkg.com/@socket.tech/dl-core/-/dl-core-2.35.0.tgz#154120d222e095db812423f3b1e748fecdeb8815" + integrity sha512-VH3I4lfCFRpF0ovaYACfd3Fhq2DAtWYcL45xUUHMNVII/EbBl3F7jB10ztWime+0l5sWXVP3o0R8bMnkrotw3w== dependencies: axios "^1.3.6" prompts "^2.4.2"