Deposit Tokens

Deposit Tokens

Acquire Tokens

At the time of writing, Exocore's testnet (exocoretestnet_233-6) supports exoETH and wstETH on Sepolia for staking. To participate in consensus, validators don't need both of these tokens; only one token type is sufficient.

  • ETH on Sepolia can be obtained from faucets provided by Alchemy or Infura.

    • Purpose: ETH is used to pay for gas on the Ethereum testnet.

  • exoETH on Sepolia can be obtained from the faucet.

    • Purpose: exoETH is used for staking on Exocore testnet.

  • wstETH on Sepolia can be obtained by sending Sepolia ETH to the wstETH address 0xB82381A3fBD3FaFA77B3a7bE693342618240067b.

    • Purpose: wstETH is Lido’s liquid staking token and is used for restaking.

  • exo, which is the native token on Exocore, can be obtained from the testnet faucet. Similar to ETH and wei, the smaller unit of exo is hua such that 1 exo = 1e18 hua.

    • Purpose: exo is used to pay for gas on Exocore.

Among the tokens listed above, only exo is present on the Exocore chain while others live on Sepolia.

Deposit Tokens

The contract which accepts deposits is currently deployed on Ethereum, which means the Ethereum private key ($ETH_PRIVATE_KEY) is needed.

## Script constants
EXO_ETH_ADDR=0x83E6850591425e3C1E263c054f4466838B9Bd9e4
WST_ETH_ADDR=0xB82381A3fBD3FaFA77B3a7bE693342618240067b
GATEWAY_ADDR=0xDf9caDCfb027d9f6264Ecd5eAEc839a8335d8520

## User choices
# Enter your Ethereum testnet private key
ETH_PRIVATE_KEY=0xabcde.....
# Enter the address corresponding to the key
ETH_ADDRESS=0x123....
# Obtain the token as described above, and choose the one you intend to deposit.
# For most validators, this default works. However, others can still bring in 
# their `wstETH` (or another supported token) to participate.
TOKEN=$EXO_ETH_ADDR
# Quantity of token to deposit (without the 1e18 multiplier)
# Decimal values are supported
QUANTITY=0.5
# Endpoint for Ethereum RPC
ETHEREUM_RPC_URL=https://rpc.ankr.com/eth_sepolia

# Approve the deposit by Vault
VAULT_ADDR=$(cast call --rpc-url $ETHEREUM_RPC_URL $GATEWAY_ADDR "tokenToVault(address) returns (address)" $TOKEN)
cast send --rpc-url $ETHEREUM_RPC_URL \
    $TOKEN \
    "approve(address,uint256)" \
    $VAULT_ADDR \
    "$(cast maxu)" \
    --private-key $ETH_PRIVATE_KEY

BOOTSTRAPPED=$(cast call --rpc-url $ETHEREUM_RPC_URL $GATEWAY_ADDR "bootstrapped() returns (bool)")
if [ "$BOOTSTRAPPED" = "true" ]; then
    # Generate the LZ messsage to calculate the fees
    DEPOSIT_PREFIX="0x00"
    TOKEN_B32=$(cast 2b $TOKEN)
    ETH_ADDRESS_B32=$(cast 2b $ETH_ADDRESS)
    QUANTITY_B32=$(printf "%064s" $(cast 2h $(cast 2w $QUANTITY) | cut -c3-) | tr ' ' '0') # left padding
    LZ_MESSAGE=$(cast ch $DEPOSIT_PREFIX $TOKEN_B32 $ETH_ADDRESS_B32 $QUANTITY_B32)
    VALUE=$(cast call --rpc-url $ETHEREUM_RPC_URL $GATEWAY_ADDR "quote(bytes)" $LZ_MESSAGE)
else
    # No fees
    VALUE=0
fi

# Execute the transaction
cast send --rpc-url $ETHEREUM_RPC_URL \
    $GATEWAY_ADDR \
    "deposit(address,uint256)" \
    $TOKEN \
    $(cast 2w $QUANTITY) \
    --private-key $ETH_PRIVATE_KEY \
    --value $(cast 2d $VALUE)

The expected output of the commands should look similar to below:

blockHash               0x496b22768c38687dedeaf1f6b3823b0973b25ae90ea961e702f6dd4ba82a980a
blockNumber             6679149

<! -- truncated -->

transactionHash         0x24426c2acf0e6a411961f478bca68a36c12ed0bff3d7206cd1cd7662908d40cf
transactionIndex        84
type                    2
blobGasPrice            
blobGasUsed             
authorizationList       
to                      0x8fc4E764C2C3B0646ba572AEa958fB5724706412

If the above transaction is executed post network launch, LayerZeroScan may be used to check whether the Deposit message, sent from Ethereum to Exocore, was executed on the destination chain successfully. Once it is executed, the deposited amount can be queried from Exocore.

ETH_LZ_ID=40161 # Sepolia, where our $GATEWAY_ADDR lives
STAKER_ID=$(echo "${ETH_ADDRESS}" | tr '[:upper:]' '[:lower:]')_$(printf '0x%x\n' "${ETH_LZ_ID}")
# our public endpoint is available below, but you can use your own node too
EXOCORE_COS_GRPC_URL=https://api-cosmos-grpc.exocore-restaking.com:443
exocored query assets QueStakerAssetInfos \
    $STAKER_ID --node $EXOCORE_COS_GRPC_URL \
    --output json | jq

The expected output of this will represent the quantity of tokens deposited, multiplied by 1e18.

{
  "asset_infos": [
    {
      // the `asset_id` will vary depending on $TOKEN chosen
      // the `_0x9ce1` represents that hex value of the ETH_LZ_ID, a unique ID
      // assigned by LayerZero to the Sepolia network
      "asset_id": "0xb82381a3fbd3fafa77b3a7be693342618240067b_0x9ce1",
      "info": {
        // Represents a quantity of 0.5 * 1e18
        "total_deposit_amount": "500000000000000000",
        // The below amount is "free" as in not deleted to an operator
        "withdrawable_amount": "500000000000000000",
        // The below amount is currently "unbonding"
        "pending_undelegation_amount": "0"
      }
    }
  ]
}

Last updated