├── .env.example ├── .gitignore ├── .gitmodules ├── .prettierignore ├── .prettierrc ├── Errors.md ├── LICENSE ├── README.md ├── SUPERBRIDGE_README.md ├── SUPERTOKEN_README.md ├── YIELD_BRIDGE.md ├── contracts ├── ConnectorPlug.sol ├── bridge │ ├── Base.sol │ ├── Controller.sol │ ├── FiatTokenV2_1 │ │ ├── FiatTokenV2_1_Controller.sol │ │ └── IFiatTokenV2_1_Mintable.sol │ └── Vault.sol ├── common │ ├── Constants.sol │ ├── Errors.sol │ └── Structs.sol ├── hooks │ ├── Controller_YieldLimitExecHook.sol │ ├── HookBase.sol │ ├── LimitExecutionHook.sol │ ├── LimitHook.sol │ ├── Vault_YieldLimitExecHook.sol │ └── plugins │ │ ├── ConnectorPoolPlugin.sol │ │ ├── ExecutionHelper.sol │ │ └── LimitPlugin.sol ├── interfaces │ ├── IBridge.sol │ ├── IConnector.sol │ ├── IController.sol │ ├── IHook.sol │ ├── ILimitHook.sol │ ├── IMintableERC20.sol │ ├── IPlug.sol │ ├── ISocket.sol │ └── IStrategy.sol ├── libraries │ ├── ExcessivelySafeCall.sol │ └── RescueFundsLib.sol ├── token │ ├── DummyERC20.sol │ ├── SuperToken.sol │ └── yield-token │ │ ├── YieldToken.sol │ │ └── YieldTokenBase.sol └── utils │ ├── AccessControl.sol │ ├── Faucet.sol │ ├── Gauge.sol │ ├── Ownable.sol │ └── RescueBase.sol ├── deployments ├── superbridge │ ├── dev_aevo-testnet_addresses.json │ ├── dev_aevo-testnet_verification.json │ ├── dev_lyra-testnet_addresses.json │ ├── dev_lyra-testnet_verification.json │ ├── prod_addresses.json │ ├── prod_aevo-testnet_addresses.json │ ├── prod_aevo-testnet_verification.json │ ├── prod_aevo_addresses.json │ ├── prod_aevo_verification.json │ ├── prod_b3_mainnet_addresses.json │ ├── prod_b3_mainnet_verification.json │ ├── prod_looks-testnet_addresses.json │ ├── prod_lyra-testnet_addresses.json │ ├── prod_lyra-testnet_verification.json │ ├── prod_lyra_addresses.json │ ├── prod_lyra_verification.json │ ├── prod_mode_addresses.json │ ├── prod_mode_verification.json │ ├── prod_polynomial_addresses.json │ ├── prod_polynomial_verification.json │ ├── prod_reya_addresses.json │ ├── prod_reya_verification.json │ ├── prod_sx-network-testnet_addresses.json │ ├── prod_sx-network-testnet_verification.json │ ├── prod_syndr-sepolia-l3_addresses.json │ ├── prod_syndr-sepolia-l3_verification.json │ ├── surge_addresses.json │ ├── surge_polter_testnet_addresses.json │ └── surge_polter_testnet_verification.json └── supertoken │ ├── prod_aavegotchi_mainnet_addresses.json │ ├── prod_aavegotchi_mainnet_verification.json │ ├── prod_addresses.json │ ├── prod_magic_mainnet_addresses.json │ ├── prod_magic_mainnet_verification.json │ ├── prod_magical_demo_mainnet_addresses.json │ ├── prod_magical_demo_mainnet_verification.json │ ├── prod_spectral-signal_addresses.json │ ├── prod_spectral-signal_verification.json │ ├── prod_testing_mainnet_addresses.json │ ├── prod_testing_mainnet_verification.json │ ├── prod_testing_testnet_addresses.json │ ├── prod_testing_testnet_verification.json │ ├── prod_timeswap_addresses.json │ ├── prod_timeswap_test_mainnet_addresses.json │ └── prod_timeswap_test_mainnet_verification.json ├── diagrams └── arch.jpg ├── foundry.toml ├── funding.json ├── hardhat.config.ts ├── lib.tsconfig.json ├── package.json ├── remappings.txt ├── script ├── admin │ ├── change-ownership.ts │ ├── check-minter-permission.ts │ ├── check-ownership.ts │ ├── check-vault-balances.ts │ ├── updateConnectorStatus.ts │ ├── updateLimits.ts │ └── utils.ts ├── bridge │ ├── bridge.ts │ └── utils.ts ├── constants │ ├── abis │ │ ├── index.ts │ │ ├── mintable.ts │ │ └── ownable.ts │ ├── config.ts │ ├── deploymentConfig.ts │ ├── index.ts │ ├── projectConstants │ │ ├── superbridge │ │ │ ├── aevo-testnet.ts │ │ │ ├── aevo.ts │ │ │ ├── b3_mainnet.ts │ │ │ ├── polter_testnet.ts │ │ │ ├── rain-testnet.ts │ │ │ ├── reya-cronos.ts │ │ │ ├── reya.ts │ │ │ ├── sx-testnet.ts │ │ │ ├── syndr-sepolia-l3.ts │ │ │ └── syndr_sepolia_testnet.ts │ │ └── supertoken │ │ │ ├── aavegotchi_mainnet.ts │ │ │ ├── leaf-testnet.ts │ │ │ ├── magic_mainnet.ts │ │ │ ├── mist-testnet.ts │ │ │ ├── spectral-signal.ts │ │ │ ├── testing_mainnet.ts │ │ │ ├── testing_testnet.ts │ │ │ └── timeswap_test_mainnet.ts │ └── roles.ts ├── deploy.ts ├── deploy │ ├── configure.ts │ ├── configureHook.ts │ ├── deploy.ts │ ├── deployHook.ts │ └── verifyContracts.ts ├── helpers │ ├── common.ts │ ├── deployUtils.ts │ ├── index.ts │ ├── networks.ts │ ├── projectConstants.ts │ ├── updateJsons.ts │ ├── utils.ts │ └── verifyConstants.ts ├── ownership │ ├── claim-owner.ts │ ├── nominate-owner.ts │ ├── remove-roles.ts │ └── util.ts ├── script.ts └── setup │ ├── addNewToken.ts │ ├── common.ts │ ├── configUtils.ts │ ├── editProject.ts │ ├── enumMaps.ts │ ├── generateConstants.ts │ ├── newProject │ ├── chainInfo.ts │ ├── hookInfo.ts │ ├── main.ts │ ├── projectInfo.ts │ ├── tokenInfo.ts │ └── utils.ts │ └── updateExistingTokenAddresses.ts ├── socket-plugs-details.json ├── src ├── constants.ts ├── core.ts ├── enum.ts ├── enums │ ├── existing-token-addresses.ts │ ├── index.ts │ ├── prodTestnetProjects.ts │ ├── projectType.ts │ ├── projects.ts │ ├── tokenDecimals.ts │ ├── tokenName.ts │ ├── tokenSymbol.ts │ └── tokens.ts ├── index.ts ├── socket-gas-helpers │ ├── arb-estimate.ts │ ├── estimateGasLimit.ts │ ├── op-n-eth-estimate.ts │ └── utils.ts └── types.ts ├── test ├── bridge │ ├── Yieldbridge.t.sol │ ├── superbridge.t.sol │ └── vault.t.sol ├── connectorPlug.t.sol ├── hooks │ ├── ExecutionHelper.t.sol │ ├── YieldLimitExecutionHook.t.sol │ ├── YieldTokenLimitExecutionHook.t.sol │ ├── limitExecutionHook.t.sol │ └── limitHook.t.sol ├── mocks │ ├── FiatTokenV2_1_Mintable.sol │ ├── MintableToken.sol │ ├── MockExecutableReceiver.sol │ ├── MockSocket.sol │ ├── MockStrategy.sol │ ├── NonMintableToken.sol │ └── hooks │ │ ├── MockYieldBridgeHook.sol │ │ └── MockYieldTokenHook.sol ├── testBridge.sol └── testInbound.t.sol ├── tsconfig.json └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | PROJECT='' # for superbridge aevo, lyra 2 | TOKENS='' # WETH, USDT 3 | DRY_RUN='false' # true, false 4 | 5 | OWNER_SIGNER_KEY='' 6 | OWNER_ADDRESS='' 7 | 8 | ARBISCAN_API_KEY='' 9 | BSCSCAN_API_KEY='' 10 | ETHERSCAN_API_KEY='' 11 | OPTIMISM_API_KEY='' 12 | POLYGONSCAN_API_KEY='' 13 | BASESCAN_API_KEY='' 14 | 15 | ARBITRUM_RPC='' 16 | ARB_SEPOLIA_RPC='' 17 | OPTIMISM_RPC='' 18 | OPTIMISM_SEPOLIA_RPC='' 19 | POLYGON_RPC='' 20 | BSC_RPC='' 21 | BSC_TESTNET_RPC='' 22 | ETHEREUM_RPC='' 23 | SEPOLIA_RPC='' 24 | AEVO_TESTNET_RPC='' 25 | AEVO_RPC='' 26 | LYRA_TESTNET_RPC='' 27 | LYRA_RPC='' 28 | SX_NETWORK_TESTNET_RPC='' 29 | BASE_RPC='' 30 | REYA_CRONOS_RPC='' 31 | REYA_RPC='' 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Dotenv file 11 | .env* 12 | !.env.example 13 | 14 | node_modules 15 | .DS_Store 16 | 17 | #Hardhat files 18 | cache_hardhat/ 19 | artifacts/ 20 | src/types 21 | 22 | #Hardhat plugin files 23 | typechain-types/ 24 | dist/ 25 | 26 | .vscode/ 27 | lcov.info -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | branch = v1.1.1 5 | [submodule "lib/openzeppelin-contracts"] 6 | path = lib/openzeppelin-contracts 7 | url = https://github.com/openzeppelin/openzeppelin-contracts 8 | [submodule "lib/solmate"] 9 | path = lib/solmate 10 | url = https://github.com/transmissions11/solmate 11 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | lib 2 | artifacts 3 | cache 4 | cache_hardhat 5 | 6 | dist 7 | node_modules 8 | out 9 | typechain-types 10 | 11 | .DS_Store 12 | .env* 13 | .gas-snapshot 14 | .gitignore 15 | .gitmodules 16 | .prettierignore 17 | deploy.sh 18 | foundry.toml 19 | LICENSE 20 | remappings.txt 21 | yarn.lock 22 | .github/* 23 | .prettierrc 24 | .git/* 25 | *.jpg 26 | lcov.info 27 | *.toml 28 | *.txt 29 | .idea 30 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": "*.sol", 5 | "options": { 6 | "tabWidth": 4, 7 | "printWidth": 80, 8 | "useTabs": false, 9 | "singleQuote": false, 10 | "bracketSpacing": false 11 | } 12 | }, 13 | { 14 | "files": ["*.js", "*.md"], 15 | "options": { 16 | "tabWidth": 2, 17 | "printWidth": 80, 18 | "useTabs": false, 19 | "semi": true, 20 | "singleQuote": true, 21 | "bracketSpacing": true, 22 | "trailingComma": "all" 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /Errors.md: -------------------------------------------------------------------------------- 1 | Error codes for errors in this project - 2 | 3 | - PlugDisconnected() - 0xe741bafb 4 | - NotHub() - 0x9de97418 5 | - NotSocket() - 0xc59f8f7c 6 | - ConnectorUnavailable() - 0xb1efb84a 7 | - AmountOutsideLimit() - 0x47ebad20 8 | - ZeroAddress() - 0xd92e233d 9 | - InvalidTokenAddress() - 0x1eb00b06 10 | - InvalidPoolId() - 0x0afa7ee8 11 | - ZeroAmount() - 0x1f2a2005 12 | - InvalidTokenContract() - 29bdfb34 13 | - SiblingNotSupported() - 14 | -------------------------------------------------------------------------------- /SUPERBRIDGE_README.md: -------------------------------------------------------------------------------- 1 | ![Superbridge Architecture](diagrams/arch.jpg) 2 | 3 | ### Gauge 4 | 5 | - Abstract contract used to implement rate limits. 6 | 7 | ### ConnectorPlugs 8 | 9 | - Vault and Controller connect to socket via ConnectorPlugs 10 | - This is to enable support of multiple switchboards on same path. 11 | 12 | ### Vault 13 | 14 | - Contract on non App chains. 15 | - Lock and unlock amounts. 16 | - Implements Gauge. 17 | - Revert on lock throttle. 18 | - Store pending and unlock later on unlock throttle. 19 | 20 | ### Controller 21 | 22 | - Contract on App chain. 23 | - Has mint and burn rights on token. 24 | - Calls ExchangeRate contract for lock >> mint and burn >> unlock conversion. 25 | - Implements sibling chain specific Gauge. 26 | - Revert on burn throttle. 27 | - Store pending and mint later on mint throttle. 28 | 29 | ### ExchangeRate 30 | 31 | - Contract for lock >> mint and burn >> unlock conversion. 32 | - Enables path to AMM based bridging. 33 | 34 | ## Throttling 35 | 36 | - Each connector has a configurable `maxLimit` and `ratePerSecond`. 37 | - `maxLimit` defines the maximum amount that can be bridged in the decided time frame. 38 | - `ratePerSecond` defines the rate at which limit is replenished once it is used. The limit keeps increasing with time till it reaches `maxLimit`. 39 | - Eg. Suppose we want to allow maximum 3600 tokens to be deposited per hour. 40 | - `maxLimit = 3600` 41 | - `ratePerSecond = maxLimit / duration = 1` 42 | - If a user were to deposit 3600 tokens, no one would be able to deposit more tokens immediately. 43 | After 10 minutes, users would be able to deposit `10 * 60 * 1 = 600` tokens. 44 | After an hour, they would be able to deposit `60 * 60 * 1 = 3600` tokens. 45 | - If a user were to deposit 1200 tokens, users could deposit `3600 - 1200 = 2400` more tokens immediately. 46 | And after 10 minutes they would be able to deposit `2400 + 10 * 60 * 1 = 3000` tokens. 47 | -------------------------------------------------------------------------------- /SUPERTOKEN_README.md: -------------------------------------------------------------------------------- 1 | ### Socket Plug 2 | 3 | - Socket DL supported plug contract which is used to enable bridge for vault and super token. 4 | 5 | ### SuperToken 6 | 7 | - Super token is an ERC20 contract which allows socket bridge to mint and burn the tokens within a certain daily limit and rate. 8 | - If max limits reaches, it stores the pending amounts which can be minted when limit replenishes. 9 | - This contract also support execution of a `payload` on `destination` after all the funds are transferred to the `receiver` address. This payload can only be executed when pending mint amount is zero. 10 | - If there is no pending amount and payload execution fails, it is cached with the `msgId` which can be retried by anyone using `retryPayloadExecution(msgId)`. 11 | 12 | ### Vault 13 | 14 | - Vault contract is used to lock and unlock tokens within a certain daily limit and rate. 15 | - If max limits reaches, it stores the pending amounts which can be unlocked when limit replenishes. 16 | - This contract also support execution of a `payload` on `destination` after all the funds are transferred to the `receiver` address. This payload can only be executed when pending unlock amount is zero. 17 | - If there is no pending amount and payload execution fails, it is cached with the `msgId` which can be retried by anyone using `retryPayloadExecution(msgId)`. 18 | 19 | ## Throttling 20 | 21 | - Each connector has a configurable `maxLimit` and `ratePerSecond`. 22 | - `maxLimit` defines the maximum amount that can be bridged in the decided time frame. 23 | - `ratePerSecond` defines the rate at which limit is replenished once it is used. The limit keeps increasing with time till it reaches `maxLimit`. 24 | - Eg. Suppose we want to allow maximum 3600 tokens to be deposited per hour. 25 | - `maxLimit = 3600` 26 | - `ratePerSecond = maxLimit / duration = 1` 27 | - If a user were to deposit 3600 tokens, no one would be able to deposit more tokens immediately. 28 | After 10 minutes, users would be able to deposit `10 * 60 * 1 = 600` tokens. 29 | After an hour, they would be able to deposit `60 * 60 * 1 = 3600` tokens. 30 | - If a user were to deposit 1200 tokens, users could deposit `3600 - 1200 = 2400` more tokens immediately. 31 | And after 10 minutes they would be able to deposit `2400 + 10 * 60 * 1 = 3000` tokens. 32 | -------------------------------------------------------------------------------- /YIELD_BRIDGE.md: -------------------------------------------------------------------------------- 1 | ### Socket Yield Bridge 2 | 3 | ## Sync 4 | 5 | - Sync: Used to push the total earnings from strategy to app chain for distribution. 6 | 7 | ## Rebalance 8 | 9 | - Rebalance: Process of depositing collected funds to Strategy, maintaining idle and invested fund ratio and withdrawing if the ratio exceeds the limits. 10 | 11 | - Rebalance delay: delay after which the funds should be pushed to strategy to batch the transfer and save gas 12 | 13 | ## Removed mint-redeem from yield vault 14 | 15 | - As we don't want to use shares on the vault chains, the related operations are removed from here and only necessary logic is picked 16 | 17 | - Cases: 18 | - what if strategy faces loss and total funds reduce on non app chain? 19 | As tokens are rebasing, it will reduce the amount in all wallets 20 | 21 | ## App chain: 22 | 23 | - controller 24 | 25 | - limit controller 26 | - erc4626 without external asset (only withdraw and redeem possible) 27 | - rebase token 28 | 29 | - vault 30 | - limit controller 31 | 32 | ## Known issue: 33 | 34 | - If yield decreases and tokens are yet to be minted, it will create a hole and will have to be paid back by bridge owners. 35 | 36 | 38 | 39 | ## App chain: 40 | 41 | - Rebasing Token is connected to a yield bridge controller with yield bridge token hook 42 | -------------------------------------------------------------------------------- /contracts/bridge/FiatTokenV2_1/FiatTokenV2_1_Controller.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | import {IFiatTokenV2_1_Mintable} from "./IFiatTokenV2_1_Mintable.sol"; 5 | import "../Controller.sol"; 6 | 7 | contract FiatTokenV2_1_Controller is Controller { 8 | using SafeTransferLib for ERC20; 9 | 10 | constructor(address token_) Controller(token_) { 11 | bridgeType = FIAT_TOKEN_CONTROLLER; 12 | } 13 | 14 | function _burn(address user_, uint256 burnAmount_) internal override { 15 | ERC20(token).safeTransferFrom(user_, address(this), burnAmount_); 16 | IFiatTokenV2_1_Mintable(address(token)).burn(burnAmount_); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/bridge/FiatTokenV2_1/IFiatTokenV2_1_Mintable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | import "solmate/tokens/ERC20.sol"; 5 | 6 | // USDC's standard token 7 | abstract contract IFiatTokenV2_1_Mintable is ERC20 { 8 | function mint(address receiver_, uint256 amount_) external virtual; 9 | 10 | function burn(uint256 _amount) external virtual; 11 | } 12 | -------------------------------------------------------------------------------- /contracts/common/Constants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | address constant ETH_ADDRESS = address( 5 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE 6 | ); 7 | 8 | bytes32 constant NORMAL_CONTROLLER = keccak256("NORMAL_CONTROLLER"); 9 | bytes32 constant FIAT_TOKEN_CONTROLLER = keccak256("FIAT_TOKEN_CONTROLLER"); 10 | 11 | bytes32 constant LIMIT_HOOK = keccak256("LIMIT_HOOK"); 12 | bytes32 constant LIMIT_EXECUTION_HOOK = keccak256("LIMIT_EXECUTION_HOOK"); 13 | bytes32 constant LIMIT_EXECUTION_YIELD_HOOK = keccak256( 14 | "LIMIT_EXECUTION_YIELD_HOOK" 15 | ); 16 | bytes32 constant LIMIT_EXECUTION_YIELD_TOKEN_HOOK = keccak256( 17 | "LIMIT_EXECUTION_YIELD_TOKEN_HOOK" 18 | ); 19 | 20 | bytes32 constant ERC20_VAULT = keccak256("ERC20_VAULT"); 21 | bytes32 constant NATIVE_VAULT = keccak256("NATIVE_VAULT"); 22 | -------------------------------------------------------------------------------- /contracts/common/Errors.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | error SiblingNotSupported(); 5 | error NotAuthorized(); 6 | error NotBridge(); 7 | error NotSocket(); 8 | error ConnectorUnavailable(); 9 | error InvalidPoolId(); 10 | error CannotTransferOrExecuteOnBridgeContracts(); 11 | error NoPendingData(); 12 | error MessageIdMisMatched(); 13 | error NotMessageBridge(); 14 | error InvalidSiblingChainSlug(); 15 | error InvalidTokenContract(); 16 | error InvalidExchangeRateContract(); 17 | error InvalidConnector(); 18 | error InvalidConnectorPoolId(); 19 | error ZeroAddressReceiver(); 20 | error ZeroAddress(); 21 | error ZeroAmount(); 22 | error DebtRatioTooHigh(); 23 | error NotEnoughAssets(); 24 | error VaultShutdown(); 25 | error InsufficientFunds(); 26 | error PermitDeadlineExpired(); 27 | error InvalidSigner(); 28 | error InsufficientMsgValue(); 29 | error InvalidOptionsLength(); 30 | -------------------------------------------------------------------------------- /contracts/common/Structs.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | struct UpdateLimitParams { 5 | bool isMint; 6 | address connector; 7 | uint256 maxLimit; 8 | uint256 ratePerSecond; 9 | } 10 | 11 | struct SrcPreHookCallParams { 12 | address connector; 13 | address msgSender; 14 | TransferInfo transferInfo; 15 | } 16 | 17 | struct SrcPostHookCallParams { 18 | address connector; 19 | bytes options; 20 | bytes postHookData; 21 | TransferInfo transferInfo; 22 | } 23 | 24 | struct DstPreHookCallParams { 25 | address connector; 26 | bytes connectorCache; 27 | TransferInfo transferInfo; 28 | } 29 | 30 | struct DstPostHookCallParams { 31 | address connector; 32 | bytes32 messageId; 33 | bytes connectorCache; 34 | bytes postHookData; 35 | TransferInfo transferInfo; 36 | } 37 | 38 | struct PreRetryHookCallParams { 39 | address connector; 40 | CacheData cacheData; 41 | } 42 | 43 | struct PostRetryHookCallParams { 44 | address connector; 45 | bytes32 messageId; 46 | bytes postHookData; 47 | CacheData cacheData; 48 | } 49 | 50 | struct TransferInfo { 51 | address receiver; 52 | uint256 amount; 53 | bytes extraData; 54 | } 55 | 56 | struct CacheData { 57 | bytes identifierCache; 58 | bytes connectorCache; 59 | } 60 | 61 | struct LimitParams { 62 | uint256 lastUpdateTimestamp; 63 | uint256 ratePerSecond; 64 | uint256 maxLimit; 65 | uint256 lastUpdateLimit; 66 | } 67 | -------------------------------------------------------------------------------- /contracts/hooks/HookBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | import "solmate/utils/ReentrancyGuard.sol"; 5 | import "../common/Errors.sol"; 6 | import "../common/Constants.sol"; 7 | import "../interfaces/IHook.sol"; 8 | import "../utils/RescueBase.sol"; 9 | 10 | /** 11 | * @title Base contract for super token and vault 12 | * @notice It contains relevant execution payload storages. 13 | * @dev This contract implements Socket's IPlug to enable message bridging and IMessageBridge 14 | * to support any type of message bridge. 15 | */ 16 | abstract contract HookBase is ReentrancyGuard, IHook, RescueBase { 17 | address public immutable vaultOrController; 18 | bytes32 public hookType; 19 | 20 | /** 21 | * @notice Constructor for creating a new SuperToken. 22 | */ 23 | constructor( 24 | address owner_, 25 | address vaultOrController_ 26 | ) AccessControl(owner_) { 27 | vaultOrController = vaultOrController_; 28 | _grantRole(RESCUE_ROLE, owner_); 29 | } 30 | 31 | modifier isVaultOrController() { 32 | if (msg.sender != vaultOrController) revert NotAuthorized(); 33 | _; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/hooks/plugins/ConnectorPoolPlugin.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | import "../HookBase.sol"; 4 | 5 | abstract contract ConnectorPoolPlugin is HookBase { 6 | // connectorPoolId => totalLockedAmount 7 | mapping(uint256 => uint256) public poolLockedAmounts; 8 | 9 | // connector => connectorPoolId 10 | mapping(address => uint256) public connectorPoolIds; 11 | 12 | event ConnectorPoolIdUpdated(address connector, uint256 poolId); 13 | event PoolLockedAmountUpdated(uint256 poolId, uint256 amount); 14 | 15 | function updateConnectorPoolId( 16 | address[] calldata connectors, 17 | uint256[] calldata poolIds_ 18 | ) external onlyOwner { 19 | uint256 length = connectors.length; 20 | for (uint256 i; i < length; i++) { 21 | if (poolIds_[i] == 0) revert InvalidPoolId(); 22 | connectorPoolIds[connectors[i]] = poolIds_[i]; 23 | emit ConnectorPoolIdUpdated(connectors[i], poolIds_[i]); 24 | } 25 | } 26 | 27 | function updatePoolLockedAmounts( 28 | uint256[] calldata poolIds_, 29 | uint256[] calldata amounts_ 30 | ) external onlyOwner { 31 | uint256 length = poolIds_.length; 32 | for (uint256 i; i < length; i++) { 33 | if (poolIds_[i] == 0) revert InvalidPoolId(); 34 | poolLockedAmounts[poolIds_[i]] = amounts_[i]; 35 | emit PoolLockedAmountUpdated(poolIds_[i], amounts_[i]); 36 | } 37 | } 38 | 39 | function _poolSrcHook(address connector_, uint256 amount_) internal { 40 | uint256 connectorPoolId = connectorPoolIds[connector_]; 41 | if (connectorPoolId == 0) revert InvalidPoolId(); 42 | if (amount_ > poolLockedAmounts[connectorPoolId]) 43 | revert InsufficientFunds(); 44 | 45 | poolLockedAmounts[connectorPoolId] -= amount_; 46 | } 47 | 48 | function _poolDstHook( 49 | address connector_, 50 | uint256 amount_ 51 | ) internal returns (uint256 oldLockedAmount) { 52 | uint256 connectorPoolId = connectorPoolIds[connector_]; 53 | if (connectorPoolId == 0) revert InvalidPoolId(); 54 | 55 | oldLockedAmount = poolLockedAmounts[connectorPoolId]; 56 | poolLockedAmounts[connectorPoolId] += amount_; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /contracts/hooks/plugins/ExecutionHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | import "../../libraries/ExcessivelySafeCall.sol"; 5 | import "../../utils/RescueBase.sol"; 6 | import "../../common/Errors.sol"; 7 | 8 | /** 9 | * @title ExecutionHelper 10 | * @notice It is an untrusted contract used for payload execution by Super token and Vault. 11 | */ 12 | contract ExecutionHelper is RescueBase { 13 | using ExcessivelySafeCall for address; 14 | uint16 private constant MAX_COPY_BYTES = 0; 15 | address public hook; 16 | bytes32 public messageId; 17 | uint256 public bridgeAmount; 18 | 19 | event ExecutionFailed(bytes reason); 20 | 21 | constructor(address owner_) AccessControl(owner_) { 22 | _grantRole(RESCUE_ROLE, owner_); 23 | } 24 | 25 | modifier onlyHook() { 26 | require(msg.sender == hook, "ExecutionHelper: only hook"); 27 | _; 28 | } 29 | 30 | function setHook(address hook_) external onlyOwner { 31 | hook = hook_; 32 | } 33 | 34 | /** 35 | * @notice this function is used to execute a payload at target_ 36 | * @dev receiver address cannot be this contract address. 37 | * @param target_ address of target. 38 | * @param payload_ payload to be executed at target. 39 | */ 40 | function execute( 41 | address target_, 42 | bytes memory payload_, 43 | bytes32 messageId_, 44 | uint256 bridgeAmount_ 45 | ) external onlyHook returns (bool success) { 46 | if (target_ == address(this)) return false; 47 | 48 | messageId = messageId_; 49 | bridgeAmount = bridgeAmount_; 50 | 51 | bytes memory returnData; 52 | (success, returnData) = target_.excessivelySafeCall( 53 | gasleft(), 54 | MAX_COPY_BYTES, 55 | payload_ 56 | ); 57 | 58 | if (!success) emit ExecutionFailed(_getRevertMsg(returnData)); 59 | 60 | messageId = bytes32(0); 61 | bridgeAmount = 0; 62 | } 63 | 64 | function _getRevertMsg( 65 | bytes memory _returnData 66 | ) internal pure returns (bytes memory) { 67 | // If the _res length is less than 68, then the transaction failed silently (without a revert message) 68 | if (_returnData.length < 68) return bytes(""); 69 | return _returnData; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /contracts/interfaces/IBridge.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.3; 3 | 4 | interface IBridge { 5 | function bridge( 6 | address receiver_, 7 | uint256 amount_, 8 | uint256 msgGasLimit_, 9 | address connector_, 10 | bytes calldata extraData_, 11 | bytes calldata options_ 12 | ) external payable; 13 | 14 | function receiveInbound( 15 | uint32 siblingChainSlug_, 16 | bytes memory payload_ 17 | ) external payable; 18 | 19 | function retry(address connector_, bytes32 messageId_) external; 20 | } 21 | -------------------------------------------------------------------------------- /contracts/interfaces/IConnector.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.13; 3 | 4 | interface IConnector { 5 | function outbound( 6 | uint256 msgGasLimit_, 7 | bytes memory payload_, 8 | bytes memory options_ 9 | ) external payable returns (bytes32 messageId_); 10 | 11 | function siblingChainSlug() external view returns (uint32); 12 | 13 | function getMinFees( 14 | uint256 msgGasLimit_, 15 | uint256 payloadSize_ 16 | ) external view returns (uint256 totalFees); 17 | 18 | function getMessageId() external view returns (bytes32); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/interfaces/IController.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.13; 3 | 4 | interface IController { 5 | function identifierCache( 6 | bytes32 messageId_ 7 | ) external payable returns (bytes memory cache); 8 | 9 | function connectorCache( 10 | address connector_ 11 | ) external payable returns (bytes memory cache); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/interfaces/IHook.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.3; 3 | import "../common/Structs.sol"; 4 | 5 | interface IHook { 6 | /** 7 | * @notice Executes pre-hook call for source underlyingAsset. 8 | * @dev This function is used to execute a pre-hook call for the source underlyingAsset before initiating a transfer. 9 | * @param params_ Parameters for the pre-hook call. 10 | * @return transferInfo Information about the transfer. 11 | * @return postHookData returned from the pre-hook call. 12 | */ 13 | function srcPreHookCall( 14 | SrcPreHookCallParams calldata params_ 15 | ) 16 | external 17 | returns (TransferInfo memory transferInfo, bytes memory postHookData); 18 | 19 | function srcPostHookCall( 20 | SrcPostHookCallParams calldata params_ 21 | ) external returns (TransferInfo memory transferInfo); 22 | 23 | /** 24 | * @notice Executes pre-hook call for destination underlyingAsset. 25 | * @dev This function is used to execute a pre-hook call for the destination underlyingAsset before initiating a transfer. 26 | * @param params_ Parameters for the pre-hook call. 27 | */ 28 | function dstPreHookCall( 29 | DstPreHookCallParams calldata params_ 30 | ) 31 | external 32 | returns (bytes memory postHookData, TransferInfo memory transferInfo); 33 | 34 | /** 35 | * @notice Executes post-hook call for destination underlyingAsset. 36 | * @dev This function is used to execute a post-hook call for the destination underlyingAsset after completing a transfer. 37 | * @param params_ Parameters for the post-hook call. 38 | * @return cacheData Cached data for the post-hook call. 39 | */ 40 | function dstPostHookCall( 41 | DstPostHookCallParams calldata params_ 42 | ) external returns (CacheData memory cacheData); 43 | 44 | /** 45 | * @notice Executes a pre-retry hook for a failed transaction. 46 | * @dev This function is used to execute a pre-retry hook for a failed transaction. 47 | * @param params_ Parameters for the pre-retry hook. 48 | * @return postHookData Data from the post-retry hook. 49 | * @return transferInfo Information about the transfer. 50 | */ 51 | function preRetryHook( 52 | PreRetryHookCallParams calldata params_ 53 | ) 54 | external 55 | returns (bytes memory postHookData, TransferInfo memory transferInfo); 56 | 57 | /** 58 | * @notice Executes a post-retry hook for a failed transaction. 59 | * @dev This function is used to execute a post-retry hook for a failed transaction. 60 | * @param params_ Parameters for the post-retry hook. 61 | * @return cacheData Cached data for the post-retry hook. 62 | */ 63 | function postRetryHook( 64 | PostRetryHookCallParams calldata params_ 65 | ) external returns (CacheData memory cacheData); 66 | } 67 | -------------------------------------------------------------------------------- /contracts/interfaces/ILimitHook.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | import "./IHook.sol"; 4 | 5 | interface ILimitHook is IHook { 6 | function updateLimitParams(UpdateLimitParams[] calldata updates) external; 7 | 8 | function checkLimit(address user, uint256 amount) external view; 9 | 10 | function getIdentifierPendingAmount( 11 | bytes32 messageId_ 12 | ) external returns (uint256); 13 | 14 | function getConnectorPendingAmount( 15 | address connector_ 16 | ) external returns (uint256); 17 | 18 | function getCurrentReceivingLimit( 19 | address connector_ 20 | ) external view returns (uint256); 21 | 22 | function getCurrentSendingLimit( 23 | address connector_ 24 | ) external view returns (uint256); 25 | 26 | function getReceivingLimitParams( 27 | address connector_ 28 | ) external view returns (LimitParams memory); 29 | 30 | function getSendingLimitParams( 31 | address connector_ 32 | ) external view returns (LimitParams memory); 33 | } 34 | -------------------------------------------------------------------------------- /contracts/interfaces/IMintableERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | interface IMintableERC20 { 5 | function mint(address receiver_, uint256 amount_) external; 6 | 7 | function burn(address burner_, uint256 amount_) external; 8 | } 9 | -------------------------------------------------------------------------------- /contracts/interfaces/IPlug.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | /** 5 | * @title IPlug 6 | * @notice Interface for a plug contract that executes the message received from a source chain. 7 | */ 8 | interface IPlug { 9 | /** 10 | * @dev this should be only executable by socket 11 | * @notice executes the message received from source chain 12 | * @notice It is expected to have original sender checks in the destination plugs using payload 13 | * @param srcChainSlug_ chain slug of source 14 | * @param payload_ the data which is needed by plug at inbound call on remote 15 | */ 16 | function inbound( 17 | uint32 srcChainSlug_, 18 | bytes calldata payload_ 19 | ) external payable; 20 | } 21 | -------------------------------------------------------------------------------- /contracts/interfaces/IStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | /** 5 | * @title IStrategy 6 | * @notice Interface for strategy contract which interacts with other protocols 7 | */ 8 | interface IStrategy { 9 | function withdraw(uint256 amount_) external returns (uint256 loss_); 10 | 11 | function withdrawAll() external; 12 | 13 | function estimatedTotalAssets() 14 | external 15 | view 16 | returns (uint256 totalUnderlyingAssets_); 17 | 18 | function invest() external; 19 | } 20 | -------------------------------------------------------------------------------- /contracts/libraries/RescueFundsLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | pragma solidity 0.8.13; 3 | 4 | import "solmate/utils/SafeTransferLib.sol"; 5 | import "solmate/tokens/ERC20.sol"; 6 | import {ZeroAddress} from "../common/Errors.sol"; 7 | import {ETH_ADDRESS} from "../common/Constants.sol"; 8 | 9 | /** 10 | * @title RescueFundsLib 11 | * @dev A library that provides a function to rescue funds from a contract. 12 | */ 13 | 14 | library RescueFundsLib { 15 | /** 16 | * @dev thrown when the given token address don't have any code 17 | */ 18 | error InvalidTokenAddress(); 19 | 20 | /** 21 | * @dev Rescues funds from a contract. 22 | * @param token_ The address of the token contract. 23 | * @param rescueTo_ The address of the user. 24 | * @param amount_ The amount of tokens to be rescued. 25 | */ 26 | function rescueFunds( 27 | address token_, 28 | address rescueTo_, 29 | uint256 amount_ 30 | ) internal { 31 | if (rescueTo_ == address(0)) revert ZeroAddress(); 32 | 33 | if (token_ == ETH_ADDRESS) { 34 | SafeTransferLib.safeTransferETH(rescueTo_, amount_); 35 | } else { 36 | if (token_.code.length == 0) revert InvalidTokenAddress(); 37 | SafeTransferLib.safeTransfer(ERC20(token_), rescueTo_, amount_); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/token/DummyERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | import "solmate/tokens/ERC20.sol"; 5 | 6 | /** 7 | * @title DummyERC20 8 | * @notice An Dummy ERC20 contract which is used for testing Superbridge. Do not use in production 9 | * @dev This contract suports minting and burning of tokens 10 | */ 11 | contract DummyERC20 is ERC20 { 12 | /** 13 | * @notice constructor for creating a new Token 14 | * @param name_ token name 15 | * @param symbol_ token symbol 16 | * @param decimals_ token decimals 17 | */ 18 | constructor( 19 | string memory name_, 20 | string memory symbol_, 21 | uint8 decimals_ 22 | ) ERC20(name_, symbol_, decimals_) {} 23 | 24 | function burn(address user_, uint256 amount_) external { 25 | _burn(user_, amount_); 26 | } 27 | 28 | function mint(address receiver_, uint256 amount_) external { 29 | _mint(receiver_, amount_); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /contracts/token/SuperToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | import "solmate/tokens/ERC20.sol"; 5 | import "../utils/RescueBase.sol"; 6 | import "../interfaces/IHook.sol"; 7 | 8 | /** 9 | * @title SuperToken 10 | * @notice An ERC20 contract which enables bridging a token to its sibling chains. 11 | * @dev This contract implements ISuperTokenOrVault to support message bridging through IMessageBridge compliant contracts. 12 | */ 13 | contract SuperToken is ERC20, RescueBase { 14 | // for all controller access (mint, burn) 15 | bytes32 constant CONTROLLER_ROLE = keccak256("CONTROLLER_ROLE"); 16 | 17 | /** 18 | * @notice constructor for creating a new SuperToken. 19 | * @param name_ token name 20 | * @param symbol_ token symbol 21 | * @param decimals_ token decimals (should be same on all chains) 22 | * @param initialSupplyHolder_ address to which initial supply will be minted 23 | * @param owner_ owner of this contract 24 | * @param initialSupply_ initial supply of super token 25 | */ 26 | constructor( 27 | string memory name_, 28 | string memory symbol_, 29 | uint8 decimals_, 30 | address initialSupplyHolder_, 31 | address owner_, 32 | uint256 initialSupply_ 33 | ) ERC20(name_, symbol_, decimals_) AccessControl(owner_) { 34 | _mint(initialSupplyHolder_, initialSupply_); 35 | _grantRole(RESCUE_ROLE, owner_); 36 | } 37 | 38 | function burn( 39 | address user_, 40 | uint256 amount_ 41 | ) external onlyRole(CONTROLLER_ROLE) { 42 | _burn(user_, amount_); 43 | } 44 | 45 | function mint( 46 | address receiver_, 47 | uint256 amount_ 48 | ) external onlyRole(CONTROLLER_ROLE) { 49 | _mint(receiver_, amount_); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/token/yield-token/YieldToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | pragma solidity 0.8.13; 3 | 4 | import "./YieldTokenBase.sol"; 5 | import {IStrategy} from "../../interfaces/IStrategy.sol"; 6 | import {IConnector} from "../../interfaces/IConnector.sol"; 7 | import {IHook} from "../../interfaces/IHook.sol"; 8 | 9 | // add shutdown 10 | contract YieldToken is YieldTokenBase { 11 | using FixedPointMathLib for uint256; 12 | 13 | bytes32 constant MINTER_ROLE = keccak256("MINTER_ROLE"); 14 | bytes32 constant HOOK_ROLE = keccak256("HOOK_ROLE"); 15 | 16 | constructor( 17 | string memory name_, 18 | string memory symbol_, 19 | uint8 decimals_ 20 | ) YieldTokenBase(name_, symbol_, decimals_) AccessControl(msg.sender) { 21 | _grantRole(RESCUE_ROLE, msg.sender); 22 | } 23 | 24 | // move to hook 25 | // fix to round up and check other cases 26 | function calculateMintAmount( 27 | uint256 underlyingAssets_ 28 | ) external view returns (uint256) { 29 | // total supply -> total shares 30 | // total yield -> total underlying from all chains 31 | // yield sent from src chain includes new amount hence subtracted here 32 | uint256 supply = _totalSupply; // Saves an extra SLOAD if _totalSupply is non-zero. 33 | return 34 | supply == 0 35 | ? underlyingAssets_ 36 | : underlyingAssets_.mulDivDown( 37 | supply, 38 | totalUnderlyingAssets - underlyingAssets_ 39 | ); 40 | } 41 | 42 | function burn( 43 | address user_, 44 | uint256 shares_ 45 | ) external nonReentrant onlyRole(MINTER_ROLE) { 46 | _burn(user_, shares_); 47 | } 48 | 49 | // minter role 50 | function mint( 51 | address receiver_, 52 | uint256 amount_ 53 | ) external nonReentrant onlyRole(MINTER_ROLE) { 54 | _mint(receiver_, amount_); 55 | } 56 | 57 | // hook role 58 | function updateTotalUnderlyingAssets( 59 | uint256 amount_ 60 | ) external onlyRole(HOOK_ROLE) { 61 | _updateTotalUnderlyingAssets(amount_); 62 | } 63 | 64 | function _updateTotalUnderlyingAssets(uint256 amount_) internal { 65 | totalUnderlyingAssets = amount_; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /contracts/utils/Gauge.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | import "../common/Structs.sol"; 4 | 5 | abstract contract Gauge { 6 | error AmountOutsideLimit(); 7 | 8 | function _getCurrentLimit( 9 | LimitParams storage _params 10 | ) internal view returns (uint256 _limit) { 11 | uint256 timeElapsed = block.timestamp - _params.lastUpdateTimestamp; 12 | uint256 limitIncrease = timeElapsed * _params.ratePerSecond; 13 | 14 | if (limitIncrease + _params.lastUpdateLimit > _params.maxLimit) { 15 | _limit = _params.maxLimit; 16 | } else { 17 | _limit = limitIncrease + _params.lastUpdateLimit; 18 | } 19 | } 20 | 21 | function _consumePartLimit( 22 | uint256 amount_, 23 | LimitParams storage _params 24 | ) internal returns (uint256 consumedAmount, uint256 pendingAmount) { 25 | uint256 currentLimit = _getCurrentLimit(_params); 26 | _params.lastUpdateTimestamp = block.timestamp; 27 | if (currentLimit >= amount_) { 28 | _params.lastUpdateLimit = currentLimit - amount_; 29 | consumedAmount = amount_; 30 | pendingAmount = 0; 31 | } else { 32 | _params.lastUpdateLimit = 0; 33 | consumedAmount = currentLimit; 34 | pendingAmount = amount_ - currentLimit; 35 | } 36 | } 37 | 38 | function _consumeFullLimit( 39 | uint256 amount_, 40 | LimitParams storage _params 41 | ) internal { 42 | uint256 currentLimit = _getCurrentLimit(_params); 43 | if (currentLimit >= amount_) { 44 | _params.lastUpdateTimestamp = block.timestamp; 45 | _params.lastUpdateLimit = currentLimit - amount_; 46 | } else { 47 | revert AmountOutsideLimit(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /contracts/utils/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | pragma solidity 0.8.13; 3 | 4 | /** 5 | * @title Ownable 6 | * @dev The Ownable contract provides a simple way to manage ownership of a contract 7 | * and allows for ownership to be transferred to a nominated address. 8 | */ 9 | abstract contract Ownable { 10 | address private _owner; 11 | address private _nominee; 12 | 13 | event OwnerNominated(address indexed nominee); 14 | event OwnerClaimed(address indexed claimer); 15 | 16 | error OnlyOwner(); 17 | error OnlyNominee(); 18 | 19 | /** 20 | * @dev Sets the contract's owner to the address that is passed to the constructor. 21 | */ 22 | constructor(address owner_) { 23 | _claimOwner(owner_); 24 | } 25 | 26 | /** 27 | * @dev Modifier that restricts access to only the contract's owner. 28 | * Throws an error if the caller is not the owner. 29 | */ 30 | modifier onlyOwner() { 31 | if (msg.sender != _owner) revert OnlyOwner(); 32 | _; 33 | } 34 | 35 | /** 36 | * @dev Returns the current owner of the contract. 37 | */ 38 | function owner() external view returns (address) { 39 | return _owner; 40 | } 41 | 42 | /** 43 | * @dev Returns the current nominee for ownership of the contract. 44 | */ 45 | function nominee() external view returns (address) { 46 | return _nominee; 47 | } 48 | 49 | /** 50 | * @dev Allows the current owner to nominate a new owner for the contract. 51 | * Throws an error if the caller is not the owner. 52 | * Emits an `OwnerNominated` event with the address of the nominee. 53 | */ 54 | function nominateOwner(address nominee_) external { 55 | if (msg.sender != _owner) revert OnlyOwner(); 56 | _nominee = nominee_; 57 | emit OwnerNominated(_nominee); 58 | } 59 | 60 | /** 61 | * @dev Allows the nominated owner to claim ownership of the contract. 62 | * Throws an error if the caller is not the nominee. 63 | * Sets the nominated owner as the new owner of the contract. 64 | * Emits an `OwnerClaimed` event with the address of the new owner. 65 | */ 66 | function claimOwner() external { 67 | if (msg.sender != _nominee) revert OnlyNominee(); 68 | _claimOwner(msg.sender); 69 | } 70 | 71 | /** 72 | * @dev Internal function that sets the owner of the contract to the specified address 73 | * and sets the nominee to address(0). 74 | */ 75 | function _claimOwner(address claimer_) internal { 76 | _owner = claimer_; 77 | _nominee = address(0); 78 | emit OwnerClaimed(claimer_); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /contracts/utils/RescueBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | import {RescueFundsLib} from "../libraries/RescueFundsLib.sol"; 4 | import {AccessControl} from "./AccessControl.sol"; 5 | 6 | /** 7 | * @title Base contract for super token and vault 8 | * @notice It contains relevant execution payload storages. 9 | * @dev This contract implements Socket's IPlug to enable message bridging and IMessageBridge 10 | * to support any type of message bridge. 11 | */ 12 | abstract contract RescueBase is AccessControl { 13 | bytes32 constant RESCUE_ROLE = keccak256("RESCUE_ROLE"); 14 | 15 | /** 16 | * @notice Rescues funds from the contract if they are locked by mistake. 17 | * @param token_ The address of the token contract. 18 | * @param rescueTo_ The address where rescued tokens need to be sent. 19 | * @param amount_ The amount of tokens to be rescued. 20 | */ 21 | function rescueFunds( 22 | address token_, 23 | address rescueTo_, 24 | uint256 amount_ 25 | ) external onlyRole(RESCUE_ROLE) { 26 | RescueFundsLib.rescueFunds(token_, rescueTo_, amount_); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /deployments/superbridge/dev_aevo-testnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "420": { 3 | "USDC": { 4 | "isAppChain": false, 5 | "NonMintableToken": "0xa23C9E4e3c65729059F12a0463F8c938e0A464d7", 6 | "Vault": "0x4F04f8Ae9Fc3A9539d00e5e69c3b262b31220d00", 7 | "connectors": { 8 | "11155112": { 9 | "FAST": "0xc2BD14Fe818C6Fc47246Bee79F0D91AFbebb43e2" 10 | } 11 | } 12 | }, 13 | "MOON": { 14 | "isAppChain": false, 15 | "NonMintableToken": "0xf848907549f27cC5424Ee0B0F8FE5238113632AF", 16 | "Vault": "0x1b74Ac5DaCa01D82A3d2E7688ea30E50Fe6Ff35E", 17 | "connectors": { 18 | "11155112": { 19 | "FAST": "0x6fEddE12105F47eAcde493Ee294d207bFE68dcE5" 20 | } 21 | } 22 | } 23 | }, 24 | "421613": { 25 | "USDC": { 26 | "isAppChain": false, 27 | "NonMintableToken": "0x010d1DB73263C6ECDD1C1C8711fD79BBb01E719E", 28 | "Vault": "0xFFB09850fAb52765b5E48eAC1AA3fFAD620C8fcE", 29 | "connectors": { 30 | "11155112": { 31 | "FAST": "0x7e54F4c0aCafec318aF1f5d1dCD373CdACc32622" 32 | } 33 | } 34 | }, 35 | "MOON": { 36 | "isAppChain": false, 37 | "NonMintableToken": "0xb1800573eD7828359555279711D8A27928940416", 38 | "Vault": "0x1bcEC7D79b274F01DB2a70D11f4e2907C04E64DF", 39 | "connectors": { 40 | "11155112": { 41 | "FAST": "0x3639bA9D2eCBA74d92Ea400f9E0AA9BA0F79Cc34" 42 | } 43 | } 44 | } 45 | }, 46 | "11155112": { 47 | "USDC": { 48 | "isAppChain": true, 49 | "MintableToken": "0x4D435C00E09034ec2113F63088CCD0be0a0fd06e", 50 | "ExchangeRate": "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf", 51 | "Controller": "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 52 | "connectors": { 53 | "420": { 54 | "FAST": "0x565810cbfa3Cf1390963E5aFa2fB953795686339" 55 | }, 56 | "421613": { 57 | "FAST": "0x8537307810fC40F4073A12a38554D4Ff78EfFf41" 58 | } 59 | } 60 | }, 61 | "MOON": { 62 | "isAppChain": true, 63 | "MintableToken": "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 64 | "ExchangeRate": "0xbDf50eAe568ECef74796ed6022a0d453e8432410", 65 | "Controller": "0x8f9EaEe5c5df888aBA3c1Ab19689a0660d042c6d", 66 | "connectors": { 67 | "420": { 68 | "FAST": "0xaa3d9fA3aB930aE635b001d00C612aa5b14d750e" 69 | }, 70 | "421613": { 71 | "FAST": "0x57D1Aeafb6a2b7Bd4954e47a556622161A8c0A65" 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /deployments/superbridge/dev_lyra-testnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "420": { 3 | "USDC": { 4 | "isAppChain": false, 5 | "NonMintableToken": "0xa23C9E4e3c65729059F12a0463F8c938e0A464d7", 6 | "Vault": "0x1bcEC7D79b274F01DB2a70D11f4e2907C04E64DF", 7 | "connectors": { 8 | "901": { 9 | "FAST": "0x3639bA9D2eCBA74d92Ea400f9E0AA9BA0F79Cc34" 10 | } 11 | } 12 | } 13 | }, 14 | "901": { 15 | "USDC": { 16 | "isAppChain": true, 17 | "MintableToken": "0xe80F2a02398BBf1ab2C9cc52caD1978159c215BD", 18 | "ExchangeRate": "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf", 19 | "Controller": "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 20 | "connectors": { 21 | "420": { 22 | "FAST": "0x565810cbfa3Cf1390963E5aFa2fB953795686339" 23 | }, 24 | "421613": { 25 | "FAST": "0x8537307810fC40F4073A12a38554D4Ff78EfFf41" 26 | } 27 | } 28 | } 29 | }, 30 | "421613": { 31 | "USDC": { 32 | "isAppChain": false, 33 | "NonMintableToken": "0x010d1DB73263C6ECDD1C1C8711fD79BBb01E719E", 34 | "Vault": "0x1F0F1FC746fcd4d59b6dBDDFf67a88cde70dAeE5", 35 | "connectors": { 36 | "901": { 37 | "FAST": "0xD9edcC943ed9729B08E52Bb1e110FE43d1930773" 38 | } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /deployments/superbridge/dev_lyra-testnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "420": [ 3 | [ 4 | "0x3639bA9D2eCBA74d92Ea400f9E0AA9BA0F79Cc34", 5 | "ConnectorPlug", 6 | "contracts/superbridge/ConnectorPlug.sol", 7 | [ 8 | "0x1bcEC7D79b274F01DB2a70D11f4e2907C04E64DF", 9 | "0xD97B9F7fF00E252C0abAa6ce0E13B5F6d9185202", 10 | 901 11 | ] 12 | ], 13 | [ 14 | "0x1bcEC7D79b274F01DB2a70D11f4e2907C04E64DF", 15 | "Vault", 16 | "contracts/superbridge/Vault.sol", 17 | ["0xa23C9E4e3c65729059F12a0463F8c938e0A464d7"] 18 | ] 19 | ], 20 | "901": [ 21 | [ 22 | "0x565810cbfa3Cf1390963E5aFa2fB953795686339", 23 | "ConnectorPlug", 24 | "contracts/superbridge/ConnectorPlug.sol", 25 | [ 26 | "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 27 | "0xa5b593aE839b3fe47983Fc28da602a6dEEfBBc9D", 28 | 420 29 | ] 30 | ], 31 | [ 32 | "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 33 | "ConnectorPlug", 34 | "contracts/superbridge/ConnectorPlug.sol", 35 | [ 36 | "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 37 | "0xa5b593aE839b3fe47983Fc28da602a6dEEfBBc9D", 38 | 421613 39 | ] 40 | ], 41 | [ 42 | "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 43 | "Controller", 44 | "contracts/superbridge/Controller.sol", 45 | [ 46 | "0xe80F2a02398BBf1ab2C9cc52caD1978159c215BD", 47 | "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf" 48 | ] 49 | ], 50 | [ 51 | "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf", 52 | "ExchangeRate", 53 | "contracts/superbridge/ExchangeRate.sol", 54 | [] 55 | ] 56 | ], 57 | "421613": [ 58 | [ 59 | "0xD9edcC943ed9729B08E52Bb1e110FE43d1930773", 60 | "ConnectorPlug", 61 | "contracts/superbridge/ConnectorPlug.sol", 62 | [ 63 | "0x1F0F1FC746fcd4d59b6dBDDFf67a88cde70dAeE5", 64 | "0x5a90a285ab72393B2c47168374895a5C8101012c", 65 | 901 66 | ] 67 | ], 68 | [ 69 | "0x1F0F1FC746fcd4d59b6dBDDFf67a88cde70dAeE5", 70 | "Vault", 71 | "contracts/superbridge/Vault.sol", 72 | ["0x010d1DB73263C6ECDD1C1C8711fD79BBb01E719E"] 73 | ] 74 | ] 75 | } 76 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_aevo-testnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "421614": { 3 | "USDC": { 4 | "isAppChain": false, 5 | "NonMintableToken": "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 6 | "Vault": "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 7 | "connectors": { 8 | "11155112": { 9 | "FAST": "0xbDf50eAe568ECef74796ed6022a0d453e8432410" 10 | } 11 | } 12 | }, 13 | "WETH": { 14 | "isAppChain": false, 15 | "NonMintableToken": "0x565810cbfa3Cf1390963E5aFa2fB953795686339", 16 | "Vault": "0xd286595d2e3D879596FAB51f83A702D10a6db27b", 17 | "connectors": { 18 | "11155112": { 19 | "FAST": "0xA7649aa944b7Dce781859C18913c2Dc8A97f03e4" 20 | } 21 | } 22 | } 23 | }, 24 | "11155112": { 25 | "USDC": { 26 | "isAppChain": true, 27 | "MintableToken": "0x4D435C00E09034ec2113F63088CCD0be0a0fd06e", 28 | "ExchangeRate": "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf", 29 | "Controller": "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 30 | "connectors": { 31 | "421614": { 32 | "FAST": "0x7050b6f947BA48508219Ac02EC152E9f198ADc5e" 33 | }, 34 | "11155420": { 35 | "FAST": "0xb584D4bE1A5470CA1a8778E9B86c81e165204599" 36 | } 37 | } 38 | }, 39 | "WETH": { 40 | "isAppChain": true, 41 | "MintableToken": "0x4B0F1E25d295bC5Bb996b831c826Fe3e7E7Ef13e", 42 | "ExchangeRate": "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf", 43 | "Controller": "0x03027410F25c527D5aEB3E6e56a6389611DCb2A9", 44 | "connectors": { 45 | "421614": { 46 | "FAST": "0xA7f7e4fE8E4cdDCD9969Bd3fbcFF67000CD7DE47" 47 | }, 48 | "11155420": { 49 | "FAST": "0xAC313d7491910516E06FBfC2A0b5BB49bb072D91" 50 | } 51 | } 52 | } 53 | }, 54 | "11155420": { 55 | "USDC": { 56 | "isAppChain": false, 57 | "NonMintableToken": "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf", 58 | "Vault": "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 59 | "connectors": { 60 | "11155112": { 61 | "FAST": "0x565810cbfa3Cf1390963E5aFa2fB953795686339" 62 | } 63 | } 64 | }, 65 | "WETH": { 66 | "isAppChain": false, 67 | "NonMintableToken": "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 68 | "Vault": "0x57D1Aeafb6a2b7Bd4954e47a556622161A8c0A65", 69 | "connectors": { 70 | "11155112": { 71 | "FAST": "0xaa3d9fA3aB930aE635b001d00C612aa5b14d750e" 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_aevo-testnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "421614": [ 3 | [ 4 | "0xA7649aa944b7Dce781859C18913c2Dc8A97f03e4", 5 | "ConnectorPlug", 6 | "contracts/superbridge/ConnectorPlug.sol", 7 | [ 8 | "0xd286595d2e3D879596FAB51f83A702D10a6db27b", 9 | "0xEA59E2b1539b514290dD3dCEa989Ea36279aC6F2", 10 | 11155112 11 | ] 12 | ], 13 | [ 14 | "0xd286595d2e3D879596FAB51f83A702D10a6db27b", 15 | "Vault", 16 | "contracts/superbridge/Vault.sol", 17 | ["0x565810cbfa3Cf1390963E5aFa2fB953795686339"] 18 | ], 19 | [ 20 | "0xbDf50eAe568ECef74796ed6022a0d453e8432410", 21 | "ConnectorPlug", 22 | "contracts/superbridge/ConnectorPlug.sol", 23 | [ 24 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 25 | "0xEA59E2b1539b514290dD3dCEa989Ea36279aC6F2", 26 | 11155112 27 | ] 28 | ], 29 | [ 30 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 31 | "Vault", 32 | "contracts/superbridge/Vault.sol", 33 | ["0x8537307810fC40F4073A12a38554D4Ff78EfFf41"] 34 | ] 35 | ], 36 | "11155112": [ 37 | [ 38 | "0xAC313d7491910516E06FBfC2A0b5BB49bb072D91", 39 | "ConnectorPlug", 40 | "contracts/superbridge/ConnectorPlug.sol", 41 | [ 42 | "0x03027410F25c527D5aEB3E6e56a6389611DCb2A9", 43 | "0xcE713890F07E39C46D698b06042d590289844A13", 44 | 11155420 45 | ] 46 | ], 47 | [ 48 | "0xA7f7e4fE8E4cdDCD9969Bd3fbcFF67000CD7DE47", 49 | "ConnectorPlug", 50 | "contracts/superbridge/ConnectorPlug.sol", 51 | [ 52 | "0x03027410F25c527D5aEB3E6e56a6389611DCb2A9", 53 | "0xcE713890F07E39C46D698b06042d590289844A13", 54 | 421614 55 | ] 56 | ], 57 | [ 58 | "0x03027410F25c527D5aEB3E6e56a6389611DCb2A9", 59 | "Controller", 60 | "contracts/superbridge/Controller.sol", 61 | [ 62 | "0x4B0F1E25d295bC5Bb996b831c826Fe3e7E7Ef13e", 63 | "0x6D290609b3F5F02D52F28d97C75a443ED8564cBf" 64 | ] 65 | ], 66 | [ 67 | "0xb584D4bE1A5470CA1a8778E9B86c81e165204599", 68 | "ConnectorPlug", 69 | "contracts/superbridge/ConnectorPlug.sol", 70 | [ 71 | "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 72 | "0xcE713890F07E39C46D698b06042d590289844A13", 73 | 11155420 74 | ] 75 | ], 76 | [ 77 | "0x7050b6f947BA48508219Ac02EC152E9f198ADc5e", 78 | "ConnectorPlug", 79 | "contracts/superbridge/ConnectorPlug.sol", 80 | [ 81 | "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 82 | "0xcE713890F07E39C46D698b06042d590289844A13", 83 | 421614 84 | ] 85 | ] 86 | ], 87 | "11155420": [ 88 | [ 89 | "0xaa3d9fA3aB930aE635b001d00C612aa5b14d750e", 90 | "ConnectorPlug", 91 | "contracts/superbridge/ConnectorPlug.sol", 92 | [ 93 | "0x57D1Aeafb6a2b7Bd4954e47a556622161A8c0A65", 94 | "0xEA59E2b1539b514290dD3dCEa989Ea36279aC6F2", 95 | 11155112 96 | ] 97 | ], 98 | [ 99 | "0x57D1Aeafb6a2b7Bd4954e47a556622161A8c0A65", 100 | "Vault", 101 | "contracts/superbridge/Vault.sol", 102 | ["0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3"] 103 | ], 104 | [ 105 | "0x565810cbfa3Cf1390963E5aFa2fB953795686339", 106 | "ConnectorPlug", 107 | "contracts/superbridge/ConnectorPlug.sol", 108 | [ 109 | "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 110 | "0xEA59E2b1539b514290dD3dCEa989Ea36279aC6F2", 111 | 11155112 112 | ] 113 | ], 114 | [ 115 | "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 116 | "Vault", 117 | "contracts/superbridge/Vault.sol", 118 | ["0x6D290609b3F5F02D52F28d97C75a443ED8564cBf"] 119 | ] 120 | ] 121 | } 122 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_b3_mainnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "8333": { 3 | "B3": { 4 | "isAppChain": true, 5 | "MintableToken": "0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3", 6 | "Controller": "0x6873ED2dda63e44C2F655Dd093ceb6DCA96e5Fc3", 7 | "LimitHook": "0x4F1505f9615D94651FD3Ca5aD8910875E9aA2854", 8 | "connectors": { 9 | "8453": { 10 | "FAST": "0xf5BDA9694F6f155348144faA6A1961D1a22C2Db4" 11 | } 12 | } 13 | } 14 | }, 15 | "8453": { 16 | "B3": { 17 | "isAppChain": false, 18 | "NonMintableToken": "0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3", 19 | "Vault": "0x5D6689B75A3019712A93aD866f119b66D664E198", 20 | "LimitHook": "0x1a0dfde3FE4f15119bC750414A3457BF5E9E8C25", 21 | "connectors": { 22 | "8333": { 23 | "FAST": "0x20bDD81FeA5A5e6a539Be17d2029204b16626624" 24 | } 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_b3_mainnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "8333": [ 3 | [ 4 | "0xf5BDA9694F6f155348144faA6A1961D1a22C2Db4", 5 | "ConnectorPlug", 6 | "contracts/ConnectorPlug.sol", 7 | [ 8 | "0x6873ED2dda63e44C2F655Dd093ceb6DCA96e5Fc3", 9 | "0x0CC93650bF4D98237628DACf87f94E443956D8dF", 10 | 8453, 11 | "0x0000000000000000000000000000000000000000000000000000000000000000" 12 | ] 13 | ], 14 | [ 15 | "0x4F1505f9615D94651FD3Ca5aD8910875E9aA2854", 16 | "LimitHook", 17 | "contracts/hooks/LimitHook.sol", 18 | [ 19 | "0xB0BBff6311B7F245761A7846d3Ce7B1b100C1836", 20 | "0x6873ED2dda63e44C2F655Dd093ceb6DCA96e5Fc3", 21 | true 22 | ] 23 | ], 24 | [ 25 | "0x6873ED2dda63e44C2F655Dd093ceb6DCA96e5Fc3", 26 | "FiatTokenV2_1_Controller", 27 | "contracts/bridge/FiatTokenV2_1/FiatTokenV2_1_Controller.sol", 28 | ["0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3"] 29 | ] 30 | ], 31 | "8453": [ 32 | [ 33 | "0x20bDD81FeA5A5e6a539Be17d2029204b16626624", 34 | "ConnectorPlug", 35 | "contracts/ConnectorPlug.sol", 36 | [ 37 | "0x5D6689B75A3019712A93aD866f119b66D664E198", 38 | "0x12E6e58864cE4402cF2B4B8a8E9c75eAD7280156", 39 | 8333, 40 | "0x0000000000000000000000000000000000000000000000000000000000000000" 41 | ] 42 | ], 43 | [ 44 | "0x1a0dfde3FE4f15119bC750414A3457BF5E9E8C25", 45 | "LimitHook", 46 | "contracts/hooks/LimitHook.sol", 47 | [ 48 | "0xB0BBff6311B7F245761A7846d3Ce7B1b100C1836", 49 | "0x5D6689B75A3019712A93aD866f119b66D664E198", 50 | false 51 | ] 52 | ], 53 | [ 54 | "0x5D6689B75A3019712A93aD866f119b66D664E198", 55 | "Vault", 56 | "contracts/bridge/Vault.sol", 57 | ["0xB3B32F9f8827D4634fE7d973Fa1034Ec9fdDB3B3"] 58 | ] 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_looks-testnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "11155112": {}, 3 | "11155420": {} 4 | } 5 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_mode_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": { 3 | "USDC": { 4 | "isAppChain": false, 5 | "NonMintableToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" 6 | } 7 | }, 8 | "10": { 9 | "USDC": { 10 | "isAppChain": false, 11 | "NonMintableToken": "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", 12 | "Vault": "0x2BBc2ED3931234E803618202Fe2F060e56625626", 13 | "connectors": { 14 | "34443": { 15 | "FAST": "0x55FA0806268ff0a1D9dFf19633E37EE5Ce5d7671" 16 | } 17 | } 18 | } 19 | }, 20 | "8453": { 21 | "USDC": { 22 | "isAppChain": false, 23 | "NonMintableToken": "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA", 24 | "Vault": "0x4C9faD010D8be90Aba505c85eacc483dFf9b8Fa9", 25 | "connectors": { 26 | "34443": { 27 | "FAST": "0x19609EeE157BC38E1A40E19c38218fC3900d97ac" 28 | } 29 | } 30 | } 31 | }, 32 | "34443": { 33 | "USDC": { 34 | "isAppChain": true, 35 | "MintableToken": "0x6df6c0e70d6874a37084270De861D4be682f271b", 36 | "ExchangeRate": "0x9ca48cAF8AD2B081a0b633d6FCD803076F719fEa", 37 | "Controller": "0x0f933F6a58D885586d356d6677DC87995bdC1B51", 38 | "connectors": { 39 | "10": { 40 | "FAST": "0xe48AE3B68f0560d4aaA312E12fD687630C948561" 41 | }, 42 | "8453": { 43 | "FAST": "0x87225Ec2C6d8ee8293E8F5667077d699eC2FB6Db" 44 | }, 45 | "42161": { 46 | "FAST": "0x06714dD1783C7Eb28c918156727bfD3aef8A4B8D" 47 | } 48 | } 49 | } 50 | }, 51 | "42161": { 52 | "USDC": { 53 | "isAppChain": false, 54 | "NonMintableToken": "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", 55 | "Vault": "0x0825266F72e8841D7FEA350B20DD65AA861ACeE9", 56 | "connectors": { 57 | "34443": { 58 | "FAST": "0x31dBDaf7A388735E95a1f68494621D0d82583c86" 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_mode_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": [ 3 | [ 4 | "0x55FA0806268ff0a1D9dFf19633E37EE5Ce5d7671", 5 | "ConnectorPlug", 6 | "contracts/superbridge/ConnectorPlug.sol", 7 | [ 8 | "0x2BBc2ED3931234E803618202Fe2F060e56625626", 9 | "0x301bD265F0b3C16A58CbDb886Ad87842E3A1c0a4", 10 | 34443 11 | ] 12 | ], 13 | [ 14 | "0x4bD04aF43a5789E6404919b70078e6D1969E24c7", 15 | "ConnectorPlug", 16 | "contracts/superbridge/ConnectorPlug.sol", 17 | [ 18 | "0x2BBc2ED3931234E803618202Fe2F060e56625626", 19 | "0x301bD265F0b3C16A58CbDb886Ad87842E3A1c0a4", 20 | 34443 21 | ] 22 | ], 23 | [ 24 | "0x2BBc2ED3931234E803618202Fe2F060e56625626", 25 | "Vault", 26 | "contracts/superbridge/Vault.sol", 27 | ["0x7F5c764cBc14f9669B88837ca1490cCa17c31607"] 28 | ] 29 | ], 30 | "8453": [ 31 | [ 32 | "0x19609EeE157BC38E1A40E19c38218fC3900d97ac", 33 | "ConnectorPlug", 34 | "contracts/superbridge/ConnectorPlug.sol", 35 | [ 36 | "0x4C9faD010D8be90Aba505c85eacc483dFf9b8Fa9", 37 | "0x12E6e58864cE4402cF2B4B8a8E9c75eAD7280156", 38 | 34443 39 | ] 40 | ], 41 | [ 42 | "0x1281C1464449DB73bdAa30928BCC63Dc25D8D187", 43 | "ConnectorPlug", 44 | "contracts/superbridge/ConnectorPlug.sol", 45 | [ 46 | "0x4C9faD010D8be90Aba505c85eacc483dFf9b8Fa9", 47 | "0x12E6e58864cE4402cF2B4B8a8E9c75eAD7280156", 48 | 34443 49 | ] 50 | ], 51 | [ 52 | "0x4C9faD010D8be90Aba505c85eacc483dFf9b8Fa9", 53 | "Vault", 54 | "contracts/superbridge/Vault.sol", 55 | ["0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA"] 56 | ] 57 | ], 58 | "34443": [ 59 | [ 60 | "0x87225Ec2C6d8ee8293E8F5667077d699eC2FB6Db", 61 | "ConnectorPlug", 62 | "contracts/superbridge/ConnectorPlug.sol", 63 | [ 64 | "0x0f933F6a58D885586d356d6677DC87995bdC1B51", 65 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 66 | 8453 67 | ] 68 | ], 69 | [ 70 | "0x06714dD1783C7Eb28c918156727bfD3aef8A4B8D", 71 | "ConnectorPlug", 72 | "contracts/superbridge/ConnectorPlug.sol", 73 | [ 74 | "0x0f933F6a58D885586d356d6677DC87995bdC1B51", 75 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 76 | 42161 77 | ] 78 | ], 79 | [ 80 | "0xe48AE3B68f0560d4aaA312E12fD687630C948561", 81 | "ConnectorPlug", 82 | "contracts/superbridge/ConnectorPlug.sol", 83 | [ 84 | "0x0f933F6a58D885586d356d6677DC87995bdC1B51", 85 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 86 | 10 87 | ] 88 | ], 89 | [ 90 | "0x0f933F6a58D885586d356d6677DC87995bdC1B51", 91 | "FiatTokenV2_1_Controller", 92 | "contracts/superbridge/FiatTokenV2_1/FiatTokenV2_1_Controller.sol", 93 | [ 94 | "0x6df6c0e70d6874a37084270De861D4be682f271b", 95 | "0x9ca48cAF8AD2B081a0b633d6FCD803076F719fEa" 96 | ] 97 | ], 98 | [ 99 | "0x9ca48cAF8AD2B081a0b633d6FCD803076F719fEa", 100 | "ExchangeRate", 101 | "contracts/superbridge/ExchangeRate.sol", 102 | [] 103 | ] 104 | ], 105 | "42161": [ 106 | [ 107 | "0x31dBDaf7A388735E95a1f68494621D0d82583c86", 108 | "ConnectorPlug", 109 | "contracts/superbridge/ConnectorPlug.sol", 110 | [ 111 | "0x0825266F72e8841D7FEA350B20DD65AA861ACeE9", 112 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 113 | 34443 114 | ] 115 | ], 116 | [ 117 | "0xa451cc3077729EcaEb3Ba2cBFd5326a90cBc4ad9", 118 | "ConnectorPlug", 119 | "contracts/superbridge/ConnectorPlug.sol", 120 | [ 121 | "0x0825266F72e8841D7FEA350B20DD65AA861ACeE9", 122 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 123 | 34443 124 | ] 125 | ], 126 | [ 127 | "0x0825266F72e8841D7FEA350B20DD65AA861ACeE9", 128 | "Vault", 129 | "contracts/superbridge/Vault.sol", 130 | ["0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8"] 131 | ] 132 | ] 133 | } 134 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_sx-network-testnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "647": { 3 | "USDC": { 4 | "isAppChain": true, 5 | "MintableToken": "0x5147891461a7C81075950f8eE6384e019e39ab98", 6 | "ExchangeRate": "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 7 | "Controller": "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 8 | "connectors": { 9 | "80001": { 10 | "FAST": "0x565810cbfa3Cf1390963E5aFa2fB953795686339" 11 | }, 12 | "11155111": { 13 | "FAST": "0xc317144DE60E6bC9455363bB09852C00bd14CD61" 14 | } 15 | } 16 | } 17 | }, 18 | "80001": { 19 | "USDC": { 20 | "isAppChain": false, 21 | "NonMintableToken": "0xD9edcC943ed9729B08E52Bb1e110FE43d1930773", 22 | "Vault": "0x613efcCFa27110e2A4d12e0467599a2911Fd96dc", 23 | "connectors": { 24 | "647": { 25 | "FAST": "0x7ae16402d316686a149Ea49bDcB208AADCfBcFf8" 26 | } 27 | } 28 | } 29 | }, 30 | "11155111": { 31 | "USDC": { 32 | "isAppChain": false, 33 | "NonMintableToken": "0x565810cbfa3Cf1390963E5aFa2fB953795686339", 34 | "Vault": "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 35 | "connectors": { 36 | "647": { 37 | "FAST": "0x57D1Aeafb6a2b7Bd4954e47a556622161A8c0A65" 38 | } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_sx-network-testnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "647": [ 3 | [ 4 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 5 | "ConnectorPlug", 6 | "contracts/superbridge/ConnectorPlug.sol", 7 | [ 8 | "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 9 | "0x834Ee253f0B926DCc1d03EbAeAfEc3a3D1eE4a86", 10 | 11155111 11 | ] 12 | ], 13 | [ 14 | "0x565810cbfa3Cf1390963E5aFa2fB953795686339", 15 | "ConnectorPlug", 16 | "contracts/superbridge/ConnectorPlug.sol", 17 | [ 18 | "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 19 | "0x834Ee253f0B926DCc1d03EbAeAfEc3a3D1eE4a86", 20 | 80001 21 | ] 22 | ], 23 | [ 24 | "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 25 | "Controller", 26 | "contracts/superbridge/Controller.sol", 27 | [ 28 | "0x5147891461a7C81075950f8eE6384e019e39ab98", 29 | "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3" 30 | ] 31 | ], 32 | [ 33 | "0x2b42AFFD4b7C14d9B7C2579229495c052672Ccd3", 34 | "ExchangeRate", 35 | "contracts/superbridge/ExchangeRate.sol", 36 | [] 37 | ] 38 | ], 39 | "80001": [ 40 | [ 41 | "0x7ae16402d316686a149Ea49bDcB208AADCfBcFf8", 42 | "ConnectorPlug", 43 | "contracts/superbridge/ConnectorPlug.sol", 44 | [ 45 | "0x613efcCFa27110e2A4d12e0467599a2911Fd96dc", 46 | "0x54FEAB3E649Ac262028996C6082F736182717abb", 47 | 647 48 | ] 49 | ], 50 | [ 51 | "0x613efcCFa27110e2A4d12e0467599a2911Fd96dc", 52 | "Vault", 53 | "contracts/superbridge/Vault.sol", 54 | ["0xD9edcC943ed9729B08E52Bb1e110FE43d1930773"] 55 | ], 56 | [ 57 | "0xD9edcC943ed9729B08E52Bb1e110FE43d1930773", 58 | "NonMintableToken", 59 | "contracts/superbridge/NonMintableToken.sol", 60 | [ 61 | "USD coin", 62 | "USDC", 63 | 6, 64 | { 65 | "type": "BigNumber", 66 | "hex": "0x038d7ea4c68000" 67 | } 68 | ] 69 | ] 70 | ], 71 | "11155111": [ 72 | [ 73 | "0x57D1Aeafb6a2b7Bd4954e47a556622161A8c0A65", 74 | "ConnectorPlug", 75 | "contracts/superbridge/ConnectorPlug.sol", 76 | [ 77 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 78 | "0x07e11D1A1543B0D0b91684eb741d1ab7D51ae237", 79 | 647 80 | ] 81 | ], 82 | [ 83 | "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 84 | "Vault", 85 | "contracts/superbridge/Vault.sol", 86 | ["0x565810cbfa3Cf1390963E5aFa2fB953795686339"] 87 | ], 88 | [ 89 | "0x565810cbfa3Cf1390963E5aFa2fB953795686339", 90 | "NonMintableToken", 91 | "contracts/superbridge/NonMintableToken.sol", 92 | [ 93 | "USD coin", 94 | "USDC", 95 | 6, 96 | { 97 | "type": "BigNumber", 98 | "hex": "0x038d7ea4c68000" 99 | } 100 | ] 101 | ] 102 | ] 103 | } 104 | -------------------------------------------------------------------------------- /deployments/superbridge/prod_syndr-sepolia-l3_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "80001": { 3 | "USDC": { 4 | "isAppChain": false, 5 | "NonMintableToken": "" 6 | } 7 | }, 8 | "421614": { 9 | "USDC": { 10 | "isAppChain": false, 11 | "NonMintableToken": "0x05A7428e6A82b347EDb3881Be60775D63dCF958E", 12 | "Vault": "0x1156bAFb7c72bfFC963038E5C65E8531F15a4a21", 13 | "connectors": { 14 | "444444": { 15 | "FAST": "0xd21109653316B21853e3FAB84E4C1E06B9Ee4429" 16 | } 17 | } 18 | }, 19 | "USDT": { 20 | "isAppChain": false, 21 | "NonMintableToken": "0xaF047bEF3F961bEa6f5340C6F0bBf6Ce093A0553", 22 | "Vault": "0xFA3ff93563759625b630FD10d05843b8384d0150", 23 | "connectors": { 24 | "444444": { 25 | "FAST": "0x5D19D6B71975D12B31A36E62086c11c08F0ddBcf" 26 | } 27 | } 28 | }, 29 | "DAI": { 30 | "isAppChain": false, 31 | "NonMintableToken": "0x351d4C4cDd7975d943276B1F4C764A5D57Df04D4", 32 | "Vault": "0xF0CB21fc8583942F20ebc41Ff2C7089DBa843432", 33 | "connectors": { 34 | "444444": { 35 | "FAST": "0x0948B1ce6B7e98B0c68D7480eE5B13c51965195B" 36 | } 37 | } 38 | }, 39 | "WETH": { 40 | "isAppChain": false, 41 | "NonMintableToken": "0x1E291EdD64dd12415150340Bbb5a1734bb69Ca13", 42 | "Vault": "0x137f30B529535a96b2A60A4F9DeAeB3D34566215", 43 | "connectors": { 44 | "444444": { 45 | "FAST": "0xFfcBD42167550EdB20D64f99278537075723B4C8" 46 | } 47 | } 48 | }, 49 | "WBTC": { 50 | "isAppChain": false, 51 | "NonMintableToken": "0xD4537cb13FEB420a5B7D2FFf5700f53A2fc020F9", 52 | "Vault": "0x4FE1aDdCb348BF191164FB10605C8Beec8D42aBd", 53 | "connectors": { 54 | "444444": { 55 | "FAST": "0x5333982087C2Db4f85d0Ed2CdE22b22ABC0fdae3" 56 | } 57 | } 58 | } 59 | }, 60 | "444444": { 61 | "USDC": { 62 | "isAppChain": true, 63 | "MintableToken": "0xb3578Ae827CAe9ac0C658294611D1E51A752f25B", 64 | "ExchangeRate": "0xc317144DE60E6bC9455363bB09852C00bd14CD61", 65 | "Controller": "0xbDf50eAe568ECef74796ed6022a0d453e8432410", 66 | "connectors": { 67 | "421614": { 68 | "FAST": "0x8f9EaEe5c5df888aBA3c1Ab19689a0660d042c6d" 69 | } 70 | } 71 | }, 72 | "USDT": { 73 | "isAppChain": true, 74 | "MintableToken": "0x22D84b9B9d41E2E80484326a4D86704EdEFD05fc", 75 | "ExchangeRate": "0x57D1Aeafb6a2b7Bd4954e47a556622161A8c0A65", 76 | "Controller": "0xaa3d9fA3aB930aE635b001d00C612aa5b14d750e", 77 | "connectors": { 78 | "421614": { 79 | "FAST": "0xd286595d2e3D879596FAB51f83A702D10a6db27b" 80 | } 81 | } 82 | }, 83 | "DAI": { 84 | "isAppChain": true, 85 | "MintableToken": "0x0b2effd3fCbCd921b17E73f019D68062100777fe", 86 | "ExchangeRate": "0xA7649aa944b7Dce781859C18913c2Dc8A97f03e4", 87 | "Controller": "0x852C5DE08b9beB014caD171C16B12a8D7456ea3f", 88 | "connectors": { 89 | "421614": { 90 | "FAST": "0x040993fbF458b95871Cd2D73Ee2E09F4AF6d56bB" 91 | } 92 | } 93 | }, 94 | "WETH": { 95 | "isAppChain": true, 96 | "MintableToken": "0x61A910409315Cb3d35A6d981A498ADdDE7223B07", 97 | "ExchangeRate": "0xBE51D38547992293c89CC589105784ab60b004A9", 98 | "Controller": "0x5800249621DA520aDFdCa16da20d8A5Fc0f814d8", 99 | "connectors": { 100 | "421614": { 101 | "FAST": "0xc0E02AA55d10e38855e13B64A8E1387A04681A00" 102 | } 103 | } 104 | }, 105 | "WBTC": { 106 | "isAppChain": true, 107 | "MintableToken": "0x64754c6a03af632005dF65a983C5A33c04A316A2", 108 | "ExchangeRate": "0xF51e426240E1C0b63dC7F7ec8b172376487329E3", 109 | "Controller": "0x2ddf16BA6d0180e5357d5e170eF1917a01b41fc0", 110 | "connectors": { 111 | "421614": { 112 | "FAST": "0x7050b6f947BA48508219Ac02EC152E9f198ADc5e" 113 | } 114 | } 115 | } 116 | }, 117 | "11155111": { 118 | "USDC": { 119 | "isAppChain": false, 120 | "NonMintableToken": "" 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /deployments/superbridge/surge_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "polter_testnet": { 3 | "398274": { 4 | "USDC": { 5 | "isAppChain": true, 6 | "MintableToken": "0x15Bb97f748B341D1f464A7257d75da879D83fC9F", 7 | "Controller": "0xb5B1e1Ba18d323a2a7313f970bF4310cF8d60B8D", 8 | "LimitHook": "0x06F92b5D06D54802601CBAf862fe549e7EaedcF7", 9 | "connectors": { 10 | "421614": { 11 | "FAST": "0xBec0d54fC3ba4b264e816328a5C60F2Ca48f9aEf" 12 | } 13 | } 14 | } 15 | }, 16 | "421614": { 17 | "USDC": { 18 | "isAppChain": false, 19 | "NonMintableToken": "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 20 | "Vault": "0xa9d73443b11596D3D44BfafA052c07b7833fF736", 21 | "LimitHook": "0x6d64dE68a6BBC57AfDf5ba9B32469c66238d1A07", 22 | "connectors": { 23 | "398274": { 24 | "FAST": "0xC95e769b47eaDAf9057a9EDF735707B97b4CC9aA" 25 | } 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /deployments/superbridge/surge_polter_testnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "398274": { 3 | "USDC": { 4 | "isAppChain": true, 5 | "MintableToken": "0x15Bb97f748B341D1f464A7257d75da879D83fC9F", 6 | "Controller": "0xb5B1e1Ba18d323a2a7313f970bF4310cF8d60B8D", 7 | "LimitHook": "0x06F92b5D06D54802601CBAf862fe549e7EaedcF7", 8 | "connectors": { 9 | "421614": { 10 | "FAST": "0xBec0d54fC3ba4b264e816328a5C60F2Ca48f9aEf" 11 | } 12 | } 13 | } 14 | }, 15 | "421614": { 16 | "USDC": { 17 | "isAppChain": false, 18 | "NonMintableToken": "0x8537307810fC40F4073A12a38554D4Ff78EfFf41", 19 | "Vault": "0xa9d73443b11596D3D44BfafA052c07b7833fF736", 20 | "LimitHook": "0x6d64dE68a6BBC57AfDf5ba9B32469c66238d1A07", 21 | "connectors": { 22 | "398274": { 23 | "FAST": "0xC95e769b47eaDAf9057a9EDF735707B97b4CC9aA" 24 | } 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /deployments/superbridge/surge_polter_testnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "398274": [ 3 | [ 4 | "0xBec0d54fC3ba4b264e816328a5C60F2Ca48f9aEf", 5 | "ConnectorPlug", 6 | "contracts/ConnectorPlug.sol", 7 | [ 8 | "0xb5B1e1Ba18d323a2a7313f970bF4310cF8d60B8D", 9 | "0x5C4186D343EeF952c9ED886E45F8243edf0A503F", 10 | 421614, 11 | "0x0000000000000000000000000000000000000000000000000000000000000000" 12 | ] 13 | ], 14 | [ 15 | "0x06F92b5D06D54802601CBAf862fe549e7EaedcF7", 16 | "LimitHook", 17 | "contracts/hooks/LimitHook.sol", 18 | [ 19 | "0x44A44837894B5eDC2Bde64567FC62599b3b88F4C", 20 | "0xb5B1e1Ba18d323a2a7313f970bF4310cF8d60B8D", 21 | true 22 | ] 23 | ], 24 | [ 25 | "0xb5B1e1Ba18d323a2a7313f970bF4310cF8d60B8D", 26 | "Controller", 27 | "contracts/bridge/Controller.sol", 28 | ["0x15Bb97f748B341D1f464A7257d75da879D83fC9F"] 29 | ] 30 | ], 31 | "421614": [ 32 | [ 33 | "0xC95e769b47eaDAf9057a9EDF735707B97b4CC9aA", 34 | "ConnectorPlug", 35 | "contracts/ConnectorPlug.sol", 36 | [ 37 | "0xa9d73443b11596D3D44BfafA052c07b7833fF736", 38 | "0x5798C2D27Db969fda2E43dE0871C21823E6418B8", 39 | 398274, 40 | "0x0000000000000000000000000000000000000000000000000000000000000000" 41 | ] 42 | ], 43 | [ 44 | "0x6d64dE68a6BBC57AfDf5ba9B32469c66238d1A07", 45 | "LimitHook", 46 | "contracts/hooks/LimitHook.sol", 47 | [ 48 | "0x44A44837894B5eDC2Bde64567FC62599b3b88F4C", 49 | "0xa9d73443b11596D3D44BfafA052c07b7833fF736", 50 | false 51 | ] 52 | ], 53 | [ 54 | "0xa9d73443b11596D3D44BfafA052c07b7833fF736", 55 | "Vault", 56 | "contracts/bridge/Vault.sol", 57 | ["0x8537307810fC40F4073A12a38554D4Ff78EfFf41"] 58 | ] 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_aavegotchi_mainnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "137": { 3 | "FUD": { 4 | "NonMintableToken": "0x403e967b044d4be25170310157cb1a4bf10bdd0f", 5 | "Vault": "0xBdc2420b1E7F1f97d45b55a2ea9d3b4eB2675B75", 6 | "LimitHook": "0x6F0265143A2A20D7eD61953A134255396aE66113", 7 | "connectors": { 8 | "8453": { 9 | "FAST": "0x2Da6f1DD5Bc4d456Da29a1138c2646Ad6E56F6d6" 10 | } 11 | } 12 | }, 13 | "FOMO": { 14 | "NonMintableToken": "0x44a6e0be76e1d9620a7f76588e4509fe4fa8e8c8", 15 | "Vault": "0x321fCfC2cc0d45d2eb252A11bBA8274543819feB", 16 | "LimitHook": "0x480e5C74F86a6948EA8972fc00FD65a405d7028F", 17 | "connectors": { 18 | "8453": { 19 | "FAST": "0xE8E9341ec9f2Fb97F794bE3505b76e0685cd5D3B" 20 | } 21 | } 22 | }, 23 | "ALPHA": { 24 | "NonMintableToken": "0x6a3E7C3c6EF65Ee26975b12293cA1AAD7e1dAeD2", 25 | "Vault": "0xc87653358D5EDc7716057c865b8cD9ac5eB44A16", 26 | "LimitHook": "0xF0FE22c3795764a3CEFd21518c8d0fE5515C9AA1", 27 | "connectors": { 28 | "8453": { 29 | "FAST": "0x13A2714aEfeBBee8D2F73B65396ADCa556C6b0Cc" 30 | } 31 | } 32 | }, 33 | "KEK": { 34 | "NonMintableToken": "0x42E5E06EF5b90Fe15F853F59299Fc96259209c5C", 35 | "Vault": "0x3D57A1a3429825C35B7C432F8885fA1D0Eede460", 36 | "LimitHook": "0xEeeF79d797fd4e10508153EbA204080F4B3bbb0F", 37 | "connectors": { 38 | "8453": { 39 | "FAST": "0x3E7D7F9E3C3B5610711fe2Fc777F22dB464C37c3" 40 | } 41 | } 42 | }, 43 | "GLTR": { 44 | "NonMintableToken": "0x3801C3B3B5c98F88a9c9005966AA96aa440B9Afc", 45 | "Vault": "0x8B2D15F61B99De5Fd53dfCFFf8AF995f17f9536d", 46 | "LimitHook": "0x3e12C3593A0fAc10a56A4e7857fdfaB22b76A678", 47 | "connectors": { 48 | "8453": { 49 | "FAST": "0x4B10af24DbcfFA13208Ccaa9E0FB17bb547a20bd" 50 | } 51 | } 52 | } 53 | }, 54 | "8453": { 55 | "FUD": { 56 | "SuperToken": "0x4595Ea2d4d76e067D6701552b8A66743f048A38b", 57 | "Controller": "0xBdc2420b1E7F1f97d45b55a2ea9d3b4eB2675B75", 58 | "LimitHook": "0x6F0265143A2A20D7eD61953A134255396aE66113", 59 | "connectors": { 60 | "137": { 61 | "FAST": "0x2Da6f1DD5Bc4d456Da29a1138c2646Ad6E56F6d6" 62 | } 63 | } 64 | }, 65 | "FOMO": { 66 | "SuperToken": "0xB501045c286E2e499D761106Da367B7b9D72De9e", 67 | "Controller": "0x321fCfC2cc0d45d2eb252A11bBA8274543819feB", 68 | "LimitHook": "0x480e5C74F86a6948EA8972fc00FD65a405d7028F", 69 | "connectors": { 70 | "137": { 71 | "FAST": "0xE8E9341ec9f2Fb97F794bE3505b76e0685cd5D3B" 72 | } 73 | } 74 | }, 75 | "ALPHA": { 76 | "SuperToken": "0x73e49fa294e6198400cA693a856816E23D0968Ee", 77 | "Controller": "0xc87653358D5EDc7716057c865b8cD9ac5eB44A16", 78 | "LimitHook": "0xF0FE22c3795764a3CEFd21518c8d0fE5515C9AA1", 79 | "connectors": { 80 | "137": { 81 | "FAST": "0x13A2714aEfeBBee8D2F73B65396ADCa556C6b0Cc" 82 | } 83 | } 84 | }, 85 | "KEK": { 86 | "SuperToken": "0x59c98408F27517937D2065d61862eBF129B07FD9", 87 | "Controller": "0x3D57A1a3429825C35B7C432F8885fA1D0Eede460", 88 | "LimitHook": "0xEeeF79d797fd4e10508153EbA204080F4B3bbb0F", 89 | "connectors": { 90 | "137": { 91 | "FAST": "0x3E7D7F9E3C3B5610711fe2Fc777F22dB464C37c3" 92 | } 93 | } 94 | }, 95 | "GLTR": { 96 | "SuperToken": "0x2D400eB3beee681471F59da5B1a0d61A18Dee743", 97 | "Controller": "0x8B2D15F61B99De5Fd53dfCFFf8AF995f17f9536d", 98 | "LimitHook": "0x3e12C3593A0fAc10a56A4e7857fdfaB22b76A678", 99 | "connectors": { 100 | "137": { 101 | "FAST": "0x4B10af24DbcfFA13208Ccaa9E0FB17bb547a20bd" 102 | } 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_magic_mainnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": { 3 | "MAGIC": { 4 | "SuperToken": "0x0d3eC0ec5BfBDCC1527060E2e0939251B1D12a31", 5 | "Controller": "0xa240B15bCB997320Ee74606197CC5F48bC0e57ef", 6 | "connectors": { 7 | "42161": { 8 | "OPTIMISTIC": "0xc3A52186d2DD0Ad084e49822854C7C93FC0E8735" 9 | } 10 | } 11 | } 12 | }, 13 | "42161": { 14 | "MAGIC": { 15 | "NonMintableToken": "0x539bde0d7dbd336b79148aa742883198bbf60342", 16 | "Vault": "0xa240B15bCB997320Ee74606197CC5F48bC0e57ef", 17 | "connectors": { 18 | "10": { 19 | "OPTIMISTIC": "0xc3A52186d2DD0Ad084e49822854C7C93FC0E8735" 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_magic_mainnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": [ 3 | [ 4 | "0xc3A52186d2DD0Ad084e49822854C7C93FC0E8735", 5 | "ConnectorPlug", 6 | "contracts/ConnectorPlug.sol", 7 | [ 8 | "0xa240B15bCB997320Ee74606197CC5F48bC0e57ef", 9 | "0x301bD265F0b3C16A58CbDb886Ad87842E3A1c0a4", 10 | 42161, 11 | "0x0000000000000000000000000000000000000000000000000000000000000000" 12 | ] 13 | ], 14 | [ 15 | "0xa240B15bCB997320Ee74606197CC5F48bC0e57ef", 16 | "Controller", 17 | "contracts/bridge/Controller.sol", 18 | ["0x0d3eC0ec5BfBDCC1527060E2e0939251B1D12a31"] 19 | ], 20 | [ 21 | "0x644Ee8BE4a1A2e78460Fbe76E6dA260e0822Ee42", 22 | "ConnectorPlug", 23 | "contracts/ConnectorPlug.sol", 24 | [ 25 | "0x4B13F35352448aa77e83F19401dcB6B0c2810520", 26 | "0x301bD265F0b3C16A58CbDb886Ad87842E3A1c0a4", 27 | 42161, 28 | "0x0000000000000000000000000000000000000000000000000000000000000000" 29 | ] 30 | ], 31 | [ 32 | "0x4B13F35352448aa77e83F19401dcB6B0c2810520", 33 | "Controller", 34 | "contracts/bridge/Controller.sol", 35 | ["0x0d3eC0ec5BfBDCC1527060E2e0939251B1D12a31"] 36 | ], 37 | [ 38 | "0x0d3eC0ec5BfBDCC1527060E2e0939251B1D12a31", 39 | "SuperToken", 40 | "contracts/token/SuperToken.sol", 41 | [ 42 | "magic", 43 | "MAGIC", 44 | 18, 45 | "0xdE7f7a699F8504641eceF544B0fbc0740C37E69B", 46 | "0xdE7f7a699F8504641eceF544B0fbc0740C37E69B", 47 | { 48 | "type": "BigNumber", 49 | "hex": "0x00" 50 | } 51 | ] 52 | ] 53 | ], 54 | "42161": [ 55 | [ 56 | "0xc3A52186d2DD0Ad084e49822854C7C93FC0E8735", 57 | "ConnectorPlug", 58 | "contracts/ConnectorPlug.sol", 59 | [ 60 | "0xa240B15bCB997320Ee74606197CC5F48bC0e57ef", 61 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 62 | 10, 63 | "0x0000000000000000000000000000000000000000000000000000000000000000" 64 | ] 65 | ], 66 | [ 67 | "0xa240B15bCB997320Ee74606197CC5F48bC0e57ef", 68 | "Vault", 69 | "contracts/bridge/Vault.sol", 70 | ["0x539bde0d7dbd336b79148aa742883198bbf60342"] 71 | ], 72 | [ 73 | "0x32cff852308d5f37e12372b3403c87C15195777C", 74 | "ConnectorPlug", 75 | "contracts/ConnectorPlug.sol", 76 | [ 77 | "0x644Ee8BE4a1A2e78460Fbe76E6dA260e0822Ee42", 78 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 79 | 10, 80 | "0x0000000000000000000000000000000000000000000000000000000000000000" 81 | ] 82 | ], 83 | [ 84 | "0x644Ee8BE4a1A2e78460Fbe76E6dA260e0822Ee42", 85 | "Vault", 86 | "contracts/bridge/Vault.sol", 87 | ["0x539bde0d7dbd336b79148aa742883198bbf60342"] 88 | ] 89 | ] 90 | } 91 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_magical_demo_mainnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": { 3 | "MAGIC": { 4 | "SuperToken": "0xbc325c4C4c74E3586f080AFc6f4C177eBe2900bf", 5 | "Controller": "0xa3dd024BAE09aa606257976215bE1AcC9B2ffdd8", 6 | "LimitHook": "0xB5dbaC5d028FA9680171AB70E82aBF2Ab9902618", 7 | "connectors": { 8 | "8453": { 9 | "FAST": "0x349Dd53d3fe777405Ae4fC83F7F842C2A564a0da" 10 | }, 11 | "42161": { 12 | "FAST": "0x19Ba6C8D70f526F8Fa8C6086608dB871F41C8704" 13 | } 14 | } 15 | } 16 | }, 17 | "8453": { 18 | "MAGIC": { 19 | "SuperToken": "0x83A52B74e06d1A705e35BB939Be95fcEF7b14CAb", 20 | "Controller": "0x5E5677D808795844662681c3A6CEd9855cf4B476", 21 | "LimitHook": "0x04a6f5bc61Fe5e7908955F60e80779730c4069B1", 22 | "connectors": { 23 | "10": { 24 | "FAST": "0x8e89587020D99D92f4AE987A5D168d6DFDb54011" 25 | }, 26 | "42161": { 27 | "FAST": "0xae69069B4eb0ff55f68d3b9700337eC3d1353785" 28 | } 29 | } 30 | } 31 | }, 32 | "42161": { 33 | "MAGIC": { 34 | "NonMintableToken": "0x539bde0d7dbd336b79148aa742883198bbf60342", 35 | "Vault": "0x349Dd53d3fe777405Ae4fC83F7F842C2A564a0da", 36 | "LimitHook": "0x19Ba6C8D70f526F8Fa8C6086608dB871F41C8704", 37 | "connectors": { 38 | "10": { 39 | "FAST": "0xf27d68CD34ddaB4Fa49461768345B2d8764cBB70" 40 | }, 41 | "8453": { 42 | "FAST": "0xDC5645EF6ecF650A83B4D2a63979B9C0908Bb0Cb" 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_spectral-signal_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "56": { 3 | "GUARD": { 4 | "NonMintableToken": "0xF606bd19b1E61574ED625d9ea96C841D4E247A32", 5 | "Vault": "0xef8d3a1fd0F9a0E04D19e29e03a16CaE0b4eD1f8", 6 | "LimitHook": "0x18266D052afF1Da6550ab51c0181924Ad45D9f42", 7 | "connectors": { 8 | "137": { 9 | "FAST": "0x67a1311532ffb1A6624C2F5BE02b2a487b0120E9" 10 | }, 11 | "42161": { 12 | "FAST": "0xe64Ac3Ec7feb2dc96586588C58C91849D9b4e3F3" 13 | } 14 | } 15 | } 16 | }, 17 | "137": { 18 | "GUARD": { 19 | "SuperToken": "0xB0B2Ef34D412d73b0Ff90A709D1779A20655165A", 20 | "Controller": "0xE24007Ea3fAC1EC3fb580d40658600E31c73dDD1", 21 | "LimitHook": "0x46333edd8A5bb17080457CA57f20d4086cCafdad", 22 | "connectors": { 23 | "56": { 24 | "FAST": "0xB8d31f18A1099F967c8c9e7d4c0C7B035241c56C" 25 | }, 26 | "42161": { 27 | "FAST": "0x3E6BD7feB3bFC6723D0489E1A67232F9C594bB0F" 28 | } 29 | } 30 | } 31 | }, 32 | "42161": { 33 | "GUARD": { 34 | "SuperToken": "0xbCF339DF10d78f2b44AA760EAd0F715A7A7d7269", 35 | "Controller": "0x9CF6f370fC5cDf5Fb81783f26c064d142AA1Bc56", 36 | "LimitHook": "0xe4593eD6f711A298eb05dAc61141F4f3Ce6fa37a", 37 | "connectors": { 38 | "56": { 39 | "FAST": "0xFF17d331174137cCd1C392a77e898B36DdD7FF54" 40 | }, 41 | "137": { 42 | "FAST": "0x5ea1172D7c6BB48fDdE560c8Cfc6660519E1fF41" 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_spectral-signal_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "56": [ 3 | [ 4 | "0x67a1311532ffb1A6624C2F5BE02b2a487b0120E9", 5 | "ConnectorPlug", 6 | "contracts/ConnectorPlug.sol", 7 | [ 8 | "0xef8d3a1fd0F9a0E04D19e29e03a16CaE0b4eD1f8", 9 | "0xdF7f95dda500E8EFc872f1dc0BC46a4E6281C00e", 10 | 137 11 | ] 12 | ], 13 | [ 14 | "0xe64Ac3Ec7feb2dc96586588C58C91849D9b4e3F3", 15 | "ConnectorPlug", 16 | "contracts/ConnectorPlug.sol", 17 | [ 18 | "0xef8d3a1fd0F9a0E04D19e29e03a16CaE0b4eD1f8", 19 | "0xdF7f95dda500E8EFc872f1dc0BC46a4E6281C00e", 20 | 42161 21 | ] 22 | ], 23 | [ 24 | "0x18266D052afF1Da6550ab51c0181924Ad45D9f42", 25 | "LimitHook", 26 | "contracts/hooks/LimitHook.sol", 27 | [ 28 | "0x5fD7D0d6b91CC4787Bcb86ca47e0Bd4ea0346d34", 29 | "0xef8d3a1fd0F9a0E04D19e29e03a16CaE0b4eD1f8", 30 | false 31 | ] 32 | ], 33 | [ 34 | "0xef8d3a1fd0F9a0E04D19e29e03a16CaE0b4eD1f8", 35 | "Vault", 36 | "contracts/bridge/Vault.sol", 37 | ["0xF606bd19b1E61574ED625d9ea96C841D4E247A32"] 38 | ] 39 | ], 40 | "137": [ 41 | [ 42 | "0xB8d31f18A1099F967c8c9e7d4c0C7B035241c56C", 43 | "ConnectorPlug", 44 | "contracts/ConnectorPlug.sol", 45 | [ 46 | "0xE24007Ea3fAC1EC3fb580d40658600E31c73dDD1", 47 | "0xc20687f8dc0ad51d01003013d1c5b02d10DED001", 48 | 56 49 | ] 50 | ], 51 | [ 52 | "0x3E6BD7feB3bFC6723D0489E1A67232F9C594bB0F", 53 | "ConnectorPlug", 54 | "contracts/ConnectorPlug.sol", 55 | [ 56 | "0xE24007Ea3fAC1EC3fb580d40658600E31c73dDD1", 57 | "0xc20687f8dc0ad51d01003013d1c5b02d10DED001", 58 | 42161 59 | ] 60 | ], 61 | [ 62 | "0x46333edd8A5bb17080457CA57f20d4086cCafdad", 63 | "LimitHook", 64 | "contracts/hooks/LimitHook.sol", 65 | [ 66 | "0x5fD7D0d6b91CC4787Bcb86ca47e0Bd4ea0346d34", 67 | "0xE24007Ea3fAC1EC3fb580d40658600E31c73dDD1", 68 | false 69 | ] 70 | ], 71 | [ 72 | "0xE24007Ea3fAC1EC3fb580d40658600E31c73dDD1", 73 | "Controller", 74 | "contracts/bridge/Controller.sol", 75 | ["0xB0B2Ef34D412d73b0Ff90A709D1779A20655165A"] 76 | ] 77 | ], 78 | "42161": [ 79 | [ 80 | "0xFF17d331174137cCd1C392a77e898B36DdD7FF54", 81 | "ConnectorPlug", 82 | "contracts/ConnectorPlug.sol", 83 | [ 84 | "0x9CF6f370fC5cDf5Fb81783f26c064d142AA1Bc56", 85 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 86 | 56 87 | ] 88 | ], 89 | [ 90 | "0x5ea1172D7c6BB48fDdE560c8Cfc6660519E1fF41", 91 | "ConnectorPlug", 92 | "contracts/ConnectorPlug.sol", 93 | [ 94 | "0x9CF6f370fC5cDf5Fb81783f26c064d142AA1Bc56", 95 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 96 | 137 97 | ] 98 | ], 99 | [ 100 | "0xe4593eD6f711A298eb05dAc61141F4f3Ce6fa37a", 101 | "LimitHook", 102 | "contracts/hooks/LimitHook.sol", 103 | [ 104 | "0x5fD7D0d6b91CC4787Bcb86ca47e0Bd4ea0346d34", 105 | "0x9CF6f370fC5cDf5Fb81783f26c064d142AA1Bc56", 106 | false 107 | ] 108 | ], 109 | [ 110 | "0x9CF6f370fC5cDf5Fb81783f26c064d142AA1Bc56", 111 | "Controller", 112 | "contracts/bridge/Controller.sol", 113 | ["0xbCF339DF10d78f2b44AA760EAd0F715A7A7d7269"] 114 | ] 115 | ] 116 | } 117 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_testing_mainnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": { 3 | "MTK": { 4 | "SuperToken": "0x094553F42B44Ea1492b0dcA5f4134F23f45db742", 5 | "Controller": "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 6 | "LimitHook": "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 7 | "connectors": { 8 | "42161": { 9 | "FAST": "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561" 10 | } 11 | } 12 | } 13 | }, 14 | "42161": { 15 | "MTK": { 16 | "NonMintableToken": "0x094553F42B44Ea1492b0dcA5f4134F23f45db742", 17 | "Vault": "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 18 | "LimitHook": "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 19 | "connectors": { 20 | "10": { 21 | "FAST": "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561" 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_testing_mainnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": [ 3 | [ 4 | "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561", 5 | "ConnectorPlug", 6 | "contracts/ConnectorPlug.sol", 7 | [ 8 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 9 | "0x301bD265F0b3C16A58CbDb886Ad87842E3A1c0a4", 10 | 42161 11 | ] 12 | ], 13 | [ 14 | "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 15 | "LimitHook", 16 | "contracts/hooks/LimitHook.sol", 17 | [ 18 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 19 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 20 | false 21 | ] 22 | ], 23 | [ 24 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 25 | "Controller", 26 | "contracts/bridge/Controller.sol", 27 | ["0x094553F42B44Ea1492b0dcA5f4134F23f45db742"] 28 | ], 29 | [ 30 | "0x094553F42B44Ea1492b0dcA5f4134F23f45db742", 31 | "SuperToken", 32 | "contracts/token/SuperToken.sol", 33 | [ 34 | "SuperMockToken", 35 | "SMTK", 36 | 18, 37 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 38 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 39 | 0 40 | ] 41 | ] 42 | ], 43 | "42161": [ 44 | [ 45 | "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561", 46 | "ConnectorPlug", 47 | "contracts/ConnectorPlug.sol", 48 | [ 49 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 50 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 51 | 10 52 | ] 53 | ], 54 | [ 55 | "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 56 | "LimitHook", 57 | "contracts/hooks/LimitHook.sol", 58 | [ 59 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 60 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 61 | false 62 | ] 63 | ], 64 | [ 65 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 66 | "Vault", 67 | "contracts/bridge/Vault.sol", 68 | ["0x094553F42B44Ea1492b0dcA5f4134F23f45db742"] 69 | ] 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_testing_testnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "421614": { 3 | "MTK": { 4 | "NonMintableToken": "0x094553F42B44Ea1492b0dcA5f4134F23f45db742", 5 | "Vault": "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 6 | "LimitHook": "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 7 | "connectors": { 8 | "11155420": { 9 | "FAST": "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561" 10 | } 11 | } 12 | } 13 | }, 14 | "11155420": { 15 | "MTK": { 16 | "SuperToken": "0x094553F42B44Ea1492b0dcA5f4134F23f45db742", 17 | "Controller": "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 18 | "LimitHook": "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 19 | "connectors": { 20 | "421614": { 21 | "FAST": "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561" 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_testing_testnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "421614": [ 3 | [ 4 | "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561", 5 | "ConnectorPlug", 6 | "contracts/ConnectorPlug.sol", 7 | [ 8 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 9 | "0xEA59E2b1539b514290dD3dCEa989Ea36279aC6F2", 10 | 11155420 11 | ] 12 | ], 13 | [ 14 | "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 15 | "LimitHook", 16 | "contracts/hooks/LimitHook.sol", 17 | [ 18 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 19 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 20 | false 21 | ] 22 | ], 23 | [ 24 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 25 | "Vault", 26 | "contracts/bridge/Vault.sol", 27 | ["0x094553F42B44Ea1492b0dcA5f4134F23f45db742"] 28 | ] 29 | ], 30 | "11155420": [ 31 | [ 32 | "0x339c460Be9F32604273d1Ba6D47Af3691Cab2561", 33 | "ConnectorPlug", 34 | "contracts/ConnectorPlug.sol", 35 | [ 36 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 37 | "0xEA59E2b1539b514290dD3dCEa989Ea36279aC6F2", 38 | 421614 39 | ] 40 | ], 41 | [ 42 | "0xe34847AaA952C85c0466ec26a438bfB4528a059F", 43 | "LimitHook", 44 | "contracts/hooks/LimitHook.sol", 45 | [ 46 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 47 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 48 | false 49 | ] 50 | ], 51 | [ 52 | "0x8B745d1979879e686E326c5274EF64E7dB4170dF", 53 | "Controller", 54 | "contracts/bridge/Controller.sol", 55 | ["0x094553F42B44Ea1492b0dcA5f4134F23f45db742"] 56 | ], 57 | [ 58 | "0x094553F42B44Ea1492b0dcA5f4134F23f45db742", 59 | "SuperToken", 60 | "contracts/token/SuperToken.sol", 61 | [ 62 | "SuperMockToken", 63 | "SMTK", 64 | 18, 65 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 66 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 67 | 0 68 | ] 69 | ] 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_timeswap_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "420": { 3 | "SocketPlug": "0x0d4c6fd645Ae536EDdE6688736Fa8c08295ce6f8", 4 | "SuperToken": "0x89dFbBde140FCFE428E443e64244913DAe46021d" 5 | }, 6 | "80001": { 7 | "SocketPlug": "0x5Fa0244513bC80d2D7E64018f0c9177539640cf8", 8 | "NonSuperToken": "0xB24d5ef4066Ba3eAF276313F6c476b82a5eDd780", 9 | "SuperTokenVault": "0xF55327A3b9Ae930Ab4391df1a506d24160446620" 10 | }, 11 | "421613": { 12 | "SocketPlug": "0xe19877990491DAA2F18137CE578df1a009ed8333", 13 | "SuperToken": "0xAcEFb125EBD5a6716856fbf58E2067660949f17C" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_timeswap_test_mainnet_addresses.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": { 3 | "STIME": { 4 | "SuperToken": "0x5e24d4e71d8fc876af3D45499f6b9E8A296EC694", 5 | "Controller": "0x68E85149bCF40E717Be880a2B8798946794054DF", 6 | "LimitHook": "0x16AC85d468B3D80Aee762f2B5739A67D7A916e86", 7 | "connectors": { 8 | "42161": { 9 | "FAST": "0xac03f33BdDc7C7D002B9426cdA0f1f5Ad366E26b" 10 | } 11 | } 12 | } 13 | }, 14 | "42161": { 15 | "STIME": { 16 | "NonMintableToken": "0x17AfF554423D2C40A1BBF51b443E9d43dd8AE1eb", 17 | "Vault": "0xac03f33BdDc7C7D002B9426cdA0f1f5Ad366E26b", 18 | "LimitHook": "0x897692516f0e3408180f660b86f94b325a95B4d2", 19 | "connectors": { 20 | "10": { 21 | "FAST": "0x54855aDcbfCE382F8aD4a933C67017D5B5A4636F" 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /deployments/supertoken/prod_timeswap_test_mainnet_verification.json: -------------------------------------------------------------------------------- 1 | { 2 | "10": [ 3 | [ 4 | "0xac03f33BdDc7C7D002B9426cdA0f1f5Ad366E26b", 5 | "ConnectorPlug", 6 | "contracts/ConnectorPlug.sol", 7 | [ 8 | "0x68E85149bCF40E717Be880a2B8798946794054DF", 9 | "0x301bD265F0b3C16A58CbDb886Ad87842E3A1c0a4", 10 | 42161 11 | ] 12 | ], 13 | [ 14 | "0x16AC85d468B3D80Aee762f2B5739A67D7A916e86", 15 | "LimitHook", 16 | "contracts/hooks/LimitHook.sol", 17 | [ 18 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 19 | "0x68E85149bCF40E717Be880a2B8798946794054DF", 20 | false 21 | ] 22 | ], 23 | [ 24 | "0x68E85149bCF40E717Be880a2B8798946794054DF", 25 | "Controller", 26 | "contracts/bridge/Controller.sol", 27 | ["0x5e24d4e71d8fc876af3D45499f6b9E8A296EC694"] 28 | ] 29 | ], 30 | "42161": [ 31 | [ 32 | "0x54855aDcbfCE382F8aD4a933C67017D5B5A4636F", 33 | "ConnectorPlug", 34 | "contracts/ConnectorPlug.sol", 35 | [ 36 | "0xac03f33BdDc7C7D002B9426cdA0f1f5Ad366E26b", 37 | "0x37cc674582049b579571E2fFd890a4d99355f6Ba", 38 | 10 39 | ] 40 | ], 41 | [ 42 | "0x897692516f0e3408180f660b86f94b325a95B4d2", 43 | "LimitHook", 44 | "contracts/hooks/LimitHook.sol", 45 | [ 46 | "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 47 | "0xac03f33BdDc7C7D002B9426cdA0f1f5Ad366E26b", 48 | false 49 | ] 50 | ], 51 | [ 52 | "0xac03f33BdDc7C7D002B9426cdA0f1f5Ad366E26b", 53 | "Vault", 54 | "contracts/bridge/Vault.sol", 55 | ["0x17AfF554423D2C40A1BBF51b443E9d43dd8AE1eb"] 56 | ] 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /diagrams/arch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SocketDotTech/socket-plugs/24551fb53934d39b307d01c06684f4caa4435d5e/diagrams/arch.jpg -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'contracts' 3 | out = 'out' 4 | libs = ['lib'] 5 | solc_version = '0.8.13' 6 | optimizer = true 7 | optimizer_runs = 99999 8 | no-match-contract='LyraBurnUSDC' 9 | 10 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config 11 | -------------------------------------------------------------------------------- /funding.json: -------------------------------------------------------------------------------- 1 | { 2 | "opRetro": { 3 | "projectId": "0xe8833ceee8beb2b3fb0f7f2dcef576f6f9cf20e35d8e53324d71b0ed47b01982" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "strict": false, 6 | "esModuleInterop": true, 7 | "outDir": "dist", 8 | "declaration": true, 9 | "resolveJsonModule": true 10 | }, 11 | "include": ["./deployments", "./script", "./src", "./hardhat.config.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@socket.tech/socket-plugs", 3 | "license": "MIT", 4 | "version": "1.0.30", 5 | "description": "Plugs built using socket's data layer", 6 | "main": "./dist/src/index.js", 7 | "types": "./dist/src/index.d.ts", 8 | "files": [ 9 | "dist", 10 | "artifacts/abi", 11 | "deployments" 12 | ], 13 | "publishConfig": { 14 | "access": "public" 15 | }, 16 | "repository": "git@github.com:SocketDotTech/socketDL-examples.git", 17 | "devDependencies": { 18 | "@ethersproject/bytes": "^5.7.0", 19 | "@nomicfoundation/hardhat-foundry": "^1.1.2", 20 | "@nomiclabs/hardhat-ethers": "^2.1.1", 21 | "@nomiclabs/hardhat-etherscan": "^3.1.0", 22 | "@typechain/ethers-v5": "^10.0.0", 23 | "@typechain/hardhat": "^6.0.0", 24 | "@types/mocha": "^9.1.0", 25 | "@types/node": "^18.11.9", 26 | "@types/prompts": "^2.4.9", 27 | "@types/yargs": "^17.0.22", 28 | "dotenv": "^16.0.3", 29 | "ethers": "^5.6.6", 30 | "hardhat": "^2.17.2", 31 | "hardhat-abi-exporter": "^2.10.1", 32 | "hardhat-change-network": "^0.0.7", 33 | "hardhat-deploy": "^0.11.20", 34 | "hardhat-preprocessor": "^0.1.4", 35 | "pre-commit": "^1.2.2", 36 | "prettier": "^2.6.1", 37 | "prettier-plugin-solidity": "^1.0.0-beta.13", 38 | "ts-node": "^10.7.0", 39 | "typechain": "^8.0.0", 40 | "typescript": "^4.6.4" 41 | }, 42 | "scripts": { 43 | "lint": "prettier \"./**\" --write", 44 | "build": "hardhat export-abi && hardhat typechain && yarn buildJson && tsc --project lib.tsconfig.json", 45 | "buildJson": "npx ts-node ./script/helpers/updateJsons.ts", 46 | "abi": "hardhat export-abi", 47 | "compile": "forge build", 48 | "test": "forge test", 49 | "setup:all": "forge install && yarn install && yarn setup:dependencies && yarn build", 50 | "setup:dependencies": "yarn && yarn add @socket.tech/dl-core", 51 | "script:setup": "yarn setup:dependencies && npx ts-node script/setup.ts", 52 | "script:deploy": "npx hardhat run script/deploy.ts", 53 | "script:verify": "npx hardhat run script/deploy/verifyContracts.ts", 54 | "script:bridge": "npx ts-node script/bridge/bridge.ts", 55 | "project:new": "npx ts-node script/script.ts new", 56 | "project:edit": "npx ts-node script/script.ts edit", 57 | "project:addToken": "npx ts-node script/script.ts add_token", 58 | "bridge": "npx hardhat run script/bridge/bridge.ts" 59 | }, 60 | "pre-commit": [ 61 | "lint", 62 | "compile" 63 | ], 64 | "dependencies": { 65 | "@arbitrum/sdk": "^3.7.0", 66 | "@eth-optimism/sdk": "^3.3.2", 67 | "@socket.tech/dl-core": "^2.39.0", 68 | "lodash": "^4.17.21", 69 | "prompts": "^2.4.2" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /remappings.txt: -------------------------------------------------------------------------------- 1 | ds-test/=lib/forge-std/lib/ds-test/src/ 2 | forge-std/=lib/forge-std/src/ 3 | solmate/=lib/solmate/src/ 4 | openzeppelin-contracts/=lib/openzeppelin-contracts/ 5 | -------------------------------------------------------------------------------- /script/admin/check-minter-permission.ts: -------------------------------------------------------------------------------- 1 | import { getSuperBridgeAddresses } from "../helpers"; 2 | import { Contract } from "ethers"; 3 | import { getProviderFromChainSlug } from "../helpers/networks"; 4 | import { isSBAppChain } from "../helpers/projectConstants"; 5 | import { MINTABLE_ABI } from "../constants/abis/mintable"; 6 | 7 | export const main = async () => { 8 | try { 9 | const addresses = await getSuperBridgeAddresses(); 10 | for (const chain of Object.keys(addresses)) { 11 | console.log(`\nChecking addresses for chain ${chain}`); 12 | for (const token of Object.keys(addresses[chain])) { 13 | if (!isSBAppChain(+chain, token)) continue; 14 | 15 | const tokenAddress = addresses[chain][token].MintableToken; 16 | const controller = addresses[chain][token].Controller; 17 | const mintable = new Contract( 18 | tokenAddress, 19 | MINTABLE_ABI, 20 | getProviderFromChainSlug(+chain) 21 | ); 22 | let isMinter; 23 | try { 24 | isMinter = await mintable.minters(controller); 25 | } catch (error) { 26 | try { 27 | isMinter = await mintable.permitted(controller); 28 | } catch (error) { 29 | isMinter = await mintable.isMinter(controller); 30 | } 31 | } 32 | 33 | console.log( 34 | `Controller (${controller}) for ${token} (${tokenAddress}) on chain ${chain} ${ 35 | isMinter ? "can" : "cannot" 36 | } mint` 37 | ); 38 | } 39 | } 40 | } catch (error) { 41 | console.error("Error while checking minter", error); 42 | } 43 | }; 44 | 45 | main() 46 | .then(() => process.exit(0)) 47 | .catch((error: Error) => { 48 | console.error(error); 49 | process.exit(1); 50 | }); 51 | -------------------------------------------------------------------------------- /script/admin/check-vault-balances.ts: -------------------------------------------------------------------------------- 1 | import { getSuperBridgeAddresses } from "../helpers"; 2 | import { ethers } from "ethers"; 3 | import { getProviderFromChainSlug } from "../helpers/networks"; 4 | import { isSBAppChain } from "../helpers/projectConstants"; 5 | import { ERC20__factory } from "../../typechain-types"; 6 | import { tokenDecimals } from "../../src/enums"; 7 | 8 | export const main = async () => { 9 | try { 10 | const addresses = await getSuperBridgeAddresses(); 11 | for (const chain of Object.keys(addresses)) { 12 | console.log(`\nChecking addresses for chain ${chain}`); 13 | for (const token of Object.keys(addresses[chain])) { 14 | if (isSBAppChain(+chain, token)) continue; 15 | 16 | const tokenAddress = addresses[chain][token].NonMintableToken; 17 | const tokenContract = ERC20__factory.connect( 18 | tokenAddress, 19 | getProviderFromChainSlug(+chain) 20 | ); 21 | const vaultBalance = await tokenContract.balanceOf( 22 | addresses[chain][token].Vault 23 | ); 24 | 25 | console.log( 26 | `Vault for ${token} on chain ${chain} has balance: ${ethers.utils.formatUnits( 27 | vaultBalance, 28 | tokenDecimals[token] 29 | )}` 30 | ); 31 | } 32 | } 33 | } catch (error) { 34 | console.error("Error while checking vault balances", error); 35 | } 36 | }; 37 | 38 | main() 39 | .then(() => process.exit(0)) 40 | .catch((error: Error) => { 41 | console.error(error); 42 | process.exit(1); 43 | }); 44 | -------------------------------------------------------------------------------- /script/admin/updateConnectorStatus.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "ethers"; 2 | import { ChainSlug } from "@socket.tech/dl-core"; 3 | import { printExecSummary, getProjectAddresses } from "../helpers"; 4 | import { getTokenConstants } from "../helpers/projectConstants"; 5 | import { 6 | Connectors, 7 | ProjectType, 8 | TokenConstants, 9 | SBAddresses, 10 | STAddresses, 11 | SBTokenAddresses, 12 | STTokenAddresses, 13 | } from "../../src"; 14 | import { getProjectName, getProjectType, getTokens } from "../constants/config"; 15 | import { connectorStatus, filterChains, siblingFilterChains } from "./utils"; 16 | import { verifyConstants } from "../helpers/verifyConstants"; 17 | import { getBridgeContract, updateConnectorStatus } from "../helpers/common"; 18 | import { Tokens } from "../../src/enums"; 19 | 20 | export enum ConnectorStatus { 21 | ACTIVE = "active", 22 | INACTIVE = "inactive", 23 | } 24 | 25 | let projectType: ProjectType; 26 | let pc: { [token: string]: TokenConstants } = {}; 27 | let projectName: string; 28 | let tokens: Tokens[]; 29 | 30 | export const main = async () => { 31 | try { 32 | await verifyConstants(); 33 | projectType = getProjectType(); 34 | projectName = getProjectName(); 35 | tokens = getTokens(); 36 | 37 | if (!connectorStatus || !["active", "inactive"].includes(connectorStatus)) { 38 | throw Error( 39 | "Connector status not provided, use either active or inactive" 40 | ); 41 | } 42 | 43 | for (let token of tokens) { 44 | pc[token] = getTokenConstants(token); 45 | let addresses: SBAddresses | STAddresses; 46 | try { 47 | addresses = getProjectAddresses(); 48 | } catch (error) { 49 | addresses = {} as SBAddresses | STAddresses; 50 | } 51 | let allChains: ChainSlug[] = [ 52 | ...pc[token].controllerChains, 53 | ...pc[token].vaultChains, 54 | ]; 55 | 56 | if (filterChains) { 57 | allChains = allChains.filter((c) => filterChains!.includes(c)); 58 | } 59 | await Promise.all( 60 | allChains.map(async (chain) => { 61 | let addr: SBTokenAddresses | STTokenAddresses = (addresses[chain]?.[ 62 | token 63 | ] ?? {}) as SBTokenAddresses | STTokenAddresses; 64 | const connectors: Connectors | undefined = addr?.connectors; 65 | if (!addr || !connectors) return; 66 | 67 | let siblingSlugs: ChainSlug[] = Object.keys(connectors).map((k) => 68 | parseInt(k) 69 | ) as ChainSlug[]; 70 | if (siblingFilterChains) { 71 | siblingSlugs = siblingSlugs.filter((c) => 72 | siblingFilterChains!.includes(c) 73 | ); 74 | } 75 | let bridgeContract: Contract = await getBridgeContract( 76 | chain, 77 | token, 78 | addr 79 | ); 80 | await updateConnectorStatus( 81 | chain, 82 | siblingSlugs, 83 | connectors, 84 | bridgeContract, 85 | connectorStatus === ConnectorStatus.ACTIVE ? true : false 86 | ); 87 | }) 88 | ); 89 | } 90 | 91 | printExecSummary(); 92 | } catch (error) { 93 | console.error("Error while sending transaction", error); 94 | } 95 | }; 96 | 97 | main() 98 | .then(() => process.exit(0)) 99 | .catch((error: Error) => { 100 | console.error(error); 101 | process.exit(1); 102 | }); 103 | -------------------------------------------------------------------------------- /script/admin/updateLimits.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "ethers"; 2 | import { ChainSlug } from "@socket.tech/dl-core"; 3 | import { printExecSummary, getProjectAddresses } from "../helpers"; 4 | import { getTokenConstants } from "../helpers/projectConstants"; 5 | import { 6 | Connectors, 7 | TokenConstants, 8 | SBAddresses, 9 | STAddresses, 10 | SBTokenAddresses, 11 | STTokenAddresses, 12 | HookContracts, 13 | } from "../../src"; 14 | import { getTokens } from "../constants/config"; 15 | import { connectorStatus, filterChains, siblingFilterChains } from "./utils"; 16 | import { verifyConstants } from "../helpers/verifyConstants"; 17 | import { 18 | getBridgeContract, 19 | getHookContract, 20 | updateLimitsAndPoolId, 21 | } from "../helpers/common"; 22 | import { Tokens } from "../../src/enums"; 23 | 24 | let pc: { [token: string]: TokenConstants } = {}; 25 | let tokens: Tokens[]; 26 | 27 | export const main = async () => { 28 | try { 29 | await verifyConstants(); 30 | tokens = getTokens(); 31 | 32 | for (let token of tokens) { 33 | pc[token] = getTokenConstants(token); 34 | let addresses: SBAddresses | STAddresses; 35 | try { 36 | addresses = getProjectAddresses(); 37 | } catch (error) { 38 | addresses = {} as SBAddresses | STAddresses; 39 | } 40 | let allChains: ChainSlug[] = [ 41 | ...pc[token].controllerChains, 42 | ...pc[token].vaultChains, 43 | ]; 44 | 45 | if (filterChains) { 46 | allChains = allChains.filter((c) => filterChains!.includes(c)); 47 | } 48 | await Promise.all( 49 | allChains.map(async (chain) => { 50 | let addr: SBTokenAddresses | STTokenAddresses = (addresses[chain]?.[ 51 | token 52 | ] ?? {}) as SBTokenAddresses | STTokenAddresses; 53 | const connectors: Connectors | undefined = addr?.connectors; 54 | if (!addr || !connectors) return; 55 | 56 | let siblingSlugs: ChainSlug[] = Object.keys(connectors).map((k) => 57 | parseInt(k) 58 | ) as ChainSlug[]; 59 | if (siblingFilterChains) { 60 | siblingSlugs = siblingSlugs.filter((c) => 61 | siblingFilterChains!.includes(c) 62 | ); 63 | } 64 | let { hookContract, hookContractName } = await getHookContract( 65 | chain, 66 | token, 67 | addr 68 | ); 69 | 70 | if ( 71 | [ 72 | HookContracts.LimitHook, 73 | HookContracts.LimitExecutionHook, 74 | ].includes(hookContractName as HookContracts) 75 | ) { 76 | await updateLimitsAndPoolId( 77 | chain, 78 | token, 79 | siblingSlugs, 80 | addr, 81 | connectors, 82 | hookContract 83 | ); 84 | } 85 | }) 86 | ); 87 | } 88 | 89 | printExecSummary(); 90 | } catch (error) { 91 | console.error("Error while sending transaction", error); 92 | } 93 | }; 94 | 95 | main() 96 | .then(() => process.exit(0)) 97 | .catch((error: Error) => { 98 | console.error(error); 99 | process.exit(1); 100 | }); 101 | -------------------------------------------------------------------------------- /script/admin/utils.ts: -------------------------------------------------------------------------------- 1 | import { BigNumberish } from "ethers"; 2 | import { IntegrationTypes, ChainSlug, DeploymentMode } from "../../src"; 3 | import dotenv from "dotenv"; 4 | 5 | dotenv.config(); 6 | export const deploymentMode = process.env.DEPLOYMENT_MODE as DeploymentMode; 7 | 8 | export type SummaryObj = { 9 | chain: ChainSlug; 10 | siblingChain?: ChainSlug; 11 | nonce: number; 12 | currentTripStatus: boolean; 13 | newTripStatus: boolean; 14 | signature: string; 15 | hasRole: boolean; 16 | gasLimit?: BigNumberish; 17 | gasPrice?: BigNumberish; 18 | type?: number; 19 | }; 20 | 21 | /** 22 | * Usable flags 23 | 24 | * --chains Run only for specified chains. 25 | * Default is all chains. 26 | * Eg. npx --chains=10,2999 ts-node scripts/admin/.ts 27 | * 28 | * --connector_status specify whether to activate or deactivate the connectors. 29 | * Value required if updating connector status. 30 | * Values -> active,inactive 31 | * Eg. npx --connector_status=active ts-node scripts/admin/updateConnectorStatus.ts 32 | * 33 | * --sibling_chains Run only for specified sibling chains. 34 | * Default is all sibling chains. 35 | * Eg. npx --sibling_chains=10,2999 ts-node scripts/admin/.ts 36 | * 37 | */ 38 | 39 | export const integrationType = ( 40 | process.env.npm_config_integration 41 | ? process.env.npm_config_integration.toUpperCase() 42 | : IntegrationTypes.fast 43 | ) as IntegrationTypes; 44 | 45 | export const filterChains = process.env.npm_config_chains 46 | ? process.env.npm_config_chains.split(",").map((c) => Number(c)) 47 | : undefined; 48 | 49 | export const connectorStatus = process.env.npm_config_connector_status; 50 | 51 | export const siblingFilterChains = process.env.npm_config_sibling_chains 52 | ? process.env.npm_config_sibling_chains.split(",").map((c) => Number(c)) 53 | : undefined; 54 | -------------------------------------------------------------------------------- /script/bridge/utils.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber } from "ethers"; 2 | import { 3 | ChainSlug, 4 | DeploymentMode, 5 | SBTokenAddresses, 6 | STTokenAddresses, 7 | } from "../../src"; 8 | import { getHookContract } from "../helpers/common"; 9 | import { Tokens } from "../../src/enums"; 10 | import { getMode } from "../constants"; 11 | 12 | export const checkSendingLimit = async ( 13 | chain: ChainSlug, 14 | token: Tokens, 15 | addr: SBTokenAddresses | STTokenAddresses, 16 | connectorAddr: string, 17 | amountBN: BigNumber 18 | ) => { 19 | let { hookContract } = await getHookContract(chain, token, addr); 20 | if (!hookContract) { 21 | console.log("No hook contract found, skipping limit check"); 22 | return; 23 | } 24 | const limit: BigNumber = await hookContract.getCurrentSendingLimit( 25 | connectorAddr 26 | ); 27 | if (limit.lt(amountBN)) throw new Error("Exceeding max limit"); 28 | }; 29 | 30 | export const checkReceivingLimit = async ( 31 | chain: ChainSlug, 32 | token: Tokens, 33 | addr: SBTokenAddresses | STTokenAddresses, 34 | connectorAddr: string, 35 | amountBN: BigNumber 36 | ) => { 37 | let { hookContract } = await getHookContract(chain, token, addr); 38 | const limit: BigNumber = await hookContract.getCurrentReceivingLimit( 39 | connectorAddr 40 | ); 41 | if (limit.lt(amountBN)) throw new Error("Exceeding max limit"); 42 | }; 43 | 44 | export const getDLAPIBaseUrl = () => { 45 | const deploymentMode = getMode(); 46 | if (deploymentMode === DeploymentMode.PROD) 47 | return "https://prod.dlapi.socket.tech"; 48 | else if (deploymentMode === DeploymentMode.SURGE) { 49 | return "https://surge.dlapi.socket.tech"; 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /script/constants/abis/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./mintable"; 2 | export * from "./ownable"; 3 | -------------------------------------------------------------------------------- /script/constants/abis/mintable.ts: -------------------------------------------------------------------------------- 1 | export const MINTABLE_ABI = [ 2 | { 3 | inputs: [ 4 | { 5 | internalType: "address", 6 | name: "", 7 | type: "address", 8 | }, 9 | ], 10 | name: "minters", 11 | outputs: [ 12 | { 13 | internalType: "bool", 14 | name: "", 15 | type: "bool", 16 | }, 17 | ], 18 | stateMutability: "view", 19 | type: "function", 20 | }, 21 | { 22 | inputs: [ 23 | { 24 | internalType: "address", 25 | name: "", 26 | type: "address", 27 | }, 28 | ], 29 | name: "permitted", 30 | outputs: [ 31 | { 32 | internalType: "bool", 33 | name: "", 34 | type: "bool", 35 | }, 36 | ], 37 | stateMutability: "view", 38 | type: "function", 39 | }, 40 | { 41 | inputs: [ 42 | { 43 | internalType: "address", 44 | name: "", 45 | type: "address", 46 | }, 47 | ], 48 | name: "isMinter", 49 | outputs: [ 50 | { 51 | internalType: "bool", 52 | name: "", 53 | type: "bool", 54 | }, 55 | ], 56 | stateMutability: "view", 57 | type: "function", 58 | }, 59 | ]; 60 | -------------------------------------------------------------------------------- /script/constants/abis/ownable.ts: -------------------------------------------------------------------------------- 1 | export const OWNABLE_ABI = [ 2 | { 3 | inputs: [], 4 | name: "owner", 5 | outputs: [{ internalType: "address", name: "", type: "address" }], 6 | stateMutability: "view", 7 | type: "function", 8 | }, 9 | { 10 | inputs: [], 11 | name: "nominee", 12 | outputs: [{ internalType: "address", name: "", type: "address" }], 13 | stateMutability: "view", 14 | type: "function", 15 | }, 16 | { 17 | inputs: [], 18 | name: "pendingOwner", 19 | outputs: [{ internalType: "address", name: "", type: "address" }], 20 | stateMutability: "view", 21 | type: "function", 22 | }, 23 | { 24 | inputs: [ 25 | { 26 | internalType: "address", 27 | name: "newOwner", 28 | type: "address", 29 | }, 30 | ], 31 | name: "transferOwnership", 32 | outputs: [], 33 | stateMutability: "nonpayable", 34 | type: "function", 35 | }, 36 | { 37 | inputs: [ 38 | { 39 | internalType: "address", 40 | name: "nominee_", 41 | type: "address", 42 | }, 43 | ], 44 | name: "nominateOwner", 45 | outputs: [], 46 | stateMutability: "nonpayable", 47 | type: "function", 48 | }, 49 | ]; 50 | -------------------------------------------------------------------------------- /script/constants/deploymentConfig.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentAddresses, 4 | DeploymentMode, 5 | getAllAddresses, 6 | MainnetIds, 7 | S3ChainConfig, 8 | S3Config, 9 | TestnetIds, 10 | } from "@socket.tech/dl-core"; 11 | import { getMode } from "./config"; 12 | import { chainSlugReverseMap } from "../setup/enumMaps"; 13 | import { ExtendedS3ChainConfig } from "../../src"; 14 | 15 | export const DEPLOYMENT_CONFIG_URL = 16 | "https://surge-deploy.socket.tech/v1/getS3Config"; 17 | export let testnetIds: ChainSlug[] = []; 18 | export let mainnetIds: ChainSlug[] = []; 19 | export let addresses: DeploymentAddresses = {}; 20 | export let chains: { 21 | [chainSlug in ChainSlug]?: ExtendedS3ChainConfig; 22 | } = {}; 23 | 24 | export const fetchDeploymentConfig = async (): Promise => { 25 | console.log("fetching deployment config..."); 26 | const response = await fetch(DEPLOYMENT_CONFIG_URL); 27 | if (!response.ok) { 28 | throw new Error("Failed to fetch deployment config"); 29 | } 30 | let result = await response.json(); 31 | return result?.data; 32 | }; 33 | 34 | export const initDeploymentConfig = async () => { 35 | if (getMode() === DeploymentMode.SURGE) { 36 | const config = await fetchDeploymentConfig(); 37 | testnetIds = config.testnetIds; 38 | mainnetIds = config.mainnetIds; 39 | addresses = config.addresses; 40 | chains = config.chains; 41 | } 42 | }; 43 | 44 | export const getTestnetIds = () => { 45 | return getMode() == DeploymentMode.PROD ? TestnetIds : testnetIds; 46 | }; 47 | export const getMainnetIds = () => { 48 | return getMode() == DeploymentMode.PROD ? MainnetIds : mainnetIds; 49 | }; 50 | export const getAddresses = (chainSlug: number, mode: DeploymentMode) => { 51 | return mode == DeploymentMode.PROD 52 | ? getAllAddresses(DeploymentMode.PROD)[chainSlug] 53 | : addresses[chainSlug]; 54 | }; 55 | 56 | export const getChainName = (chainSlug: number) => { 57 | let chainName = 58 | chainSlugReverseMap.get(String(chainSlug)) ?? chains[chainSlug].chainName; 59 | return chainName.toUpperCase().replace(/[\s-]/g, "_"); // convert to uppercase, replace space and - with _ 60 | }; 61 | -------------------------------------------------------------------------------- /script/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./roles"; 2 | export * from "./config"; 3 | export * from "./deploymentConfig"; 4 | export * from "./abis"; 5 | -------------------------------------------------------------------------------- /script/constants/projectConstants/superbridge/aevo-testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Tokens } from "../../../../src/enums"; 7 | import { Hooks, ProjectConstants } from "../../../../src"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.USDC]: { 12 | controllerChains: [ChainSlug.AEVO_TESTNET], 13 | vaultChains: [ChainSlug.ARBITRUM_SEPOLIA, ChainSlug.OPTIMISM_SEPOLIA], 14 | hook: { 15 | hookType: Hooks.LIMIT_HOOK, 16 | limitsAndPoolId: { 17 | [ChainSlug.ARBITRUM_SEPOLIA]: { 18 | [IntegrationTypes.fast]: { 19 | sendingLimit: "50000", 20 | receivingLimit: "50000", 21 | }, 22 | }, 23 | [ChainSlug.OPTIMISM_SEPOLIA]: { 24 | [IntegrationTypes.fast]: { 25 | sendingLimit: "50000", 26 | receivingLimit: "50000", 27 | }, 28 | }, 29 | [ChainSlug.AEVO]: { 30 | [IntegrationTypes.fast]: { 31 | sendingLimit: "50000", 32 | receivingLimit: "50000", 33 | }, 34 | }, 35 | }, 36 | }, 37 | }, 38 | [Tokens.WETH]: { 39 | controllerChains: [ChainSlug.AEVO_TESTNET], 40 | vaultChains: [ChainSlug.ARBITRUM_SEPOLIA, ChainSlug.OPTIMISM_SEPOLIA], 41 | hook: { 42 | hookType: Hooks.LIMIT_HOOK, 43 | limitsAndPoolId: { 44 | [ChainSlug.ARBITRUM_SEPOLIA]: { 45 | [IntegrationTypes.fast]: { 46 | sendingLimit: "100", 47 | receivingLimit: "100", 48 | }, 49 | }, 50 | [ChainSlug.OPTIMISM_SEPOLIA]: { 51 | [IntegrationTypes.fast]: { 52 | sendingLimit: "100", 53 | receivingLimit: "100", 54 | }, 55 | }, 56 | [ChainSlug.AEVO]: { 57 | [IntegrationTypes.fast]: { 58 | sendingLimit: "100", 59 | receivingLimit: "100", 60 | }, 61 | }, 62 | }, 63 | }, 64 | }, 65 | }, 66 | }; 67 | -------------------------------------------------------------------------------- /script/constants/projectConstants/superbridge/aevo.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.USDCE]: { 12 | controllerChains: [ChainSlug.AEVO], 13 | vaultChains: [ChainSlug.ARBITRUM, ChainSlug.OPTIMISM], 14 | hook: { 15 | hookType: Hooks.LIMIT_HOOK, 16 | limitsAndPoolId: { 17 | [ChainSlug.ARBITRUM]: { 18 | [IntegrationTypes.fast]: { 19 | sendingLimit: "7000000", 20 | receivingLimit: "7000000", 21 | poolCount: 1, 22 | }, 23 | }, 24 | [ChainSlug.OPTIMISM]: { 25 | [IntegrationTypes.fast]: { 26 | sendingLimit: "7000000", 27 | receivingLimit: "7000000", 28 | poolCount: 1, 29 | }, 30 | }, 31 | [ChainSlug.AEVO]: { 32 | [IntegrationTypes.fast]: { 33 | sendingLimit: "7000000", 34 | receivingLimit: "7000000", 35 | poolCount: 1, 36 | }, 37 | }, 38 | }, 39 | }, 40 | }, 41 | [Tokens.USDC]: { 42 | controllerChains: [ChainSlug.AEVO], 43 | vaultChains: [ChainSlug.ARBITRUM, ChainSlug.OPTIMISM], 44 | hook: { 45 | hookType: Hooks.LIMIT_HOOK, 46 | limitsAndPoolId: { 47 | [ChainSlug.ARBITRUM]: { 48 | [IntegrationTypes.fast]: { 49 | sendingLimit: "7000000", 50 | receivingLimit: "7000000", 51 | }, 52 | }, 53 | [ChainSlug.OPTIMISM]: { 54 | [IntegrationTypes.fast]: { 55 | sendingLimit: "7000000", 56 | receivingLimit: "7000000", 57 | }, 58 | }, 59 | [ChainSlug.AEVO]: { 60 | [IntegrationTypes.fast]: { 61 | sendingLimit: "7000000", 62 | receivingLimit: "7000000", 63 | }, 64 | }, 65 | }, 66 | }, 67 | }, 68 | [Tokens.WETH]: { 69 | controllerChains: [ChainSlug.AEVO], 70 | vaultChains: [ChainSlug.ARBITRUM, ChainSlug.OPTIMISM], 71 | hook: { 72 | hookType: Hooks.LIMIT_HOOK, 73 | limitsAndPoolId: { 74 | [ChainSlug.ARBITRUM]: { 75 | [IntegrationTypes.fast]: { 76 | sendingLimit: "1250", 77 | receivingLimit: "1250", 78 | }, 79 | }, 80 | [ChainSlug.OPTIMISM]: { 81 | [IntegrationTypes.fast]: { 82 | sendingLimit: "1250", 83 | receivingLimit: "1250", 84 | }, 85 | }, 86 | [ChainSlug.AEVO]: { 87 | [IntegrationTypes.fast]: { 88 | sendingLimit: "1250", 89 | receivingLimit: "1250", 90 | }, 91 | }, 92 | }, 93 | }, 94 | }, 95 | }, 96 | }; 97 | -------------------------------------------------------------------------------- /script/constants/projectConstants/superbridge/b3_mainnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | // 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. 10 | export const pc: ProjectConstants = { 11 | [DeploymentMode.PROD]: { 12 | [Tokens.B3]: { 13 | vaultChains: [ChainSlug.BASE], 14 | controllerChains: [ChainSlug.B3], 15 | isFiatTokenV2_1: true, 16 | hook: { 17 | hookType: Hooks.LIMIT_HOOK, 18 | limitsAndPoolId: { 19 | [ChainSlug.B3]: { 20 | [IntegrationTypes.fast]: { 21 | sendingLimit: "1000000000", 22 | receivingLimit: "1000000000", 23 | }, 24 | }, 25 | [ChainSlug.BASE]: { 26 | [IntegrationTypes.fast]: { 27 | sendingLimit: "1000000000", 28 | receivingLimit: "1000000000", 29 | }, 30 | }, 31 | }, 32 | }, 33 | }, 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /script/constants/projectConstants/superbridge/polter_testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | // 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. 10 | export const pc: ProjectConstants = { 11 | [DeploymentMode.SURGE]: { 12 | [Tokens.USDC]: { 13 | vaultChains: [ChainSlug.ARBITRUM_SEPOLIA], 14 | controllerChains: [398274], 15 | tokenAddresses: { 16 | 398274: "0x15Bb97f748B341D1f464A7257d75da879D83fC9F", 17 | }, 18 | hook: { 19 | hookType: Hooks.LIMIT_HOOK, 20 | limitsAndPoolId: { 21 | 398274: { 22 | [IntegrationTypes.fast]: { 23 | sendingLimit: "100000", 24 | receivingLimit: "100000", 25 | }, 26 | }, 27 | [ChainSlug.ARBITRUM_SEPOLIA]: { 28 | [IntegrationTypes.fast]: { 29 | sendingLimit: "100000", 30 | receivingLimit: "100000", 31 | }, 32 | }, 33 | }, 34 | }, 35 | }, 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /script/constants/projectConstants/superbridge/rain-testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.USDC]: { 12 | vaultChains: [ChainSlug.OPTIMISM_SEPOLIA], 13 | controllerChains: [ChainSlug.ARBITRUM_SEPOLIA], 14 | hook: { 15 | hookType: Hooks.LIMIT_EXECUTION_HOOK, 16 | limitsAndPoolId: { 17 | [ChainSlug.ARBITRUM_SEPOLIA]: { 18 | [IntegrationTypes.fast]: { 19 | sendingLimit: "50000", 20 | receivingLimit: "50000", 21 | }, 22 | }, 23 | [ChainSlug.OPTIMISM_SEPOLIA]: { 24 | [IntegrationTypes.fast]: { 25 | sendingLimit: "100", 26 | receivingLimit: "100", 27 | poolCount: 1, 28 | }, 29 | }, 30 | }, 31 | }, 32 | }, 33 | [Tokens.WETH]: { 34 | vaultChains: [ChainSlug.OPTIMISM_SEPOLIA], 35 | controllerChains: [ChainSlug.ARBITRUM_SEPOLIA], 36 | hook: { 37 | hookType: Hooks.LIMIT_EXECUTION_HOOK, 38 | limitsAndPoolId: { 39 | [ChainSlug.ARBITRUM_SEPOLIA]: { 40 | [IntegrationTypes.fast]: { 41 | sendingLimit: "500", 42 | receivingLimit: "500", 43 | }, 44 | }, 45 | [ChainSlug.OPTIMISM_SEPOLIA]: { 46 | [IntegrationTypes.fast]: { 47 | sendingLimit: "500", 48 | receivingLimit: "500", 49 | poolCount: 1, 50 | }, 51 | }, 52 | }, 53 | }, 54 | }, 55 | [Tokens.WSTETH]: { 56 | vaultChains: [ChainSlug.OPTIMISM_SEPOLIA], 57 | controllerChains: [ChainSlug.ARBITRUM_SEPOLIA], 58 | hook: { 59 | hookType: Hooks.LIMIT_EXECUTION_HOOK, 60 | limitsAndPoolId: { 61 | [ChainSlug.ARBITRUM_SEPOLIA]: { 62 | [IntegrationTypes.fast]: { 63 | sendingLimit: "500", 64 | receivingLimit: "500", 65 | }, 66 | }, 67 | [ChainSlug.OPTIMISM_SEPOLIA]: { 68 | [IntegrationTypes.fast]: { 69 | sendingLimit: "500", 70 | receivingLimit: "500", 71 | poolCount: 1, 72 | }, 73 | }, 74 | }, 75 | }, 76 | }, 77 | }, 78 | }; 79 | -------------------------------------------------------------------------------- /script/constants/projectConstants/superbridge/sx-testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.USDC]: { 12 | controllerChains: [ChainSlug.SX_NETWORK_TESTNET], 13 | vaultChains: [ChainSlug.SEPOLIA], 14 | hook: { 15 | hookType: Hooks.LIMIT_HOOK, 16 | limitsAndPoolId: { 17 | [ChainSlug.SEPOLIA]: { 18 | [IntegrationTypes.fast]: { 19 | sendingLimit: "10000", 20 | receivingLimit: "10000", 21 | }, 22 | }, 23 | [ChainSlug.SX_NETWORK_TESTNET]: { 24 | [IntegrationTypes.fast]: { 25 | sendingLimit: "10000", 26 | receivingLimit: "10000", 27 | }, 28 | }, 29 | }, 30 | }, 31 | }, 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /script/constants/projectConstants/superbridge/syndr_sepolia_testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.USDC]: { 12 | vaultChains: [ChainSlug.ARBITRUM_SEPOLIA], 13 | controllerChains: [ChainSlug.SYNDR_SEPOLIA_L3], 14 | hook: { 15 | hookType: Hooks.LIMIT_HOOK, 16 | limitsAndPoolId: { 17 | [ChainSlug.ARBITRUM_SEPOLIA]: { 18 | [IntegrationTypes.fast]: { 19 | sendingLimit: "10000000", 20 | receivingLimit: "1000000", 21 | }, 22 | }, 23 | [ChainSlug.SYNDR_SEPOLIA_L3]: { 24 | [IntegrationTypes.fast]: { 25 | sendingLimit: "10000000", 26 | receivingLimit: "1000000", 27 | }, 28 | }, 29 | }, 30 | }, 31 | }, 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /script/constants/projectConstants/supertoken/leaf-testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.USDC]: { 12 | vaultChains: [ChainSlug.OPTIMISM_SEPOLIA], 13 | controllerChains: [ChainSlug.ARBITRUM_SEPOLIA, ChainSlug.AEVO_TESTNET], 14 | superTokenInfo: { 15 | name: "Leaf", 16 | symbol: "LEAF", 17 | decimals: 6, 18 | initialSupplyOwner: "0xab2f8c1588aca57bc2909512b645a860c65770d3", 19 | owner: "0xab2f8c1588aca57bc2909512b645a860c65770d3", 20 | initialSupply: "1000000000", 21 | }, 22 | hook: { 23 | hookType: Hooks.LIMIT_HOOK, 24 | limitsAndPoolId: { 25 | [ChainSlug.ARBITRUM_SEPOLIA]: { 26 | [IntegrationTypes.fast]: { 27 | sendingLimit: "50000", 28 | receivingLimit: "50000", 29 | }, 30 | }, 31 | [ChainSlug.AEVO_TESTNET]: { 32 | [IntegrationTypes.fast]: { 33 | sendingLimit: "50000", 34 | receivingLimit: "50000", 35 | poolCount: 1, 36 | }, 37 | }, 38 | [ChainSlug.OPTIMISM_SEPOLIA]: { 39 | [IntegrationTypes.fast]: { 40 | sendingLimit: "50000", 41 | receivingLimit: "50000", 42 | poolCount: 1, 43 | }, 44 | }, 45 | }, 46 | }, 47 | }, 48 | [Tokens.USDCE]: { 49 | vaultChains: [ChainSlug.OPTIMISM_SEPOLIA], 50 | controllerChains: [ChainSlug.ARBITRUM_SEPOLIA, ChainSlug.AEVO_TESTNET], 51 | superTokenInfo: { 52 | name: "Leaf", 53 | symbol: "LEAF", 54 | decimals: 6, 55 | initialSupplyOwner: "0xab2f8c1588aca57bc2909512b645a860c65770d3", 56 | owner: "0xab2f8c1588aca57bc2909512b645a860c65770d3", 57 | initialSupply: "1000000000", 58 | }, 59 | hook: { 60 | hookType: Hooks.LIMIT_HOOK, 61 | limitsAndPoolId: { 62 | [ChainSlug.ARBITRUM_SEPOLIA]: { 63 | [IntegrationTypes.fast]: { 64 | sendingLimit: "50000", 65 | receivingLimit: "50000", 66 | }, 67 | }, 68 | [ChainSlug.AEVO_TESTNET]: { 69 | [IntegrationTypes.fast]: { 70 | sendingLimit: "50000", 71 | receivingLimit: "50000", 72 | poolCount: 1, 73 | }, 74 | }, 75 | [ChainSlug.OPTIMISM_SEPOLIA]: { 76 | [IntegrationTypes.fast]: { 77 | sendingLimit: "50000", 78 | receivingLimit: "50000", 79 | poolCount: 1, 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }, 86 | }; 87 | -------------------------------------------------------------------------------- /script/constants/projectConstants/supertoken/magic_mainnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.MAGIC]: { 12 | vaultChains: [ChainSlug.ARBITRUM], 13 | controllerChains: [ChainSlug.OPTIMISM], 14 | hook: { 15 | hookType: Hooks.NO_HOOK, 16 | }, 17 | superTokenInfo: { 18 | name: "magic", 19 | symbol: Tokens.MAGIC, 20 | decimals: 18, 21 | owner: "0xdE7f7a699F8504641eceF544B0fbc0740C37E69B", 22 | initialSupplyOwner: "0xdE7f7a699F8504641eceF544B0fbc0740C37E69B", 23 | initialSupply: "0", 24 | }, 25 | }, 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /script/constants/projectConstants/supertoken/mist-testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { getOwner } from "../../config"; 8 | import { Tokens } from "../../../../src/enums"; 9 | 10 | export const pc: ProjectConstants = { 11 | [DeploymentMode.PROD]: { 12 | [Tokens.USDC]: { 13 | vaultChains: [ChainSlug.OPTIMISM_SEPOLIA], 14 | controllerChains: [ChainSlug.ARBITRUM_SEPOLIA, ChainSlug.AEVO_TESTNET], 15 | superTokenInfo: { 16 | name: "Mist", 17 | symbol: "MIST", 18 | decimals: 6, 19 | initialSupplyOwner: getOwner(), 20 | owner: getOwner(), 21 | initialSupply: "1000000000", 22 | }, 23 | hook: { 24 | hookType: Hooks.LIMIT_HOOK, 25 | limitsAndPoolId: { 26 | [ChainSlug.ARBITRUM_SEPOLIA]: { 27 | [IntegrationTypes.fast]: { 28 | sendingLimit: "50000", 29 | receivingLimit: "50000", 30 | }, 31 | }, 32 | [ChainSlug.AEVO_TESTNET]: { 33 | [IntegrationTypes.fast]: { 34 | sendingLimit: "50000", 35 | receivingLimit: "50000", 36 | }, 37 | }, 38 | [ChainSlug.OPTIMISM_SEPOLIA]: { 39 | [IntegrationTypes.fast]: { 40 | sendingLimit: "50000", 41 | receivingLimit: "50000", 42 | poolCount: 1, 43 | }, 44 | }, 45 | }, 46 | }, 47 | }, 48 | }, 49 | }; 50 | -------------------------------------------------------------------------------- /script/constants/projectConstants/supertoken/spectral-signal.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | import { getOwner } from "../../config"; 9 | 10 | export const pc: ProjectConstants = { 11 | [DeploymentMode.PROD]: { 12 | [Tokens.GUARD]: { 13 | vaultChains: [ChainSlug.BSC], 14 | controllerChains: [ChainSlug.ARBITRUM, ChainSlug.POLYGON_MAINNET], 15 | superTokenInfo: { 16 | name: "Guardian", 17 | symbol: "GUARD", 18 | decimals: 18, 19 | initialSupplyOwner: getOwner(), 20 | owner: getOwner(), 21 | initialSupply: "0", 22 | }, 23 | hook: { 24 | hookType: Hooks.LIMIT_HOOK, 25 | limitsAndPoolId: { 26 | [ChainSlug.BSC]: { 27 | [IntegrationTypes.fast]: { 28 | sendingLimit: "50000", 29 | receivingLimit: "50000", 30 | }, 31 | }, 32 | [ChainSlug.ARBITRUM]: { 33 | [IntegrationTypes.fast]: { 34 | sendingLimit: "50000", 35 | receivingLimit: "50000", 36 | }, 37 | }, 38 | [ChainSlug.POLYGON_MAINNET]: { 39 | [IntegrationTypes.fast]: { 40 | sendingLimit: "50000", 41 | receivingLimit: "50000", 42 | }, 43 | }, 44 | }, 45 | }, 46 | }, 47 | }, 48 | }; 49 | -------------------------------------------------------------------------------- /script/constants/projectConstants/supertoken/testing_mainnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.MTK]: { 12 | vaultChains: [ChainSlug.ARBITRUM], 13 | controllerChains: [ChainSlug.OPTIMISM], 14 | superTokenInfo: { 15 | name: "SuperMockToken", 16 | symbol: "SMTK", 17 | decimals: 18, 18 | initialSupplyOwner: "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 19 | owner: "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 20 | initialSupply: "0", 21 | }, 22 | hook: { 23 | hookType: Hooks.LIMIT_HOOK, 24 | limitsAndPoolId: { 25 | [ChainSlug.OPTIMISM]: { 26 | [IntegrationTypes.fast]: { 27 | sendingLimit: "100", 28 | receivingLimit: "100", 29 | }, 30 | }, 31 | [ChainSlug.ARBITRUM]: { 32 | [IntegrationTypes.fast]: { 33 | sendingLimit: "100", 34 | receivingLimit: "100", 35 | }, 36 | }, 37 | }, 38 | }, 39 | }, 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /script/constants/projectConstants/supertoken/testing_testnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.MTK]: { 12 | vaultChains: [ChainSlug.ARBITRUM_SEPOLIA], 13 | controllerChains: [ChainSlug.OPTIMISM_SEPOLIA], 14 | hook: { 15 | hookType: Hooks.LIMIT_HOOK, 16 | limitsAndPoolId: { 17 | [ChainSlug.ARBITRUM_SEPOLIA]: { 18 | [IntegrationTypes.fast]: { 19 | sendingLimit: "1000", 20 | receivingLimit: "1000", 21 | }, 22 | }, 23 | [ChainSlug.OPTIMISM_SEPOLIA]: { 24 | [IntegrationTypes.fast]: { 25 | sendingLimit: "1000", 26 | receivingLimit: "1000", 27 | }, 28 | }, 29 | }, 30 | }, 31 | superTokenInfo: { 32 | name: "SuperMockToken", 33 | symbol: "SMTK", 34 | decimals: 18, 35 | initialSupplyOwner: "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 36 | owner: "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 37 | initialSupply: "0", 38 | }, 39 | }, 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /script/constants/projectConstants/supertoken/timeswap_test_mainnet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainSlug, 3 | DeploymentMode, 4 | IntegrationTypes, 5 | } from "@socket.tech/dl-core"; 6 | import { Hooks, ProjectConstants } from "../../../../src"; 7 | import { Tokens } from "../../../../src/enums"; 8 | 9 | export const pc: ProjectConstants = { 10 | [DeploymentMode.PROD]: { 11 | [Tokens.STIME]: { 12 | vaultChains: [ChainSlug.ARBITRUM], 13 | controllerChains: [ChainSlug.OPTIMISM], 14 | hook: { 15 | hookType: Hooks.LIMIT_HOOK, 16 | limitsAndPoolId: { 17 | [ChainSlug.OPTIMISM]: { 18 | [IntegrationTypes.fast]: { 19 | sendingLimit: "1000000.0", 20 | receivingLimit: "1000000.0", 21 | }, 22 | }, 23 | [ChainSlug.ARBITRUM]: { 24 | [IntegrationTypes.fast]: { 25 | sendingLimit: "1000000.0", 26 | receivingLimit: "1000000.0", 27 | }, 28 | }, 29 | }, 30 | }, 31 | superTokenInfo: { 32 | name: "Timeswap Test", 33 | symbol: "TSWP", 34 | decimals: 18, 35 | initialSupply: "0", 36 | initialSupplyOwner: "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 37 | owner: "0x572E38236eA3632b779962e27b47B3Dd75Fee127", 38 | }, 39 | }, 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /script/constants/roles.ts: -------------------------------------------------------------------------------- 1 | import { id } from "ethers/lib/utils"; 2 | 3 | export const LIMIT_UPDATER_ROLE = id("LIMIT_UPDATER_ROLE"); 4 | export const RESCUE_ROLE = id("RESCUE_ROLE"); 5 | export const CONTROLLER_ROLE = id("CONTROLLER_ROLE"); 6 | -------------------------------------------------------------------------------- /script/deploy.ts: -------------------------------------------------------------------------------- 1 | import { initDeploymentConfig } from "./constants"; 2 | import { configure } from "./deploy/configure"; 3 | import { deploy } from "./deploy/deploy"; 4 | 5 | import { EventEmitter } from "events"; 6 | EventEmitter.defaultMaxListeners = 20; 7 | 8 | export const main = async () => { 9 | try { 10 | await initDeploymentConfig(); 11 | let allAddresses = await deploy(); 12 | await configure(allAddresses); 13 | } catch (error) { 14 | console.log("Error in deploy and configure: ", error); 15 | } 16 | }; 17 | 18 | main() 19 | .then(() => process.exit(0)) 20 | .catch((error: Error) => { 21 | console.error(error); 22 | process.exit(1); 23 | }); 24 | -------------------------------------------------------------------------------- /script/deploy/configureHook.ts: -------------------------------------------------------------------------------- 1 | import { Contract, Wallet } from "ethers"; 2 | 3 | import { ChainSlug } from "@socket.tech/dl-core"; 4 | import { getInstance, execute } from "../helpers"; 5 | import { 6 | Connectors, 7 | HookContracts, 8 | SBTokenAddresses, 9 | STTokenAddresses, 10 | } from "../../src"; 11 | import { getHookContract, updateLimitsAndPoolId } from "../helpers/common"; 12 | import { Tokens } from "../../src/enums"; 13 | import { getDryRun } from "../constants/config"; 14 | import { constants } from "ethers"; 15 | const { AddressZero } = constants; 16 | 17 | export const configureHooks = async ( 18 | chain: ChainSlug, 19 | token: Tokens, 20 | bridgeContract: Contract, 21 | socketSigner: Wallet, 22 | siblingSlugs: ChainSlug[], 23 | connectors: Connectors, 24 | addr: SBTokenAddresses | STTokenAddresses 25 | ) => { 26 | let { hookContract, hookContractName } = await getHookContract( 27 | chain, 28 | token, 29 | addr 30 | ); 31 | if (!hookContract || !hookContractName) { 32 | return; // No hook to configure 33 | } 34 | 35 | if (hookContractName === HookContracts.LimitExecutionHook) { 36 | await setHookInExecutionHelper(chain, socketSigner, hookContract, addr); 37 | } 38 | await setHookInBridge(chain, bridgeContract, hookContract); 39 | 40 | if ( 41 | [HookContracts.LimitHook, HookContracts.LimitExecutionHook].includes( 42 | hookContractName as HookContracts 43 | ) 44 | ) { 45 | await updateLimitsAndPoolId( 46 | chain, 47 | token, 48 | siblingSlugs, 49 | addr, 50 | connectors, 51 | hookContract 52 | ); 53 | } 54 | }; 55 | 56 | // export const setLimitUpdaterRole = async ( 57 | // chain: ChainSlug, 58 | // hookContract: Contract 59 | // ) => { 60 | // await checkAndGrantRole( 61 | // chain, 62 | // hookContract, 63 | // "limit updater", 64 | // LIMIT_UPDATER_ROLE, 65 | // getOwner() 66 | // ); 67 | // }; 68 | 69 | export const setHookInBridge = async ( 70 | chain: ChainSlug, 71 | bridgeContract: Contract, 72 | hookContract: Contract 73 | ) => { 74 | let storedHookAddress = getDryRun() 75 | ? AddressZero 76 | : await bridgeContract.hook__(); 77 | if (storedHookAddress === hookContract.address) { 78 | console.log(`✔ Hook already set on Bridge for chain ${chain}`); 79 | return; 80 | } 81 | await execute( 82 | bridgeContract, 83 | "updateHook", 84 | [hookContract.address, false], 85 | chain 86 | ); 87 | }; 88 | 89 | export const setHookInExecutionHelper = async ( 90 | chain: ChainSlug, 91 | socketSigner: Wallet, 92 | hookContract: Contract, 93 | addr: SBTokenAddresses | STTokenAddresses 94 | ) => { 95 | let address = addr[HookContracts.ExecutionHelper]; 96 | if (!address) { 97 | throw new Error("Execution Helper address not found"); 98 | } 99 | let executionHelperContract = await getInstance( 100 | HookContracts.ExecutionHelper, 101 | address 102 | ); 103 | executionHelperContract = executionHelperContract.connect(socketSigner); 104 | 105 | let storedHookAddress = await executionHelperContract.hook(); 106 | if (storedHookAddress === hookContract.address) { 107 | console.log(`✔ Hook already set on Execution Helper for chain ${chain}`); 108 | return; 109 | } 110 | await execute( 111 | executionHelperContract, 112 | "setHook", 113 | [hookContract.address], 114 | chain 115 | ); 116 | }; 117 | -------------------------------------------------------------------------------- /script/deploy/verifyContracts.ts: -------------------------------------------------------------------------------- 1 | import hre from "hardhat"; 2 | import fs from "fs"; 3 | 4 | import { verify } from "../helpers/deployUtils"; 5 | import { 6 | ChainSlug, 7 | ChainSlugToKey as ChainSlugToHardhatKey, 8 | } from "@socket.tech/dl-core"; 9 | import { getVerificationPath } from "../helpers/utils"; 10 | import { CustomNetworksConfig } from "../../hardhat.config"; 11 | 12 | export type VerifyParams = { 13 | [chainSlug in ChainSlug]?: VerifyArgs[]; 14 | }; 15 | type VerifyArgs = [string, string, string, any[]]; 16 | 17 | /** 18 | * Deploys network-independent socket contracts 19 | */ 20 | export const main = async () => { 21 | try { 22 | const path = getVerificationPath(); 23 | if (!fs.existsSync(path)) { 24 | throw new Error("addresses.json not found"); 25 | } 26 | let verificationParams: VerifyParams = JSON.parse( 27 | fs.readFileSync(path, "utf-8") 28 | ); 29 | 30 | const chainSlugs: ChainSlug[] = Object.keys(verificationParams).map((c) => 31 | Number(c) 32 | ); 33 | 34 | console.log("Chains array:", chainSlugs); 35 | if (!chainSlugs) { 36 | console.log("No chainSlugs found, exiting."); 37 | return; 38 | } 39 | 40 | for (let chainIndex = 0; chainIndex < chainSlugs.length; chainIndex++) { 41 | console.log( 42 | `Verifying contracts for chainSlug ${chainSlugs[chainIndex]}...` 43 | ); 44 | 45 | const chainSlug = chainSlugs[chainIndex]; 46 | // hre.changeNetwork(ChainSlugToHardhatKey[chainSlug]); 47 | 48 | if ( 49 | hre.network.name !== ChainSlugToHardhatKey[chainSlug] && 50 | CustomNetworksConfig[hre.network.name]?.chainId !== chainSlug 51 | ) { 52 | console.log( 53 | `Skipping verification for chainSlug ${chainSlug} as the network param does not match.` 54 | ); 55 | continue; 56 | } 57 | const chainParams: VerifyArgs[] | undefined = 58 | verificationParams[chainSlug]; 59 | if (!chainParams) continue; 60 | if (chainParams.length) { 61 | const len = chainParams.length; 62 | for (let index = 0; index < len!; index++) 63 | await verify(...chainParams[index]); 64 | } 65 | } 66 | } catch (error) { 67 | console.log("Error in contract verification", error); 68 | } 69 | }; 70 | 71 | main() 72 | .then(() => process.exit(0)) 73 | .catch((error: Error) => { 74 | console.error(error); 75 | process.exit(1); 76 | }); 77 | -------------------------------------------------------------------------------- /script/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./deployUtils"; 2 | export * from "./utils"; 3 | export * from "./networks"; 4 | export * from "./projectConstants"; 5 | -------------------------------------------------------------------------------- /script/helpers/projectConstants.ts: -------------------------------------------------------------------------------- 1 | import { ChainSlug, IntegrationTypes } from "@socket.tech/dl-core"; 2 | import { BigNumber, utils } from "ethers"; 3 | import { ProjectConstants, TokenConstants } from "../../src"; 4 | import { getMode, getProjectName } from "../constants/config"; 5 | import { getConstantPath } from "./utils"; 6 | import { tokenDecimals } from "../../src/enums/tokenDecimals"; 7 | 8 | export const isSBAppChain = (chain: ChainSlug, token: string) => 9 | getTokenConstants(token).controllerChains.includes(chain); 10 | 11 | export const isSTVaultChain = (chain: ChainSlug, token: string) => 12 | getTokenConstants(token).vaultChains.includes(chain); 13 | 14 | let pc: ProjectConstants; 15 | 16 | export const getTokenConstants = (tokenName: string): TokenConstants => { 17 | let pc_ = getProjectConstants(); 18 | const tc = pc_?.[getMode()]?.[tokenName]; 19 | if (!tc) 20 | throw new Error( 21 | `config not found for ${getProjectName()}, ${getMode()}, ${tokenName}` 22 | ); 23 | return tc; 24 | }; 25 | 26 | export const getProjectConstants = (): ProjectConstants => { 27 | if (pc) return pc; 28 | pc = require(getConstantPath()).pc; 29 | return pc; 30 | }; 31 | 32 | export const getIntegrationTypeConsts = ( 33 | it: IntegrationTypes, 34 | chain: ChainSlug, 35 | tokenName: string 36 | ) => { 37 | const pci = getTokenConstants(tokenName).hook?.limitsAndPoolId?.[chain]?.[it]; 38 | if (!pci) throw new Error("invalid integration for mode and project"); 39 | return pci; 40 | }; 41 | 42 | export const getLimitBN = ( 43 | it: IntegrationTypes, 44 | chain: ChainSlug, 45 | token: string, 46 | isSending: boolean 47 | ): BigNumber => { 48 | if (isSending) { 49 | return utils.parseUnits( 50 | getIntegrationTypeConsts(it, chain, token).sendingLimit, 51 | tokenDecimals[token] 52 | ); 53 | } else { 54 | return utils.parseUnits( 55 | getIntegrationTypeConsts(it, chain, token).receivingLimit, 56 | tokenDecimals[token] 57 | ); 58 | } 59 | }; 60 | 61 | export const getRateBN = ( 62 | it: IntegrationTypes, 63 | chain: ChainSlug, 64 | token: string, 65 | isSending: boolean 66 | ): BigNumber => { 67 | let limitBN = getLimitBN(it, chain, token, isSending); 68 | return limitBN.div(86400); 69 | }; 70 | -------------------------------------------------------------------------------- /script/helpers/updateJsons.ts: -------------------------------------------------------------------------------- 1 | import { updateAllAddressesFile, updateDetailsFile } from "./deployUtils"; 2 | 3 | export const main = async () => { 4 | try { 5 | await updateAllAddressesFile(); 6 | 7 | await updateDetailsFile(); 8 | } catch (error) { 9 | console.log(error); 10 | } 11 | }; 12 | 13 | main(); 14 | -------------------------------------------------------------------------------- /script/helpers/verifyConstants.ts: -------------------------------------------------------------------------------- 1 | import { config as dotenvConfig } from "dotenv"; 2 | dotenvConfig(); 3 | 4 | import { ChainSlug } from "@socket.tech/dl-core"; 5 | import { isSuperBridge, isSuperToken, getConfigs } from "../constants/config"; 6 | import { checkMissingFields } from "../helpers"; 7 | import { Hooks, ProjectType, TokenConstants } from "../../src"; 8 | import { getTokenConstants } from "../helpers/projectConstants"; 9 | import { Tokens } from "../../src/enums"; 10 | 11 | let projectType: ProjectType; 12 | let pc: { [token: string]: TokenConstants } = {}; 13 | let projectName: string; 14 | let tokens: Tokens[]; 15 | 16 | export const verifyConstants = async () => { 17 | ({ projectName, projectType, tokens } = getConfigs()); 18 | 19 | for (let token of tokens) { 20 | console.log(`\nVerifying ${token}...`); 21 | pc[token] = getTokenConstants(token); 22 | let currentPc = pc[token]; 23 | let allChains = [...currentPc.controllerChains, ...currentPc.vaultChains]; 24 | if (isSuperBridge()) { 25 | if (currentPc.controllerChains.length != 1) { 26 | throw new Error("SuperBridge can only have one controllerChains"); 27 | } 28 | } 29 | if (isSuperToken()) { 30 | let { superTokenInfo } = currentPc; 31 | checkMissingFields({ superTokenInfo }); 32 | 33 | if ("address" in superTokenInfo) { 34 | // Handle the case where only the address is present 35 | checkMissingFields({ address: superTokenInfo.address }); 36 | console.log(`Using already deployed token ${superTokenInfo.address}`); 37 | } else { 38 | // Handle the case where detailed information is present 39 | let { 40 | name, 41 | symbol, 42 | decimals, 43 | initialSupplyOwner, 44 | owner, 45 | initialSupply, 46 | } = superTokenInfo; 47 | checkMissingFields({ 48 | name, 49 | symbol, 50 | decimals, 51 | initialSupplyOwner, 52 | owner, 53 | initialSupply, 54 | }); 55 | console.log( 56 | `Deploying new SuperToken with ${name} (${symbol}) with ${decimals} decimals` 57 | ); 58 | } 59 | } 60 | 61 | if (currentPc.hook) { 62 | let { hookType, limitsAndPoolId, yieldVaultInfo } = currentPc.hook; 63 | checkMissingFields({ hookType }); 64 | if ( 65 | hookType == Hooks.LIMIT_HOOK || 66 | hookType == Hooks.LIMIT_EXECUTION_HOOK 67 | ) { 68 | checkMissingFields({ limitsAndPoolId }); 69 | let chainsWithLimits = Object.keys(limitsAndPoolId!); 70 | for (let chain of allChains) { 71 | if (!chainsWithLimits.includes(chain.toString())) { 72 | throw new Error( 73 | `Limits not found for chain ${chain} in token ${token}` 74 | ); 75 | } 76 | } 77 | for (let chain in limitsAndPoolId) { 78 | let chainLimits = limitsAndPoolId[chain]; 79 | for (let integration in chainLimits) { 80 | let { sendingLimit, receivingLimit } = chainLimits[integration]; 81 | checkMissingFields({ sendingLimit, receivingLimit }); 82 | } 83 | } 84 | } 85 | if (hookType == Hooks.YIELD_LIMIT_EXECUTION_HOOK) { 86 | let { yieldTokenInfo } = currentPc; 87 | checkMissingFields({ yieldTokenInfo }); 88 | let { name, symbol, decimals } = yieldTokenInfo!; 89 | checkMissingFields({ 90 | name, 91 | symbol, 92 | decimals, 93 | }); 94 | 95 | checkMissingFields({ yieldVaultInfo }); 96 | let { debtRatio, rebalanceDelay, strategy, underlyingAsset } = 97 | yieldVaultInfo!; 98 | checkMissingFields({ 99 | debtRatio, 100 | rebalanceDelay, 101 | strategy, 102 | underlyingAsset, 103 | }); 104 | } 105 | } 106 | } 107 | }; 108 | -------------------------------------------------------------------------------- /script/ownership/claim-owner.ts: -------------------------------------------------------------------------------- 1 | import { config as dotenvConfig } from "dotenv"; 2 | import { Signer, Wallet, ethers } from "ethers"; 3 | import { 4 | ChainSlug, 5 | SBAddresses, 6 | SBTokenAddresses, 7 | STAddresses, 8 | STTokenAddresses, 9 | } from "../../src"; 10 | import { Ownable, Ownable__factory } from "../../typechain-types"; 11 | import { getProjectAddresses } from "../helpers"; 12 | import { getOverrides, getProviderFromChainSlug } from "../helpers/networks"; 13 | import { ContractList, getContractList } from "./util"; 14 | 15 | dotenvConfig(); 16 | 17 | /** 18 | * Usage 19 | * 20 | * --sendtx Send claim tx along with ownership check. 21 | * Default is only check owner, nominee. 22 | * Eg. npx --sendtx ts-node script/ownership/claim-owner.ts 23 | * 24 | * --chains Run only for specified chains. 25 | * Default is all chains. 26 | * Eg. npx --chains=10,2999 ts-node script/ownership/claim-owner.ts 27 | */ 28 | 29 | const signerKey = process.env.OWNER_SIGNER_KEY; 30 | if (!signerKey) { 31 | console.error("Error: OWNER_SIGNER_KEY is required"); 32 | } 33 | 34 | const sendTx = process.env.npm_config_sendtx == "true"; 35 | 36 | const filterChainsParam = process.env.npm_config_chains 37 | ? process.env.npm_config_chains.split(",") 38 | : null; 39 | const addresses: SBAddresses | STAddresses = getProjectAddresses(); 40 | const allChainSlugs = Object.keys(addresses); 41 | const filteredChainSlugs = !filterChainsParam 42 | ? allChainSlugs 43 | : allChainSlugs.filter((c) => filterChainsParam.includes(c)); 44 | 45 | const wallet: Wallet = new ethers.Wallet(signerKey); 46 | const signerAddress = wallet.address.toLowerCase(); 47 | 48 | const main = async () => { 49 | await Promise.all( 50 | filteredChainSlugs.map(async (chainSlug) => { 51 | const provider = getProviderFromChainSlug( 52 | parseInt(chainSlug) as ChainSlug 53 | ); 54 | const signer = wallet.connect(provider); 55 | 56 | const chainAddresses = addresses[chainSlug]; 57 | for (const token of Object.keys(chainAddresses)) { 58 | const tokenAddresses: SBTokenAddresses | STTokenAddresses = 59 | addresses[chainSlug][token]; 60 | let contractList: ContractList = getContractList( 61 | tokenAddresses, 62 | chainSlug, 63 | token 64 | ); 65 | 66 | for (const contract of contractList) { 67 | await checkAndClaim( 68 | contract.address, 69 | signer, 70 | chainSlug, 71 | contract.label 72 | ); 73 | } 74 | } 75 | }) 76 | ); 77 | }; 78 | 79 | const checkAndClaim = async ( 80 | contractAddress: string, 81 | signer: Signer, 82 | chainSlug: string, 83 | label: string 84 | ) => { 85 | label = label.padEnd(45); 86 | const contract = new ethers.Contract( 87 | contractAddress, 88 | Ownable__factory.abi, 89 | signer 90 | ) as Ownable; 91 | 92 | try { 93 | const owner = (await contract.owner()).toLowerCase(); 94 | const nominee = (await contract.nominee()).toLowerCase(); 95 | 96 | console.log(` - ${label}: Checking: ${owner}, ${nominee}`); 97 | 98 | if (signerAddress === owner) { 99 | console.log(` ✔ ${label}: Already claimed`); 100 | return; 101 | } 102 | 103 | if (signerAddress !== nominee) { 104 | console.log(`❗ ${label}: Signer is not current nominee`); 105 | return; 106 | } 107 | 108 | if (sendTx) { 109 | console.log(`✨ ${label}: Claiming`); 110 | const tx = await contract.claimOwner({ 111 | ...getOverrides(parseInt(chainSlug)), 112 | }); 113 | const receipt = await tx.wait(); 114 | console.log(`🚀 ${label}: Done: ${receipt.transactionHash}`); 115 | } else { 116 | console.log(`✨ ${label}: Needs claiming`); 117 | } 118 | } catch (e) { 119 | console.error(`❗ ${label}: Error while checking ${contractAddress}`); 120 | } 121 | }; 122 | 123 | main() 124 | .then(() => process.exit(0)) 125 | .catch((error: Error) => { 126 | console.error(error); 127 | process.exit(1); 128 | }); 129 | -------------------------------------------------------------------------------- /script/ownership/util.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AppChainAddresses, 3 | NonAppChainAddresses, 4 | SBTokenAddresses, 5 | STControllerChainAddresses, 6 | STTokenAddresses, 7 | STVaultChainAddresses, 8 | } from "../../src"; 9 | 10 | export type ContractList = { label: string; address: string }[]; 11 | 12 | export const getContractList = ( 13 | tokenAddresses: SBTokenAddresses | STTokenAddresses, 14 | chainSlug: string, 15 | token: string 16 | ): ContractList => { 17 | const contractList: ContractList = []; 18 | 19 | if ((tokenAddresses as AppChainAddresses).isAppChain) { 20 | contractList.push({ 21 | address: (tokenAddresses as AppChainAddresses).Controller, 22 | label: `${chainSlug}, ${token}, Controller`, 23 | }); 24 | contractList.push({ 25 | address: (tokenAddresses as AppChainAddresses).MintableToken, 26 | label: `${chainSlug}, ${token}, MintableToken`, 27 | }); 28 | } else if ((tokenAddresses as NonAppChainAddresses).isAppChain === false) { 29 | contractList.push({ 30 | address: (tokenAddresses as NonAppChainAddresses).Vault, 31 | label: `${chainSlug}, ${token}, Vault`, 32 | }); 33 | contractList.push({ 34 | address: (tokenAddresses as NonAppChainAddresses).NonMintableToken, 35 | label: `${chainSlug}, ${token}, NonMintableToken`, 36 | }); 37 | } else if ((tokenAddresses as STControllerChainAddresses).Controller) { 38 | contractList.push({ 39 | address: (tokenAddresses as STControllerChainAddresses).Controller, 40 | label: `${chainSlug}, ${token}, Controller`, 41 | }); 42 | contractList.push({ 43 | address: (tokenAddresses as STControllerChainAddresses).SuperToken, 44 | label: `${chainSlug}, ${token}, SuperToken`, 45 | }); 46 | } else if ((tokenAddresses as STVaultChainAddresses).Vault) { 47 | contractList.push({ 48 | address: (tokenAddresses as STVaultChainAddresses).Vault, 49 | label: `${chainSlug}, ${token}, Vault`, 50 | }); 51 | contractList.push({ 52 | address: (tokenAddresses as STVaultChainAddresses).NonMintableToken, 53 | label: `${chainSlug}, ${token}, NonMintableToken`, 54 | }); 55 | } 56 | 57 | if (tokenAddresses.LimitHook) { 58 | contractList.push({ 59 | address: tokenAddresses.LimitHook, 60 | label: `${chainSlug}, ${token}, LimitHook`, 61 | }); 62 | } 63 | if (tokenAddresses.LimitExecutionHook) { 64 | contractList.push({ 65 | address: tokenAddresses.LimitExecutionHook, 66 | label: `${chainSlug}, ${token}, LimitExecutionHook`, 67 | }); 68 | } 69 | if (tokenAddresses.ExecutionHelper) { 70 | contractList.push({ 71 | address: tokenAddresses.ExecutionHelper, 72 | label: `${chainSlug}, ${token}, ExecutionHelper`, 73 | }); 74 | } 75 | 76 | const siblings = Object.keys(tokenAddresses.connectors); 77 | siblings.forEach((sibling) => { 78 | const its = Object.keys(tokenAddresses.connectors[sibling]); 79 | for (const it of its) { 80 | contractList.push({ 81 | address: tokenAddresses.connectors[sibling][it], 82 | label: `${chainSlug}, ${token}, Connector ${sibling} ${it}`, 83 | }); 84 | } 85 | }); 86 | 87 | return contractList; 88 | }; 89 | -------------------------------------------------------------------------------- /script/script.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ts-node 2 | 3 | import { initDeploymentConfig } from "./constants"; 4 | import { addProject } from "./setup/newProject/main"; 5 | import { addNewToken } from "./setup/addNewToken"; 6 | import { editProject } from "./setup/editProject"; 7 | 8 | async function main() { 9 | const args = process.argv.slice(2); 10 | const command = args[0]; 11 | 12 | switch (command) { 13 | case "new": 14 | await addProject(); 15 | break; 16 | case "edit": 17 | await editProject(); 18 | break; 19 | case "add_token": 20 | await addNewToken(); 21 | break; 22 | default: 23 | console.log("Unknown command"); 24 | } 25 | } 26 | 27 | main(); 28 | -------------------------------------------------------------------------------- /script/setup/addNewToken.ts: -------------------------------------------------------------------------------- 1 | import prompts from "prompts"; 2 | import { appendToEnvFile, updateTokenEnums } from "./configUtils"; 3 | import { ChainSlug, MainnetIds, TestnetIds } from "@socket.tech/dl-core"; 4 | import { ExistingTokenAddresses, Tokens } from "../../src/enums"; 5 | import { generateTokenAddressesFile } from "./updateExistingTokenAddresses"; 6 | import { 7 | NewTokenInfo, 8 | getTokenMetadata, 9 | validateEthereumAddress, 10 | validateRPC, 11 | } from "./common"; 12 | import { chainSlugReverseMap } from "./enumMaps"; 13 | import { getJsonRpcUrl, rpcKeys } from "../helpers"; 14 | import { providers } from "ethers"; 15 | 16 | export const addNewToken = async () => { 17 | let chainOptions = [...MainnetIds, ...TestnetIds].map((chain) => ({ 18 | title: chainSlugReverseMap.get(String(chain)), 19 | value: chain, 20 | })); 21 | let newTokenInfo: NewTokenInfo = await getNewTokenInfo(chainOptions); 22 | if (!newTokenInfo.name) return; 23 | console.log("Adding new token: ", newTokenInfo); 24 | if (!Object.keys(Tokens).includes(newTokenInfo.symbol.toUpperCase())) { 25 | await updateTokenEnums(newTokenInfo); 26 | } 27 | 28 | const newTokensEnum = { 29 | ...Tokens, 30 | [newTokenInfo.symbol.toUpperCase()]: newTokenInfo.symbol.toUpperCase(), 31 | }; 32 | 33 | generateTokenAddressesFile( 34 | [ 35 | { 36 | chainSlug: newTokenInfo.chainSlug as ChainSlug, 37 | token: newTokenInfo.symbol.toUpperCase() as Tokens, 38 | address: newTokenInfo.address, 39 | }, 40 | ], 41 | newTokensEnum 42 | ); 43 | }; 44 | 45 | export const getNewTokenInfo = async ( 46 | chainOptions: { title: string; value: number }[] 47 | ) => { 48 | let newTokenInfo: NewTokenInfo = { 49 | name: "", 50 | symbol: "", 51 | decimals: 0, 52 | address: "", 53 | chainSlug: 0 as ChainSlug, 54 | }; 55 | 56 | const { chainSlug, address } = await prompts([ 57 | { 58 | name: "chainSlug", 59 | type: "select", 60 | message: "Select chain where token is deployed", 61 | choices: chainOptions, 62 | }, 63 | { 64 | name: "address", 65 | type: "text", 66 | message: "Enter token address", 67 | validate: (value) => validateEthereumAddress(value.trim()), 68 | }, 69 | ]); 70 | newTokenInfo.chainSlug = chainSlug as ChainSlug; 71 | newTokenInfo.address = address.trim(); 72 | 73 | if (ExistingTokenAddresses[chainSlug]) { 74 | for (let [symbol, address] of Object.entries( 75 | ExistingTokenAddresses[newTokenInfo.chainSlug] 76 | )) { 77 | if (address.toLowerCase() === newTokenInfo.address.toLowerCase()) { 78 | console.log( 79 | `Token already present in the repo as ${symbol} on chain ${chainSlugReverseMap.get( 80 | String(chainSlug) 81 | )}` 82 | ); 83 | return newTokenInfo; 84 | } 85 | } 86 | } 87 | 88 | let rpcKey = rpcKeys(chainSlug); 89 | let rpc = process.env[rpcKey]; 90 | if (!rpc) { 91 | const rpcInfo = await prompts([ 92 | { 93 | name: "rpc", 94 | type: "text", 95 | message: `Enter RPC url for the chain ${chainSlug} (for fetching token metadata)`, 96 | validate: (value) => validateRPC(chainSlug, value.trim()), 97 | }, 98 | ]); 99 | rpc = rpcInfo.rpc.trim(); 100 | appendToEnvFile(rpcKey, rpc); 101 | } 102 | 103 | newTokenInfo.address = newTokenInfo.address.trim(); 104 | let { name, symbol, decimals } = await getTokenMetadata( 105 | chainSlug, 106 | newTokenInfo.address, 107 | rpc 108 | ); 109 | if ( 110 | ExistingTokenAddresses[chainSlug]?.[symbol.toUpperCase()]?.toLowerCase() === 111 | newTokenInfo.address.toLowerCase() 112 | ) { 113 | console.log("Token already present in the list"); 114 | return newTokenInfo; 115 | } 116 | console.log("fetched token metadata: ", { name, symbol, decimals }); 117 | newTokenInfo = { 118 | ...newTokenInfo, 119 | name, 120 | symbol: symbol.toUpperCase(), 121 | decimals, 122 | chainSlug, 123 | }; 124 | return newTokenInfo; 125 | }; 126 | -------------------------------------------------------------------------------- /script/setup/common.ts: -------------------------------------------------------------------------------- 1 | import { ChainSlug } from "@socket.tech/dl-core"; 2 | import { Contract, providers, utils } from "ethers"; 3 | import { 4 | getProviderFromChainSlug, 5 | isContractAtAddress, 6 | rpcKeys, 7 | } from "../helpers"; 8 | import { Hooks, ProjectType } from "../../src"; 9 | import { StaticJsonRpcProvider } from "@ethersproject/providers"; 10 | import { Tokens } from "../../src/enums"; 11 | 12 | export type ProjectConfig = { 13 | projectType: ProjectType; 14 | projectName: string; 15 | hookType: Hooks; 16 | owner: string; 17 | isMainnet: boolean; 18 | newToken?: boolean; 19 | }; 20 | 21 | export type NewTokenInfo = { 22 | name: string; 23 | symbol: string; 24 | decimals: number; 25 | chainSlug: ChainSlug; 26 | address: string; 27 | }; 28 | 29 | type TokenRateLimits = Record< 30 | string, 31 | { sendingLimit: number; receivingLimit: number } 32 | >; 33 | 34 | export const validateEthereumAddress = (address: string) => { 35 | return utils.isAddress(address); 36 | }; 37 | 38 | export const validateEmptyValue = (data: string) => { 39 | const isEmpty = data == "" || data == null || data == undefined; 40 | return !isEmpty; 41 | }; 42 | 43 | export const getTokenMetadata = async ( 44 | chainSlug: ChainSlug, 45 | tokenAddress: string, 46 | rpc: string = "" 47 | ) => { 48 | try { 49 | let provider: StaticJsonRpcProvider; 50 | if (rpc) { 51 | provider = new StaticJsonRpcProvider(rpc); 52 | } else { 53 | provider = getProviderFromChainSlug(chainSlug); 54 | } 55 | 56 | const isContract = await isContractAtAddress(provider, tokenAddress); 57 | if (!isContract) { 58 | console.log( 59 | "\n\nInvalid token address. No contract present at the address.\n\n" 60 | ); 61 | process.exit(1); 62 | } 63 | const token = new utils.Interface([ 64 | "function name() view returns (string)", 65 | "function symbol() view returns (string)", 66 | "function decimals() view returns (uint8)", 67 | ]); 68 | const contract = new Contract(tokenAddress, token, provider); 69 | try { 70 | const name = await contract.name(); 71 | const symbol = await contract.symbol(); 72 | const decimals = await contract.decimals(); 73 | return { name, symbol, decimals }; 74 | } catch (error) { 75 | console.log( 76 | "\n\nError while fetching token metadata. Check if the chain is correct and entered address is a valid token address.\n\n" 77 | ); 78 | process.exit(1); 79 | } 80 | } catch (error) { 81 | console.log(error); 82 | process.exit(1); 83 | } 84 | }; 85 | 86 | export const validateRPC = async (chainSlug: ChainSlug, rpcUrl: string) => { 87 | try { 88 | let provider = new providers.StaticJsonRpcProvider(rpcUrl); 89 | let network = await provider.getNetwork(); 90 | if (chainSlug != ChainSlug.REYA && network.chainId !== chainSlug) { 91 | console.log( 92 | `ChainId mismatch: ChainId of the network is ${network.chainId} while the expected chainId is ${chainSlug}` 93 | ); 94 | return false; 95 | } 96 | return true; 97 | } catch (error) { 98 | console.log("Error while checking rpc : ", error); 99 | return false; 100 | } 101 | }; 102 | 103 | export const initialLimitsForSuperbridge: { 104 | [token in Tokens]?: { sendingLimit: number; receivingLimit: number }; 105 | } = { 106 | [Tokens.ETH]: { sendingLimit: 10.0, receivingLimit: 10.0 }, 107 | [Tokens.WETH]: { sendingLimit: 10.0, receivingLimit: 10.0 }, 108 | [Tokens.WSTETH]: { sendingLimit: 10.0, receivingLimit: 10.0 }, 109 | [Tokens.USDC]: { sendingLimit: 100_000.0, receivingLimit: 100_000.0 }, 110 | [Tokens.USDCE]: { sendingLimit: 100_000.0, receivingLimit: 100_000.0 }, 111 | [Tokens.USDT]: { sendingLimit: 100_000.0, receivingLimit: 100_000.0 }, 112 | [Tokens.DAI]: { sendingLimit: 100_000.0, receivingLimit: 100_000.0 }, 113 | [Tokens.WBTC]: { sendingLimit: 1.0, receivingLimit: 1.0 }, 114 | }; 115 | -------------------------------------------------------------------------------- /script/setup/enumMaps.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChainId, 3 | ChainSlug, 4 | DeploymentMode, 5 | IntegrationTypes, 6 | } from "@socket.tech/dl-core"; 7 | import { Project, Tokens } from "../../src/enums"; 8 | import { Hooks } from "../../src"; 9 | 10 | export const chainSlugReverseMap = createReverseEnumMap(ChainSlug); 11 | export const chainIdReverseMap = createReverseEnumMap(ChainId); 12 | export const tokensReverseMap = createReverseEnumMap(Tokens); 13 | export const integrationTypesreverseMap = 14 | createReverseEnumMap(IntegrationTypes); 15 | export const deploymentModeReverseMap = createReverseEnumMap(DeploymentMode); 16 | export const hookReverseMap = createReverseEnumMap(Hooks); 17 | export const projectReverseMap = createReverseEnumMap(Project); 18 | 19 | // Function to create a reverse map from an enum 20 | function createReverseEnumMap(enumObj: any) { 21 | const reverseMap = new Map(); 22 | for (const [key, value] of Object.entries(enumObj)) { 23 | reverseMap.set(String(value) as unknown as string, String(key)); 24 | } 25 | return reverseMap; 26 | } 27 | 28 | export const getEnumMaps = (tokensEnum: object = Tokens) => { 29 | // tokens is calculating separately because it is updated during setupScript with new token 30 | const tokensMap = createReverseEnumMap(tokensEnum); 31 | return { 32 | chainSlugMap: chainSlugReverseMap, 33 | tokensMap, 34 | integrationTypesMap: integrationTypesreverseMap, 35 | deploymentModeMap: deploymentModeReverseMap, 36 | hookMap: hookReverseMap, 37 | }; 38 | }; 39 | -------------------------------------------------------------------------------- /script/setup/generateConstants.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import { ProjectConstants, ProjectType } from "../../src"; 3 | import path from "path"; 4 | import { serializeConstants } from "./configUtils"; 5 | import { Tokens } from "../../src/enums"; 6 | 7 | export const generateConstantsFile = ( 8 | projectType: ProjectType, 9 | projectName: string, 10 | projectConstants: ProjectConstants, 11 | tokensEnum: object = Tokens 12 | ) => { 13 | let filePath = path.join( 14 | __dirname, 15 | `/../constants/projectConstants/${projectType}/${projectName}.ts` 16 | ); 17 | 18 | const content = ` 19 | import { 20 | ChainSlug, 21 | DeploymentMode, 22 | IntegrationTypes, 23 | } from "@socket.tech/dl-core"; 24 | import { Hooks, ProjectConstants } from "../../../../src"; 25 | import { Tokens } from "../../../../src/enums"; 26 | 27 | // 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. 28 | export const pc: ProjectConstants = { 29 | ${serializeConstants(projectConstants, 1, tokensEnum)} 30 | }; 31 | `; 32 | fs.writeFileSync(filePath, content); 33 | console.log(`✔ Project Constants file generated : ${filePath}`); 34 | }; 35 | -------------------------------------------------------------------------------- /script/setup/newProject/chainInfo.ts: -------------------------------------------------------------------------------- 1 | import prompts from "prompts"; 2 | import { ProjectType } from "../../../src"; 3 | 4 | export const getChainsInfo = async ( 5 | projectType: ProjectType, 6 | chainOptions: { title: string; value: number }[] 7 | ) => { 8 | if (projectType == ProjectType.SUPERBRIDGE) { 9 | const vaultChainsInfo = await prompts([ 10 | { 11 | name: "vaultChains", 12 | type: "multiselect", 13 | message: 14 | "Select vault chains (src chains, where token is already present and will be locked in bridge contract. check README for more info)", 15 | choices: chainOptions, 16 | min: 1, 17 | max: 20, 18 | }, 19 | ]); 20 | 21 | const controllerChainOptions = chainOptions.filter( 22 | (chainOption) => !vaultChainsInfo.vaultChains.includes(chainOption.value) 23 | ); 24 | const controllerChainsInfo = await prompts([ 25 | { 26 | name: "controllerChains", 27 | type: "select", 28 | message: 29 | "Select controller chain (app chain, where token will be minted/burned. check README for more info)", 30 | choices: controllerChainOptions, 31 | }, 32 | ]); 33 | return { 34 | vaultChains: vaultChainsInfo.vaultChains, 35 | controllerChains: [controllerChainsInfo.controllerChains], 36 | }; 37 | } else { 38 | const vaultChainsInfo = await prompts([ 39 | { 40 | name: "vaultChains", 41 | type: "multiselect", 42 | message: 43 | "Select a vault chain, if applicable (where token is already present and will be locked to bridge to other chains. Press enter without selecting anything if fresh supertoken deployment. check README for more info)", 44 | choices: chainOptions, 45 | min: 0, 46 | max: 1, 47 | }, 48 | ]); 49 | const controllerChainOptions = chainOptions.filter( 50 | (chainOption) => !vaultChainsInfo.vaultChains.includes(chainOption.value) 51 | ); 52 | const controllerChainsInfo = await prompts([ 53 | { 54 | name: "controllerChains", 55 | type: "multiselect", 56 | min: 1, 57 | max: 20, 58 | message: 59 | "Select controller chains, where token will be minted/burned (check README for more info)", 60 | choices: controllerChainOptions, 61 | }, 62 | ]); 63 | 64 | return { 65 | vaultChains: vaultChainsInfo.vaultChains, 66 | controllerChains: controllerChainsInfo.controllerChains, 67 | }; 68 | } 69 | }; 70 | -------------------------------------------------------------------------------- /script/setup/newProject/hookInfo.ts: -------------------------------------------------------------------------------- 1 | import prompts from "prompts"; 2 | import { ProjectType } from "../../../src"; 3 | import { Tokens } from "../../../src/enums"; 4 | import { validateEmptyValue } from "../common"; 5 | import { SuperTokenInfo, TokenRateLimits } from "./main"; 6 | import { getInitialLimitValue } from "./utils"; 7 | 8 | export const getHookRelatedInfo = async ( 9 | projectType: ProjectType, 10 | isLimitsRequired: boolean, 11 | tokens: Tokens[], 12 | superTokenInfoMap: Record = {} 13 | ) => { 14 | const tokenLimitInfo: TokenRateLimits = {}; 15 | if (isLimitsRequired) { 16 | for (const token of tokens) { 17 | const initialValue = await getInitialLimitValue( 18 | projectType, 19 | token, 20 | superTokenInfoMap 21 | ); 22 | const limitInfo = await prompts([ 23 | { 24 | name: "sendingLimit", 25 | type: "text", 26 | message: `Enter max daily sending limit for ${token} (Enter formatted values, 100.0 for 100 USDC. Check README for more info):`, 27 | validate: (value) => validateEmptyValue(String(value).trim()), 28 | initial: String(initialValue.sendingLimit), 29 | }, 30 | { 31 | name: "receivingLimit", 32 | type: "text", 33 | message: `Enter max daily receiving limit for ${token} (Enter formatted values, 100.0 for 100 USDC Check README for more info):`, 34 | validate: (value) => validateEmptyValue(String(value).trim()), 35 | initial: String(initialValue.receivingLimit), 36 | }, 37 | ]); 38 | 39 | tokenLimitInfo[token] = limitInfo; 40 | } 41 | } 42 | return { tokenLimitInfo }; 43 | }; 44 | -------------------------------------------------------------------------------- /script/setup/newProject/main.ts: -------------------------------------------------------------------------------- 1 | import { ChainSlug } from "@socket.tech/dl-core"; 2 | import { Tokens } from "../../../src/enums"; 3 | import { buildEnvFile, updateProjectEnums } from "../configUtils"; 4 | import { generateConstantsFile } from "../generateConstants"; 5 | import { getChainsInfo } from "./chainInfo"; 6 | import { getHookRelatedInfo } from "./hookInfo"; 7 | import { getProjectInfo } from "./projectInfo"; 8 | import { getProjectTokenListInfo } from "./tokenInfo"; 9 | import { buildProjectConstants } from "./utils"; 10 | 11 | export type TokenRateLimits = Record< 12 | string, 13 | { sendingLimit: number; receivingLimit: number } 14 | >; 15 | 16 | export type SuperTokenInfo = { 17 | name: string; 18 | symbol: string; 19 | decimals: number; 20 | owner: string; 21 | initialSupplyOwner: string; 22 | initialSupply: string; 23 | initialChain?: ChainSlug; 24 | currentAddresses?: { chainSlug: ChainSlug; address: string; token: string }[]; 25 | }; 26 | 27 | export type TokenInfo = { 28 | tokens: Tokens[]; 29 | superTokenInfoMap?: Record; 30 | mergeInboundWithTokens?: { 31 | [key in Tokens]?: Tokens[]; 32 | }; 33 | tokenAddresses?: { 34 | [key in Tokens]?: { 35 | [chainslug in ChainSlug]?: string; 36 | }; 37 | }; 38 | }; 39 | 40 | export type ChainsInfo = { 41 | vaultChains: ChainSlug[]; 42 | controllerChains: ChainSlug[]; 43 | }; 44 | export const tokenEnum = Tokens; 45 | 46 | export const addProject = async () => { 47 | const projectConfig = await getProjectInfo(); 48 | const { 49 | projectName, 50 | projectType, 51 | hookType, 52 | owner, 53 | isLimitsRequired, 54 | chainOptions, 55 | } = projectConfig; 56 | 57 | const chainsInfo: ChainsInfo = await getChainsInfo(projectType, chainOptions); 58 | const { vaultChains, controllerChains } = chainsInfo; 59 | const allChains = [...chainsInfo.vaultChains, ...chainsInfo.controllerChains]; 60 | 61 | const tokenInfo: TokenInfo = await getProjectTokenListInfo( 62 | projectType, 63 | owner, 64 | vaultChains, 65 | controllerChains 66 | ); 67 | const { tokenLimitInfo } = await getHookRelatedInfo( 68 | projectType, 69 | isLimitsRequired, 70 | tokenInfo.tokens, 71 | tokenInfo.superTokenInfoMap 72 | ); 73 | await updateProjectEnums(projectConfig.projectName, projectType); 74 | console.log(`✔ Updated Enums :Project`); 75 | await buildEnvFile( 76 | projectConfig.projectName, 77 | projectConfig.projectType, 78 | projectConfig.owner, 79 | tokenInfo.tokens, 80 | allChains 81 | ); 82 | 83 | const projectConstants = await buildProjectConstants( 84 | tokenInfo, 85 | chainsInfo, 86 | hookType, 87 | isLimitsRequired, 88 | tokenLimitInfo, 89 | allChains 90 | ); 91 | generateConstantsFile(projectType, projectName, projectConstants); 92 | 93 | console.log( 94 | `✔ Setup done! You can run this script again to add new projects, add new tokens, or edit project` 95 | ); 96 | }; 97 | -------------------------------------------------------------------------------- /script/setup/newProject/projectInfo.ts: -------------------------------------------------------------------------------- 1 | import prompts from "prompts"; 2 | import { DeploymentMode, Hooks, ProjectType } from "../../../src"; 3 | import { 4 | getChainName, 5 | getMainnetIds, 6 | getTestnetIds, 7 | initDeploymentConfig, 8 | } from "../../constants/deploymentConfig"; 9 | import { ProjectConfig, validateEthereumAddress } from "../common"; 10 | import { getMode, setMode } from "../../constants"; 11 | 12 | export const getProjectInfo = async () => { 13 | const currentOwnerAddress = process.env.OWNER_ADDRESS; 14 | const projectInfo: ProjectConfig = await prompts([ 15 | { 16 | name: "projectType", 17 | type: "select", 18 | choices: [ 19 | { 20 | title: "SuperBridge", 21 | value: ProjectType.SUPERBRIDGE, 22 | }, 23 | { 24 | title: "SuperToken", 25 | value: ProjectType.SUPERTOKEN, 26 | }, 27 | ], 28 | message: "Select project type", 29 | }, 30 | { 31 | name: "projectName", 32 | type: "text", 33 | message: 34 | "Enter project name (use underscore instead of spaces, eg: socket_bridge)", 35 | }, 36 | { 37 | name: "owner", 38 | type: "text", 39 | message: 40 | "Enter owner Address * (Owner will be the deployer initially to configure roles)", 41 | initial: currentOwnerAddress, 42 | validate: (value) => validateEthereumAddress(value.trim()), 43 | }, 44 | { 45 | name: "hookType", 46 | type: "select", 47 | choices: [ 48 | { 49 | title: "Limit Hook", 50 | value: Hooks.LIMIT_HOOK, 51 | }, 52 | { 53 | title: "Limit Execution Hook", 54 | value: Hooks.LIMIT_EXECUTION_HOOK, 55 | }, 56 | { 57 | title: "No Hook", 58 | value: Hooks.NO_HOOK, 59 | }, 60 | ], 61 | message: "Select Hook type (Recommended: Limit Hook)", 62 | }, 63 | { 64 | name: "isMainnet", 65 | type: "toggle", 66 | message: "Is the deployment for mainnet?", 67 | active: "yes", 68 | inactive: "no", 69 | }, 70 | ]); 71 | 72 | if (projectInfo.isMainnet) { 73 | setMode(DeploymentMode.PROD); 74 | } else { 75 | setMode(DeploymentMode.SURGE); 76 | } 77 | await initDeploymentConfig(); 78 | projectInfo.projectName = getProjectName( 79 | projectInfo.projectName, 80 | projectInfo.isMainnet 81 | ); 82 | projectInfo.owner = projectInfo.owner.trim(); 83 | const isLimitsRequired = 84 | projectInfo.hookType === Hooks.LIMIT_HOOK || 85 | projectInfo.hookType === Hooks.LIMIT_EXECUTION_HOOK; 86 | const possibleChains = projectInfo.isMainnet 87 | ? getMainnetIds() 88 | : getTestnetIds(); 89 | const chainOptions = possibleChains.map((chain) => ({ 90 | title: getChainName(chain), 91 | value: chain, 92 | })); 93 | return { ...projectInfo, isLimitsRequired, chainOptions }; 94 | }; 95 | 96 | export const getProjectName = (projectName: string, isMainnet: boolean) => { 97 | const newProjectName = projectName 98 | .toLowerCase() 99 | .trim() 100 | .replace(/[\s-]/g, "_"); // convert to lowercase, replace all space and - with _ 101 | return isMainnet ? newProjectName + "_mainnet" : newProjectName + "_testnet"; 102 | }; 103 | -------------------------------------------------------------------------------- /script/setup/newProject/utils.ts: -------------------------------------------------------------------------------- 1 | import { ChainSlug, IntegrationTypes } from "@socket.tech/dl-core"; 2 | import { 3 | Hooks, 4 | ProjectConstants, 5 | ProjectType, 6 | tokensWithOnePoolId, 7 | } from "../../../src"; 8 | import { Tokens } from "../../../src/enums"; 9 | import { getMode } from "../../constants"; 10 | import { initialLimitsForSuperbridge } from "../common"; 11 | import { ChainsInfo, SuperTokenInfo, TokenInfo, TokenRateLimits } from "./main"; 12 | 13 | export const buildProjectConstants = async ( 14 | tokenInfo: TokenInfo, 15 | chainsInfo: ChainsInfo, 16 | hookType: Hooks, 17 | isLimitsRequired: boolean, 18 | tokenLimitInfo: TokenRateLimits, 19 | allChains: ChainSlug[] 20 | ) => { 21 | const deploymentMode = getMode(); 22 | const projectConstants: ProjectConstants = { 23 | [deploymentMode]: {}, 24 | }; 25 | 26 | for (const token of tokenInfo.tokens) { 27 | const poolCount = tokensWithOnePoolId.includes(token) ? 1 : undefined; // If poolCount is not 1, assign undefined to avoid adding poolCount 0 in constants file. 28 | const limitsAndPoolId = {}; 29 | for (const chain of allChains) { 30 | limitsAndPoolId[chain] = { 31 | [IntegrationTypes.fast]: { ...tokenLimitInfo[token], poolCount }, 32 | }; 33 | } 34 | 35 | projectConstants[deploymentMode][token] = { 36 | vaultChains: chainsInfo.vaultChains, 37 | controllerChains: chainsInfo.controllerChains, 38 | tokenAddresses: tokenInfo.tokenAddresses?.[token], 39 | mergeInboundWithTokens: tokenInfo?.mergeInboundWithTokens?.[token], 40 | hook: { 41 | hookType, 42 | }, 43 | }; 44 | 45 | const superTokenInfo = tokenInfo.superTokenInfoMap?.[token]; 46 | if (superTokenInfo) { 47 | delete superTokenInfo.currentAddresses; 48 | projectConstants[deploymentMode][token].superTokenInfo = superTokenInfo; 49 | } 50 | 51 | if (isLimitsRequired) { 52 | projectConstants[deploymentMode][token].hook.limitsAndPoolId = 53 | limitsAndPoolId; 54 | } 55 | } 56 | 57 | return JSON.parse(JSON.stringify(projectConstants)); // stringify and parse to remove undefined values 58 | }; 59 | 60 | export const getInitialLimitValue = async ( 61 | projectType: ProjectType, 62 | token: Tokens, 63 | superTokenInfoMap: Record = {} 64 | ) => { 65 | if (projectType == ProjectType.SUPERBRIDGE) { 66 | return ( 67 | initialLimitsForSuperbridge[token] ?? { 68 | sendingLimit: 0, 69 | receivingLimit: 0, 70 | } 71 | ); 72 | } else if (projectType == ProjectType.SUPERTOKEN) { 73 | const info = superTokenInfoMap[token.toUpperCase()]; 74 | return { 75 | sendingLimit: info?.initialSupply 76 | ? parseInt(info?.initialSupply) / 100 77 | : 0, 78 | receivingLimit: info?.initialSupply 79 | ? parseInt(info?.initialSupply) / 100 80 | : 0, 81 | }; 82 | // think about using initial supply 83 | } 84 | }; 85 | -------------------------------------------------------------------------------- /script/setup/updateExistingTokenAddresses.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import { ChainSlug, Hooks, ProjectConstants, ProjectType } from "../../src"; 3 | import { enumFolderPath, serializeConstants } from "./configUtils"; 4 | import { Tokens } from "../../src/enums"; 5 | import { ExistingTokenAddresses } from "../../src/enums"; 6 | 7 | export type TokenAddressObj = { 8 | chainSlug: ChainSlug; 9 | token: Tokens | string; 10 | address: string; 11 | }; 12 | export const generateTokenAddressesFile = ( 13 | tokenAddresses: TokenAddressObj[], 14 | tokensEnum: object = Tokens 15 | ) => { 16 | for (const tokenAddressObj of tokenAddresses) { 17 | const { chainSlug, token, address } = tokenAddressObj; 18 | if (!ExistingTokenAddresses[chainSlug]) 19 | ExistingTokenAddresses[chainSlug] = {}; 20 | ExistingTokenAddresses[chainSlug][token] = address; 21 | } 22 | const serializedContent = serializeConstants( 23 | ExistingTokenAddresses, 24 | 0, 25 | tokensEnum 26 | ); 27 | const content = ` 28 | import { ChainSlug } from "@socket.tech/dl-core"; 29 | import { Tokens } from "./tokens"; 30 | 31 | export const ExistingTokenAddresses: { 32 | [key in ChainSlug]?: { [key in Tokens]?: string }; 33 | } = { 34 | ${serializedContent} 35 | }; 36 | `; 37 | fs.writeFileSync(enumFolderPath + "existing-token-addresses.ts", content); 38 | console.log( 39 | `✔ existing token addresses file updated : ${ 40 | enumFolderPath + "existing-token-addresses.ts" 41 | }` 42 | ); 43 | }; 44 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | import { ChainSlug } from "@socket.tech/dl-core"; 2 | import { Project, Tokens } from "./enums"; 3 | 4 | export const ChainSlugToProject: { [chainSlug in ChainSlug]?: Project } = { 5 | [ChainSlug.AEVO]: Project.AEVO, 6 | [ChainSlug.AEVO_TESTNET]: Project.AEVO_TESTNET, 7 | [ChainSlug.LYRA_TESTNET]: Project.LYRA_TESTNET, 8 | [ChainSlug.LYRA]: Project.LYRA, 9 | [ChainSlug.SX_NETWORK_TESTNET]: Project.SX_NETWORK_TESTNET, 10 | }; 11 | 12 | // pool Id is used to identify a source when multiple tokens use same controller. This is useful for the cases like merging inbounds 13 | // for USDC and USDCE so we dont have 2 versions of USDC on app chain. 14 | export const tokensWithOnePoolId: Tokens[] = [Tokens.USDCE, Tokens.WETH]; 15 | 16 | export const tokensAllowingMergingInbound: { 17 | [token in Tokens]?: Tokens[]; 18 | } = { 19 | [Tokens.USDC]: [Tokens.USDCE], // Currently only USDC can be merged into USDCE. Later on can add SUSD, USDT, DAI, etc. if needed. 20 | [Tokens.USDCE]: [Tokens.USDC], 21 | [Tokens.WETH]: [Tokens.ETH], 22 | [Tokens.ETH]: [Tokens.WETH], 23 | }; 24 | -------------------------------------------------------------------------------- /src/core.ts: -------------------------------------------------------------------------------- 1 | // Exporting so that they can also be used by downstream projects without explicitly importing dl-core 2 | export { 3 | DeploymentMode, 4 | ChainSlug, 5 | IntegrationTypes, 6 | } from "@socket.tech/dl-core"; 7 | -------------------------------------------------------------------------------- /src/enum.ts: -------------------------------------------------------------------------------- 1 | export enum Hooks { 2 | NO_HOOK = "NO_HOOK", 3 | LIMIT_HOOK = "LIMIT_HOOK", 4 | LIMIT_EXECUTION_HOOK = "LIMIT_EXECUTION_HOOK", 5 | YIELD_LIMIT_EXECUTION_HOOK = "YIELD_LIMIT_EXECUTION_HOOK", 6 | // CONTROLLER_YIELD_LIMIT_EXECUTION_HOOK = "CONTROLLER_YIELD_LIMIT_EXECUTION_HOOK", 7 | // VAULT_YIELD_LIMIT_EXECUTION_HOOK = "VAULT_YIELD_LIMIT_EXECUTION_HOOK", 8 | } 9 | 10 | export enum ProjectType { 11 | SUPERBRIDGE = "superbridge", 12 | SUPERTOKEN = "supertoken", 13 | } 14 | 15 | export enum CommonContracts { 16 | Vault = "Vault", 17 | Controller = "Controller", 18 | NonMintableToken = "NonMintableToken", 19 | } 20 | 21 | export enum TokenContracts { 22 | NonMintableToken = "NonMintableToken", 23 | MintableToken = "MintableToken", 24 | SuperToken = "SuperToken", 25 | } 26 | 27 | export enum SuperBridgeContracts { 28 | MintableToken = "MintableToken", 29 | NonMintableToken = "NonMintableToken", 30 | Vault = "Vault", 31 | Controller = "Controller", 32 | FiatTokenV2_1_Controller = "FiatTokenV2_1_Controller", 33 | ExchangeRate = "ExchangeRate", 34 | ConnectorPlug = "ConnectorPlug", 35 | } 36 | 37 | export enum HookContracts { 38 | LimitHook = "LimitHook", 39 | LimitExecutionHook = "LimitExecutionHook", 40 | ControllerYieldLimitExecutionHook = "Controller_YieldLimitExecHook", 41 | VaultYieldLimitExecutionHook = "Vault_YieldLimitExecHook", 42 | ExecutionHelper = "ExecutionHelper", 43 | } 44 | export enum SuperTokenContracts { 45 | NonSuperToken = "NonSuperToken", 46 | SuperToken = "SuperToken", 47 | } 48 | -------------------------------------------------------------------------------- /src/enums/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./tokens"; 2 | export * from "./projects"; 3 | export * from "./existing-token-addresses"; 4 | export * from "./tokenSymbol"; 5 | export * from "./tokenName"; 6 | export * from "./tokenDecimals"; 7 | -------------------------------------------------------------------------------- /src/enums/prodTestnetProjects.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "./projects"; 2 | 3 | export const ProdTestnetProjects = [ 4 | Project.AEVO_TESTNET, 5 | Project.LYRA_TESTNET, 6 | Project.SX_NETWORK_TESTNET, 7 | Project.LEAF_TESTNET, 8 | Project.RAIN_TESTNET, 9 | Project.MIST_TESTNET, 10 | Project.REYA_CRONOS, 11 | Project.SYNDR_SEPOLIA_TESTNET, 12 | Project.TESTING_TESTNET, 13 | ]; 14 | -------------------------------------------------------------------------------- /src/enums/projectType.ts: -------------------------------------------------------------------------------- 1 | import { ProjectType } from "../enum"; 2 | import { Project } from "./projects"; 3 | 4 | export const ProjectTypeMap: Record = { 5 | [Project.AEVO]: ProjectType.SUPERBRIDGE, 6 | [Project.AEVO_TESTNET]: ProjectType.SUPERBRIDGE, 7 | [Project.LYRA]: ProjectType.SUPERBRIDGE, 8 | [Project.LYRA_TESTNET]: ProjectType.SUPERBRIDGE, 9 | [Project.REYA_CRONOS]: ProjectType.SUPERBRIDGE, 10 | [Project.REYA]: ProjectType.SUPERBRIDGE, 11 | [Project.RAIN_TESTNET]: ProjectType.SUPERBRIDGE, 12 | [Project.SX_NETWORK_TESTNET]: ProjectType.SUPERBRIDGE, 13 | [Project.SPECTRAL_SIGNAL]: ProjectType.SUPERTOKEN, 14 | [Project.LEAF_TESTNET]: ProjectType.SUPERTOKEN, 15 | [Project.MIST_TESTNET]: ProjectType.SUPERTOKEN, 16 | [Project.SYNDR_SEPOLIA_TESTNET]: ProjectType.SUPERBRIDGE, 17 | [Project.TESTING_MAINNET]: ProjectType.SUPERTOKEN, 18 | [Project.AA_MAINNET]: ProjectType.SUPERTOKEN, 19 | [Project.SV_MAINNET]: ProjectType.SUPERTOKEN, 20 | [Project.ADG_MAINNET]: ProjectType.SUPERTOKEN, 21 | [Project.AAVEGOTCHI_MAINNET]: ProjectType.SUPERTOKEN, 22 | [Project.TIMESWAP_TEST_MAINNET]: ProjectType.SUPERTOKEN, 23 | [Project.TESTING_TESTNET]: ProjectType.SUPERTOKEN, 24 | [Project.MAGIC_MAINNET]: ProjectType.SUPERTOKEN, 25 | [Project.POLTER_TESTNET]: ProjectType.SUPERBRIDGE, 26 | [Project.B3_MAINNET]: ProjectType.SUPERBRIDGE, 27 | }; 28 | -------------------------------------------------------------------------------- /src/enums/projects.ts: -------------------------------------------------------------------------------- 1 | export enum Project { 2 | AEVO = "aevo", 3 | AEVO_TESTNET = "aevo-testnet", 4 | LYRA_TESTNET = "lyra-testnet", 5 | LYRA = "lyra", 6 | SX_NETWORK_TESTNET = "sx-network-testnet", 7 | LEAF_TESTNET = "leaf-testnet", 8 | RAIN_TESTNET = "rain-testnet", 9 | MIST_TESTNET = "mist-testnet", 10 | REYA_CRONOS = "reya-cronos", 11 | REYA = "reya", 12 | SPECTRAL_SIGNAL = "spectral-signal", 13 | SYNDR_SEPOLIA_TESTNET = "syndr_sepolia_testnet", 14 | TESTING_MAINNET = "testing_mainnet", 15 | AA_MAINNET = "aa_mainnet", 16 | SV_MAINNET = "sv_mainnet", 17 | ADG_MAINNET = "adg_mainnet", 18 | AAVEGOTCHI_MAINNET = "aavegotchi_mainnet", 19 | TIMESWAP_TEST_MAINNET = "timeswap_test_mainnet", 20 | TESTING_TESTNET = "testing_testnet", 21 | MAGIC_MAINNET = "magic_mainnet", 22 | POLTER_TESTNET = "polter_testnet", 23 | B3_MAINNET = "b3_mainnet", 24 | } 25 | -------------------------------------------------------------------------------- /src/enums/tokenDecimals.ts: -------------------------------------------------------------------------------- 1 | import { Tokens } from "./tokens"; 2 | 3 | export const tokenDecimals: { [key in Tokens]: number } = { 4 | [Tokens.Moon]: 18, 5 | [Tokens.USDC]: 6, 6 | [Tokens.USDCE]: 6, 7 | [Tokens.WETH]: 18, 8 | [Tokens.WBTC]: 8, 9 | [Tokens.USDT]: 6, 10 | [Tokens.SNX]: 18, 11 | [Tokens.WSTETH]: 18, 12 | [Tokens.DAI]: 18, 13 | [Tokens.GUARD]: 18, 14 | [Tokens.ETH]: 18, 15 | [Tokens.MTK]: 18, 16 | [Tokens.FUD]: 18, 17 | [Tokens.FOMO]: 18, 18 | [Tokens.ALPHA]: 18, 19 | [Tokens.KEK]: 18, 20 | [Tokens.GLTR]: 18, 21 | [Tokens.STIME]: 18, 22 | [Tokens.USDE]: 6, 23 | [Tokens.MAGIC]: 18, 24 | [Tokens.SUSDE]: 18, 25 | [Tokens.SDEUSD]: 18, 26 | [Tokens.DEUSD]: 18, 27 | [Tokens.B3]: 18, 28 | }; 29 | -------------------------------------------------------------------------------- /src/enums/tokenName.ts: -------------------------------------------------------------------------------- 1 | import { Tokens } from "./tokens"; 2 | 3 | export const tokenName: { [key in Tokens]: string } = { 4 | [Tokens.Moon]: "Moon", 5 | [Tokens.USDCE]: "Bridged USD coin", 6 | [Tokens.USDC]: "USD coin", 7 | [Tokens.WETH]: "Wrapped Ether", 8 | [Tokens.WBTC]: "Wrapped Bitcoin", 9 | [Tokens.USDT]: "Tether USD", 10 | [Tokens.SNX]: "Synthetix Network Token", 11 | [Tokens.WSTETH]: "Wrapped liquid staked Ether 2.0", 12 | [Tokens.DAI]: "Dai Stablecoin", 13 | [Tokens.GUARD]: "Guardian", 14 | [Tokens.ETH]: "Ether", 15 | [Tokens.MTK]: "MockToken", 16 | [Tokens.FUD]: "Aavegotchi FUD", 17 | [Tokens.FOMO]: "Aavegotchi FOMO", 18 | [Tokens.ALPHA]: "Aavegotchi ALPHA", 19 | [Tokens.KEK]: "Aavegotchi KEK", 20 | [Tokens.GLTR]: "GAX Liquidity Token Reward", 21 | [Tokens.STIME]: "SuperTimeToken", 22 | [Tokens.USDE]: "USDe", 23 | [Tokens.MAGIC]: "magic", 24 | [Tokens.SUSDE]: "Staked USDe", 25 | [Tokens.SDEUSD]: "Staked deUSD", 26 | [Tokens.DEUSD]: "deUSD", 27 | [Tokens.B3]: "B3", 28 | }; 29 | -------------------------------------------------------------------------------- /src/enums/tokenSymbol.ts: -------------------------------------------------------------------------------- 1 | import { Tokens } from "./tokens"; 2 | 3 | export const tokenSymbol: { [key in Tokens]: string } = { 4 | [Tokens.Moon]: "MOON", 5 | [Tokens.USDCE]: "USDC.e", 6 | [Tokens.USDC]: "USDC", 7 | [Tokens.WETH]: "WETH", 8 | [Tokens.WBTC]: "WBTC", 9 | [Tokens.USDT]: "USDT", 10 | [Tokens.SNX]: "SNX", 11 | [Tokens.WSTETH]: "wstETH", 12 | [Tokens.DAI]: "DAI", 13 | [Tokens.GUARD]: "GUARD", 14 | [Tokens.ETH]: "ETH", 15 | [Tokens.MTK]: "MTK", 16 | [Tokens.FUD]: "FUD", 17 | [Tokens.FOMO]: "FOMO", 18 | [Tokens.ALPHA]: "ALPHA", 19 | [Tokens.KEK]: "KEK", 20 | [Tokens.GLTR]: "GLTR", 21 | [Tokens.STIME]: "STIME", 22 | [Tokens.USDE]: "USDe", 23 | [Tokens.MAGIC]: "MAGIC", 24 | [Tokens.SUSDE]: "SUSDE", 25 | [Tokens.SDEUSD]: "SDEUSD", 26 | [Tokens.DEUSD]: "DEUSD", 27 | [Tokens.B3]: "B3", 28 | }; 29 | -------------------------------------------------------------------------------- /src/enums/tokens.ts: -------------------------------------------------------------------------------- 1 | export enum Tokens { 2 | USDCE = "USDC.e", 3 | USDC = "USDC", 4 | USDT = "USDT", 5 | DAI = "DAI", 6 | WETH = "WETH", 7 | ETH = "ETH", 8 | WSTETH = "wstETH", 9 | WBTC = "WBTC", 10 | SNX = "SNX", 11 | GUARD = "GUARD", 12 | MTK = "MTK", 13 | FUD = "FUD", 14 | FOMO = "FOMO", 15 | ALPHA = "ALPHA", 16 | KEK = "KEK", 17 | GLTR = "GLTR", 18 | STIME = "STIME", 19 | Moon = "MOON", 20 | USDE = "USDe", 21 | MAGIC = "MAGIC", 22 | SUSDE = "SUSDE", 23 | SDEUSD = "SDEUSD", 24 | DEUSD = "DEUSD", 25 | B3 = "B3", 26 | } 27 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./types"; 2 | export * from "./core"; 3 | export * from "./constants"; 4 | export * from "./enum"; 5 | export * from "./socket-gas-helpers/estimateGasLimit"; 6 | -------------------------------------------------------------------------------- /src/socket-gas-helpers/arb-estimate.ts: -------------------------------------------------------------------------------- 1 | import { utils, BigNumber } from "ethers"; 2 | import { ArbGasInfo__factory } from "@arbitrum/sdk/dist/lib/abi/factories/ArbGasInfo__factory"; 3 | import { NodeInterface__factory } from "@arbitrum/sdk/dist/lib/abi/factories/NodeInterface__factory"; 4 | import { 5 | ARB_GAS_INFO, 6 | NODE_INTERFACE_ADDRESS, 7 | } from "@arbitrum/sdk/dist/lib/dataEntities/constants"; 8 | import { StaticJsonRpcProvider } from "@ethersproject/providers"; 9 | import { TxData } from "./utils"; 10 | 11 | export const getArbitrumGasLimitEstimate = async ( 12 | provider: StaticJsonRpcProvider, 13 | txData: TxData 14 | ): Promise => { 15 | const arbGasInfo = ArbGasInfo__factory.connect(ARB_GAS_INFO, provider); 16 | const nodeInterface = NodeInterface__factory.connect( 17 | NODE_INTERFACE_ADDRESS, 18 | provider 19 | ); 20 | // Getting the gas prices from ArbGasInfo.getPricesInWei() 21 | const gasComponents = await arbGasInfo.callStatic.getPricesInWei(); 22 | const gasEstimateComponents = 23 | await nodeInterface.callStatic.gasEstimateComponents( 24 | txData.to, 25 | false, 26 | txData.data, 27 | { from: txData.from } 28 | ); 29 | 30 | const l2GasUsed = gasEstimateComponents.gasEstimate.sub( 31 | gasEstimateComponents.gasEstimateForL1 32 | ); 33 | 34 | // Size in bytes of the calldata to post on L1 35 | const L1S = 140 + utils.hexDataLength(txData.data); 36 | 37 | // Estimated L1 gas cost 38 | const L1C = gasComponents[1].mul(L1S); 39 | 40 | // Extra buffer 41 | const B = L1C.div(gasComponents[5]); 42 | 43 | // G (Gas Limit) = l2GasUsed + B 44 | const gasLimit = l2GasUsed.add(B); 45 | return gasLimit; 46 | }; 47 | -------------------------------------------------------------------------------- /src/socket-gas-helpers/estimateGasLimit.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber, providers, utils } from "ethers"; 2 | import PlugABI from "@socket.tech/dl-core/artifacts/abi/IPlug.json"; 3 | 4 | import { ChainDetails, Inputs, getPayload } from "./utils"; 5 | import { getArbitrumGasLimitEstimate } from "./arb-estimate"; 6 | import { getOpAndEthGasLimitEstimate } from "./op-n-eth-estimate"; 7 | import { 8 | arbChains, 9 | arbL3Chains, 10 | DeploymentMode, 11 | getAddresses, 12 | } from "@socket.tech/dl-core"; 13 | 14 | export const estimateGasLimit = async ( 15 | chainDetails: ChainDetails, 16 | inputs: Inputs 17 | ): Promise => { 18 | const srcChainSlug = chainDetails.srcChainSlug; 19 | 20 | const provider = new providers.StaticJsonRpcProvider(chainDetails.dstRPC); 21 | const payload = await getPayload(inputs, provider); 22 | 23 | const abiInterface = new utils.Interface(PlugABI); 24 | const data = abiInterface.encodeFunctionData("inbound", [ 25 | srcChainSlug, 26 | payload, 27 | ]); 28 | 29 | const txData = { 30 | from: getAddresses(chainDetails.srcChainSlug, DeploymentMode.PROD).Socket, 31 | to: inputs.connectorPlug, 32 | data, 33 | }; 34 | 35 | if ( 36 | arbChains.includes(chainDetails.dstChainSlug) || 37 | arbL3Chains.includes(chainDetails.dstChainSlug) 38 | ) { 39 | return await getArbitrumGasLimitEstimate(provider, txData); 40 | } else { 41 | // works for opt and eth like chains 42 | return await getOpAndEthGasLimitEstimate(provider, txData); 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /src/socket-gas-helpers/op-n-eth-estimate.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber } from "ethers"; 2 | import { StaticJsonRpcProvider } from "@ethersproject/providers"; 3 | import { asL2Provider } from "@eth-optimism/sdk"; 4 | import { TxData } from "./utils"; 5 | 6 | // Get optimism gas limit from the SDK 7 | export const getOpAndEthGasLimitEstimate = async ( 8 | provider: StaticJsonRpcProvider, 9 | txData: TxData 10 | ): Promise => { 11 | const l2Provider = asL2Provider(provider); 12 | const gasLimit = await l2Provider.estimateGas(txData); 13 | return gasLimit; 14 | }; 15 | -------------------------------------------------------------------------------- /src/socket-gas-helpers/utils.ts: -------------------------------------------------------------------------------- 1 | import { Contract } from "ethers"; 2 | import { defaultAbiCoder } from "ethers/lib/utils"; 3 | import { StaticJsonRpcProvider } from "@ethersproject/providers"; 4 | 5 | export type TxData = { 6 | from: string; 7 | to: string; 8 | data: string; 9 | }; 10 | 11 | export type Inputs = { 12 | amount: string; 13 | receiver: string; 14 | extraData: string; 15 | connectorPlug: string; 16 | }; 17 | 18 | export type ChainDetails = { 19 | srcChainSlug: number; 20 | dstChainSlug: number; 21 | dstRPC: string; 22 | }; 23 | 24 | const ConnectorABI = [ 25 | { 26 | inputs: [], 27 | name: "getMessageId", 28 | outputs: [ 29 | { 30 | internalType: "bytes32", 31 | name: "", 32 | type: "bytes32", 33 | }, 34 | ], 35 | stateMutability: "view", 36 | type: "function", 37 | }, 38 | ]; 39 | 40 | export const getPayload = async ( 41 | inputs: Inputs, 42 | provider: StaticJsonRpcProvider 43 | ) => { 44 | const connectorContract = new Contract( 45 | inputs.connectorPlug, 46 | ConnectorABI, 47 | provider 48 | ); 49 | const msgId = await connectorContract.getMessageId(); 50 | return defaultAbiCoder.encode( 51 | ["address", "uint256", "bytes32", "bytes"], 52 | [inputs.receiver, inputs.amount, msgId, inputs.extraData] 53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /test/mocks/FiatTokenV2_1_Mintable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.13; 3 | 4 | import "../../contracts/bridge/FiatTokenV2_1/IFiatTokenV2_1_Mintable.sol"; 5 | 6 | // this is a mock token used in tests, other projects' token to be used here 7 | contract FiatTokenV2_1_Mintable is IFiatTokenV2_1_Mintable { 8 | constructor( 9 | string memory name_, 10 | string memory symbol_, 11 | uint8 decimals_ 12 | ) ERC20(name_, symbol_, decimals_) {} 13 | 14 | function mint(address receiver_, uint256 amount_) external override { 15 | _mint(receiver_, amount_); 16 | } 17 | 18 | function burn(uint256 amount_) external override { 19 | _burn(msg.sender, amount_); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/mocks/MintableToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.13; 2 | 3 | import "solmate/tokens/ERC20.sol"; 4 | 5 | // this is a mock token used in tests, other projects' token to be used here 6 | contract MintableToken is ERC20 { 7 | constructor( 8 | string memory name_, 9 | string memory symbol_, 10 | uint8 decimals_ 11 | ) ERC20(name_, symbol_, decimals_) {} 12 | 13 | function mint(address receiver_, uint256 amount_) external { 14 | _mint(receiver_, amount_); 15 | } 16 | 17 | function burn(address burner_, uint256 amount_) external { 18 | _burn(burner_, amount_); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/mocks/MockExecutableReceiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.13; 2 | 3 | import "solmate/tokens/ERC20.sol"; 4 | 5 | // this is a mock token used in tests, other projects' token to be used here 6 | contract MockExecutableReceiver { 7 | ERC20 public token; 8 | address public admin; 9 | uint256 public counter; 10 | 11 | error TransferFailed(); 12 | error InvalidAmount(); 13 | 14 | constructor(address admin_, address token_) { 15 | admin = admin_; 16 | token = ERC20(token_); 17 | } 18 | 19 | function incrementCounter() external { 20 | counter++; 21 | } 22 | 23 | function transferFundsToAdmin(uint256 amount_) external { 24 | if (amount_ > 50 && counter == 0) { 25 | revert InvalidAmount(); 26 | } 27 | bool success = token.transfer(admin, amount_); 28 | if (!success) revert TransferFailed(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/mocks/MockSocket.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.13; 2 | 3 | import "../../contracts/interfaces/ISocket.sol"; 4 | import "../../contracts/interfaces/IPlug.sol"; 5 | 6 | contract MockSocket is ISocket { 7 | uint32 _localSlug; 8 | 9 | struct PlugConfig { 10 | address siblingPlug; 11 | address inboundSwitchboard; 12 | address outboundSwitchboard; 13 | } 14 | // localSlug => localPlug => siblingSlug => config(inboundSwitchboard, outboundSwitchboard, siblingPlug) 15 | mapping(uint32 => mapping(address => mapping(uint32 => PlugConfig))) 16 | public plugConfigs; 17 | 18 | error WrongSiblingPlug(); 19 | error PlugDisconnected(); 20 | 21 | function chainSlug() external view override returns (uint32) { 22 | return _localSlug; 23 | } 24 | 25 | function setLocalSlug(uint32 localSlug_) external { 26 | _localSlug = localSlug_; 27 | } 28 | 29 | function connect( 30 | uint32 siblingChainSlug_, 31 | address siblingPlug_, 32 | address inboundSwitchboard_, 33 | address outboundSwitchboard_ 34 | ) external override { 35 | PlugConfig storage plugConfig = plugConfigs[_localSlug][msg.sender][ 36 | siblingChainSlug_ 37 | ]; 38 | 39 | plugConfig.siblingPlug = siblingPlug_; 40 | plugConfig.inboundSwitchboard = inboundSwitchboard_; 41 | plugConfig.outboundSwitchboard = outboundSwitchboard_; 42 | } 43 | 44 | function outbound( 45 | uint32 siblingChainSlug_, 46 | uint256 minMsgGasLimit_, 47 | bytes32, 48 | bytes32, 49 | bytes calldata payload_ 50 | ) external payable override returns (bytes32) { 51 | PlugConfig memory srcPlugConfig = plugConfigs[_localSlug][msg.sender][ 52 | siblingChainSlug_ 53 | ]; 54 | 55 | if (srcPlugConfig.siblingPlug == address(0)) revert PlugDisconnected(); 56 | 57 | PlugConfig memory dstPlugConfig = plugConfigs[siblingChainSlug_][ 58 | srcPlugConfig.siblingPlug 59 | ][_localSlug]; 60 | 61 | if (dstPlugConfig.siblingPlug != msg.sender) revert WrongSiblingPlug(); 62 | IPlug(srcPlugConfig.siblingPlug).inbound{gas: minMsgGasLimit_}( 63 | _localSlug, 64 | payload_ 65 | ); 66 | 67 | return 68 | bytes32( 69 | (uint256(_localSlug) << 224) | 70 | (uint256(uint160(srcPlugConfig.siblingPlug)) << 64) | 71 | 0 72 | ); 73 | } 74 | 75 | // ignore ISocket function 76 | function execute( 77 | ISocket.ExecutionDetails calldata executionDetails_, 78 | ISocket.MessageDetails calldata messageDetails_ 79 | ) external payable override {} 80 | 81 | // ignore ISocket function 82 | function getMinFees( 83 | uint256 minMsgGasLimit_, 84 | uint256 payloadSize_, 85 | bytes32 executionParams_, 86 | bytes32 transmissionParams_, 87 | uint32 siblingChainSlug_, 88 | address plug_ 89 | ) external view override returns (uint256 totalFees) {} 90 | 91 | function getPlugConfig( 92 | address plugAddress_, 93 | uint32 siblingChainSlug_ 94 | ) 95 | external 96 | view 97 | returns ( 98 | address siblingPlug, 99 | address inboundSwitchboard__, 100 | address outboundSwitchboard__, 101 | address capacitor__, 102 | address decapacitor__ 103 | ) 104 | { 105 | PlugConfig memory srcPlugConfig = plugConfigs[_localSlug][plugAddress_][ 106 | siblingChainSlug_ 107 | ]; 108 | 109 | return ( 110 | srcPlugConfig.siblingPlug, 111 | address(srcPlugConfig.inboundSwitchboard), 112 | address(srcPlugConfig.outboundSwitchboard), 113 | address(0), 114 | address(0) 115 | ); 116 | } 117 | 118 | function globalMessageCount() external view returns (uint64) {} 119 | } 120 | -------------------------------------------------------------------------------- /test/mocks/MockStrategy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only 2 | pragma solidity 0.8.13; 3 | 4 | import "../../contracts/interfaces/IStrategy.sol"; 5 | import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; 6 | 7 | /** 8 | * @title MockStrategy 9 | */ 10 | contract MockStrategy is IStrategy { 11 | IERC20 public token; 12 | 13 | event Invested(uint256 amount); 14 | error InsufficientFunds(); 15 | 16 | constructor(address token_) { 17 | token = IERC20(token_); 18 | } 19 | 20 | function withdraw(uint256 amount_) external returns (uint256) { 21 | uint256 total = token.balanceOf(address(this)); 22 | if (total < amount_) revert InsufficientFunds(); 23 | token.transfer(msg.sender, amount_); 24 | return amount_; 25 | } 26 | 27 | function withdrawAll() external { 28 | uint256 amount = token.balanceOf(address(this)); 29 | token.transfer(msg.sender, amount); 30 | } 31 | 32 | function estimatedTotalAssets() 33 | external 34 | view 35 | returns (uint256 totalUnderlyingAssets_) 36 | { 37 | return token.balanceOf(address(this)); 38 | } 39 | 40 | // stores balance in this contract 41 | function invest() external { 42 | emit Invested(token.balanceOf(address(this))); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/mocks/NonMintableToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.13; 2 | 3 | import "solmate/tokens/ERC20.sol"; 4 | 5 | contract NonMintableToken is ERC20 { 6 | // this is a mock token used in tests, other projects' token to be used here 7 | constructor( 8 | string memory name_, 9 | string memory symbol_, 10 | uint8 decimals_, 11 | uint256 totalSupply_ 12 | ) ERC20(name_, symbol_, decimals_) { 13 | _mint(msg.sender, totalSupply_); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/mocks/hooks/MockYieldBridgeHook.sol: -------------------------------------------------------------------------------- 1 | // // // SPDX-License-Identifier: GPL-3.0-only 2 | pragma solidity 0.8.13; 3 | 4 | import "../../../contracts/hooks/Vault_YieldLimitExecHook.sol"; 5 | 6 | contract MockYieldBridgeHook is Vault_YieldLimitExecHook { 7 | constructor( 8 | uint256 debtRatio_, 9 | uint128 rebalanceDelay_, 10 | address strategy_, 11 | address underlyingAsset_, 12 | address controller_, 13 | address executionHelper_ 14 | ) 15 | Vault_YieldLimitExecHook( 16 | debtRatio_, 17 | rebalanceDelay_, 18 | strategy_, 19 | underlyingAsset_, 20 | controller_, 21 | executionHelper_, 22 | false 23 | ) 24 | {} 25 | 26 | function updateStorage( 27 | uint256 totalIdle_, 28 | uint256 totalDebt_, 29 | uint256 totalLockedInStrategy_ 30 | ) external { 31 | totalIdle_ = totalIdle; 32 | totalDebt_ = totalDebt; 33 | totalLockedInStrategy_ = totalLockedInStrategy; 34 | lastRebalanceTimestamp = uint128(block.timestamp); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/mocks/hooks/MockYieldTokenHook.sol: -------------------------------------------------------------------------------- 1 | // // // SPDX-License-Identifier: GPL-3.0-only 2 | pragma solidity 0.8.13; 3 | 4 | import "../../../contracts/hooks/Controller_YieldLimitExecHook.sol"; 5 | 6 | contract MockYieldTokenHook is Controller_YieldLimitExecHook { 7 | constructor( 8 | address underlyingAsset_, 9 | address controller_, 10 | address executionHelper_ 11 | ) 12 | Controller_YieldLimitExecHook( 13 | underlyingAsset_, 14 | controller_, 15 | executionHelper_ 16 | ) 17 | {} 18 | 19 | function updateSiblingYield(uint256 poolId_, uint256 yield_) external { 20 | poolLockedAmounts[poolId_] = yield_; 21 | } 22 | 23 | function updateTotalYield(uint256 yield_) external { 24 | totalUnderlyingAssets = yield_; 25 | yieldToken__.updateTotalUnderlyingAssets(yield_); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/testBridge.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.13; 2 | import "forge-std/Test.sol"; 3 | import "forge-std/console.sol"; 4 | 5 | import "../contracts/bridge/Controller.sol"; 6 | import "../contracts/bridge/Vault.sol"; 7 | 8 | contract TestInbound is Test { 9 | Controller public controller; 10 | Vault public vault; 11 | uint256 fork; 12 | address constant user = 0x44A44837894B5eDC2Bde64567FC62599b3b88F4C; 13 | address constant _connector = 0x0f7d2F0b5C6973cC378ceD768bbb54d75B48a461; 14 | address constant hub = 0x70659628aCd497ee492b9D5fFe3d6A0a9B60Ec82; 15 | 16 | function setUp() external { 17 | // fork = vm.createFork( 18 | // "https://l2-aevo-testnet-k1zx5a2ajj.t.conduit.xyz/" 19 | // ); 20 | 21 | vault = Vault(hub); 22 | } 23 | 24 | // function testBridgeMsg() external { 25 | // vm.selectFork(fork); 26 | // vm.prank(user); 27 | // vault.bridge( 28 | // address(user), 29 | // 0, 30 | // 500000, 31 | // _connector, 32 | // new bytes(0), 33 | // new bytes(0) 34 | // ); 35 | // } 36 | } 37 | -------------------------------------------------------------------------------- /test/testInbound.t.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.8.13; 2 | import "forge-std/Test.sol"; 3 | import "forge-std/console.sol"; 4 | 5 | import "../contracts/bridge/Controller.sol"; 6 | 7 | contract TestInbound is Test { 8 | Controller public controller; 9 | uint256 fork; 10 | address constant _connector = 0x17DF75CA38a39ba65B68ed935A86D1D61BB46c80; 11 | 12 | function setUp() external { 13 | fork = vm.createFork( 14 | "https://l2-aevo-testnet-k1zx5a2ajj.t.conduit.xyz/" 15 | ); 16 | controller = Controller(0x0FFee9dBEC6cd9C0dcB851c9A53e38104aAadbCD); 17 | } 18 | 19 | // function testInbound() external { 20 | // vm.selectFork(fork); 21 | // vm.prank(_connector); 22 | // controller.receiveInbound( 23 | // uint32(0x00AA37DC), 24 | // bytes( 25 | // hex"00000000000000000000000044a44837894b5edc2bde64567fc62599b3b88f4c000000000000000000000000000000000000000000000000000000000000000000aa37dc17df75ca38a39ba65b68ed935a86d1d61bb46c80000000000000005a00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000" 26 | // ) 27 | // ); 28 | // } 29 | } 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "strict": false, 6 | "esModuleInterop": true, 7 | "outDir": "dist", 8 | "declaration": true, 9 | "resolveJsonModule": true 10 | }, 11 | "include": ["./src", "./script", "./hardhat.config.ts"], 12 | "files": ["./hardhat.config.ts"] 13 | } 14 | --------------------------------------------------------------------------------