Skip to content

Instantly share code, notes, and snippets.

@nazreen
Last active October 13, 2025 14:14
Show Gist options
  • Select an option

  • Save nazreen/ff9e535ba99fd953de7c7b372fbb938c to your computer and use it in GitHub Desktop.

Select an option

Save nazreen/ff9e535ba99fd953de7c7b372fbb938c to your computer and use it in GitHub Desktop.
ApeCoin OFT expansion instructions - EVM pathways

This is instructions set 3 of 3.

Right now the OFT configs are spread across 3 repos:

For context, the Solana OFT repo is pretty much a superset of the EVM only OFT repo. So moving forward, the Solana OFT repo can host the EVM-EVM pathway configs too. I suggest archiving or clearly marking the ape-oft repo to not be used. Link to the ape-solana repo instead.

Consolidate EVM-EVM wiring artifacts (LZ Config and Hardhat Config) into the ape-solana repo

  1. From ape-oft repo, copy contracts/ApeOFT.sol and contracts/ApeOFTAdapter.sol into the ape-solana repo, into the same contracts/ folder. Future EVM OFT deployments can use the ApeOFT.sol in the ape-solana repo.

Note: There is no need to copy over the hardhat.config.ts as the Solana repo already has all the same EVM networks defined for mainnet. Optional: copy over the testnet networks from ape-oft's hardhat.config.ts into ape-solana's hardhat.config.ts's config.networks.

Solana repo - wiring EVM-EVM pathways.

Note: it is recommended for you to execute the txns from the ape-solana instructions https://gist.github.com/nazreen/e8395a10c0ef30df856d5cee396660c3 first so that in this section, you will only be presented with txns for EVM-EVM.

After consolidating the EVM-EVM wiring artifacts, it's time for us to add BNB and Base.

  1. We will now merge in the EVM-EVM pathways configs into the Solana repo's layerzero.config.ts.

1a. In ape-solana's layerzero.config.ts, declare the following:

```
const EVM_TO_ARBITRUM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
  {
      msgType: 1,
      optionType: ExecutorOptionType.LZ_RECEIVE,
      gas: 75000,
      value: 0,
  },
  {
      msgType: 2,
      optionType: ExecutorOptionType.LZ_RECEIVE,
      gas: 75000,
      value: 0,
  },
  {
      msgType: 2,
      optionType: ExecutorOptionType.COMPOSE,
      index: 0,
      gas: 60000,
      value: 0,
  },
]

const EVM_TO_ETHEREUM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
    {
        msgType: 1,
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 170000,
        value: 0,
    },
    {
        msgType: 2,
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 170000,
        value: 0,
    },
    {
        msgType: 2,
        optionType: ExecutorOptionType.COMPOSE,
        index: 0,
        gas: 60000,
        value: 0,
    },
]

const EVM_TO_APE_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
    {
        msgType: 1,
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 75000,
        value: 0,
    },
    {
        msgType: 2,
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 75000,
        value: 0,
    },
    {
        msgType: 2,
        optionType: ExecutorOptionType.COMPOSE,
        index: 0,
        gas: 60000,
        value: 0,
    },
]
```

1b. Add the existing EVM pathways into generateConnectionsConfig's connections array:

```
[
        ethereumContract, // Chain A contract
        arbitrumContract, // Chain B contract
        [['Horizen', 'Polyhedra', 'ABDB', 'LayerZero Labs'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
        [15, 20], // [A to B confirmations, B to A confirmations]
        [EVM_TO_ARBITRUM_ENFORCED_OPTIONS, EVM_TO_ETHEREUM_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
    ],
    [
        ethereumContract, // Chain A contract
        apeContract, // Chain B contract
        [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
        [15, 30], // [A to B confirmations, B to A confirmations]
        [EVM_TO_APE_ENFORCED_OPTIONS, EVM_TO_ETHEREUM_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
    ],
    [
        apeContract, // Chain A contract
        arbitrumContract, // Chain B contract
        [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
        [30, 20], // [A to B confirmations, B to A confirmations]
        [EVM_TO_ARBITRUM_ENFORCED_OPTIONS, EVM_TO_APE_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
    ],
```

1c. Add the new pathways involving Base/BNB into the same connections array (place it at the end):

[
  apeContract, // Chain A contract
  baseContract, // Chain B contract
  [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  [30, 10], // [A to B confirmations, B to A confirmations]
  [TO_BASE_MAINNET_ENFORCED_OPTIONS, TO_APE_MAINNET_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
[
  apeContract, // Chain A contract
  bnbContract, // Chain B contract
  [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  [30, 20], // [A to B confirmations, B to A confirmations]
  [TO_BNB_MAINNET_ENFORCED_OPTIONS, TO_APE_MAINNET_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
[
  arbitrumContract, // Chain A contract
  baseContract, // Chain B contract
  [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  [20, 10], // [A to B confirmations, B to A confirmations]
  [TO_BASE_MAINNET_ENFORCED_OPTIONS, TO_ARBITRUM_MAINNET_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
[
  arbitrumContract, // Chain A contract
  bnbContract, // Chain B contract
  [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  [20, 20], // [A to B confirmations, B to A confirmations]
  [TO_BNB_MAINNET_ENFORCED_OPTIONS, TO_ARBITRUM_MAINNET_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
[
  ethereumContract, // Chain A contract
  baseContract, // Chain B contract
  [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  [15, 10], // [A to B confirmations, B to A confirmations]
  [TO_BASE_MAINNET_ENFORCED_OPTIONS, TO_ETHEREUM_MAINNET_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
[
  ethereumContract, // Chain A contract
  bnbContract, // Chain B contract
  [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  [15, 20], // [A to B confirmations, B to A confirmations]
  [TO_BNB_MAINNET_ENFORCED_OPTIONS, TO_ETHEREUM_MAINNET_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
[
  baseContract, // Chain A contract
  bnbContract, // Chain B contract
  [['LayerZero Labs', 'Horizen'], []], // [ requiredDVN[], [ optionalDVN[], threshold ] ]
  [10, 20], // [A to B confirmations, B to A confirmations]
  [TO_BNB_MAINNET_ENFORCED_OPTIONS, TO_BASE_MAINNET_ENFORCED_OPTIONS], // Chain B enforcedOptions, Chain A enforcedOptions
],
  1. Run the wire command: npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts --multisig-key GPuMML3FeJXTr948CvTwSYANHm74RSW5iUibw5T6vSfa --output-filename evm-evm-wire-txns.json
  • Note: Ensure that there are NO transactions involving ONLY the existing EVM chains (Ape, Arbitrum, Ethereum). As in, a txn that is updating configs for Ethereum-Ape. We do not want to alter existing pathways for now.
  • If you had already executes the txns from the Ape Solana instructions, you should not see any Solana related txns here.
  • 3a. Open evm-evm-wire-txns.json to view the txns that need executing. Execute them via the Safe Multisig UI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment