Skip to content

DEVREL-126 feat: validate Solana admin address for delegate/owner when wiring - #1538

Merged
nazreen merged 20 commits into
mainfrom
codex/add-solana-contract-owner/delegate-check
Jul 16, 2025
Merged

DEVREL-126 feat: validate Solana admin address for delegate/owner when wiring#1538
nazreen merged 20 commits into
mainfrom
codex/add-solana-contract-owner/delegate-check

Conversation

@nazreen

@nazreen nazreen commented May 30, 2025

Copy link
Copy Markdown
Contributor

Summary

  • for Solana, we expect the owner or delegate address to be an on curve address or a Squads vault address (and not the multisig account address)
  • however, right now we don't have any checks to enforce the above
  • this PR introduces those checks

Changes

  • Introduced in packages/devtools-solana a helper to ensure an address is not a Multisig Account address
  • used this new helper in setOwner and setDelegate of the oft sdk in packages/ua-devtools-solana

Testing

Init an oft-solana example.

For all scenarios, you can run the following to go through deployment of a Sepolia and Solana OFT, up until full wiring. Then, (in isolation) you can alter only the owner value with the value being tested and rerun the wiring task.

export PROGRAM_ID=GCAg4xufdyBPTAzKdGnthbMUAV4ex9LdTkUHnADUcwP5
pnpm hardhat lz:oft:solana:create --eid 40168 --program-id $PROGRAM_ID --only-oft-store true --amount 100000000000

pnpm hardhat --network sepolia-testnet lz:deploy --tags MyOFT 


npx hardhat lz:oft:solana:init-config --oapp-config layerzero.config.ts 
npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts

Technically, you don't need to follow through with submitting the wiring transactions. This saves you time to test all scenarios quickly. You can still choose to preview the transaction that does not trip up an error.

Scenario: delegate is a regular address

in the LZ Config, update the delegate or owner value to a regular address

        {
            contract: solanaContract,
            config: {
                delegate: 'C25HqKaTzRqMPnMaeNXoEgZeXm9skUheqF7anfMT57XP',
            },
        },

expected: no errors

info:    There is 1 transaction required to configure the OApp
? Would you like to preview the transactions before continuing? › (Y/n)

Scenario: delegate is a Squads vault address

in the LZ Config, update the delegate or owner value to a Squads vault address

        {
            contract: solanaContract,
            config: {
                delegate: '9x3vKSwioT85mPwWFrdR4ZXQoWV2KRyw6EWbWDYeBWCc',
            },
        },

expected: no errors

Scenario: delegate is a Squads Multisig Account address

in the LZ Config, update the delegate or owner value to a Squads Multisig Account address

        {
            contract: solanaContract,
            config: {
                delegate: '59jdDuB6khhBf9nwwyJfwGXPeEF2mxTMbQusNXGAXjff',
            },
        },

expected: error

Error: SOLANA_OWNER_OR_DELEGATE_MULTISIG_ACCOUNT
Fix suggestion: The owner or delegate of the Solana OApp must not be the Squads multisig account address.
Elaboration: If you intend to use Squads Multisig, ensure that you are providing a Squads Vault address as the owner or delegate of the OApp. The Squads Multisig account address cannot be the owner or delegate.

Scenario: owner is...

You can repeat the above scenarios with the same set of addresses.

Remember however that to apply ownership change, you have to run a different command:

npx hardhat lz:ownable:transfer-ownership --oapp-config layerzero.config.ts

Example DebugLogger output in terminal if setting to Multisig Address:

Error: SOLANA_OWNER_OR_DELEGATE_MULTISIG_ACCOUNT
Fix suggestion: The owner or delegate of the Solana OApp must not be the Squads multisig account address.
Elaboration: If you intend to use Squads Multisig, ensure that you are providing a Squads Vault address as the owner or delegate of the OApp. The Squads Multisig account address cannot be the owner or delegate.

Proof of Tests

I verified that owner should be a Vault Address while the --multisig-key param that is passed in when running the wiring task should be the Multisig Account Address. This is a setPeerConfig (the only change was updating the enforced options gas amount) transaction in which I execute a transaction proposed via running wiring with --multisig-key: https://solscan.io/tx/3YvaGtczqoCpDWStcnVoBrSmyAYEp3c9TPeTh9dNaZMfWAZe3RBQNtrGJpyy2cC2uzDWE8VvCLfqDTZHgfowWnPA?cluster=devnet

I then updated the same Solana OFT to have the owner be the Multisig Account Address (temporarily reverted to version of ua-devtools-solana that does not implement the assertion)

I then modified the LZ config to change the delegate (which is something only the owner can do). The vault transaction was created successfully (wiring task ended successfully) but it couldn't be Executed:

Screenshot 2025-06-24 at 6 16 00 PM

At this point, the delegate was still the vault address. Surprisingly, a transaction to update the enforced options (which to my understanding only requires the delegate) also couldn't be executed.

Then, I attempted to change the owner back to the vault address. But it (expectedly) errored when it came to execution via the vault. Same as above screenshot.

@socket-security

socket-security Bot commented Jun 19, 2025

Copy link
Copy Markdown

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

@nazreen nazreen changed the title Validate Solana admin addresses in oapp config feat: validate Solana admin address for delegate/owner when wiring Jun 20, 2025
@socket-security

socket-security Bot commented Jun 23, 2025

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​solana-developers/​helpers@​2.8.09810010085100

View full report

@nazreen
nazreen marked this pull request as ready for review June 23, 2025 23:46
@nazreen nazreen changed the title feat: validate Solana admin address for delegate/owner when wiring DEVREL-126 feat: validate Solana admin address for delegate/owner when wiring Jun 23, 2025
@nazreen
nazreen requested review from DanL0 and EWCunha June 24, 2025 14:38
@nazreen
nazreen requested a review from Copilot July 3, 2025 20:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enforces that owner and delegate addresses for Solana wiring are either on-curve addresses or Squads vault addresses and not Squads multisig account addresses. It introduces a validation helper, wires it into the OFT SDK, and adds corresponding error messages.

  • Added assertValidSolanaAdmin helper and integrated validation in setOwner/setDelegate
  • Extended error codes and fix suggestions in the debug logger for Solana admin validation
  • Exported new address utilities and bumped TypeScript target

Reviewed Changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/ua-devtools/tsconfig.json Bumped target to ES2020
packages/ua-devtools-solana/src/oft/sdk.ts Imported validation helper and added admin address checks
packages/io-devtools/src/stdio/debugLogger.ts Added Solana-specific error codes and fixes
packages/devtools-solana/src/common/index.ts Exported new addresses module
packages/devtools-solana/src/common/addresses.ts Implemented isOnCurveAddress, isPossibleSquadsVault, and assertValidSolanaAdmin
packages/devtools-solana/package.json Pinned @solana-developers/helpers to 2.8.0
packages/devtools-solana/DEVELOPMENT.md Documented pin for @solana-developers/helpers
.changeset/*.md Bumped versions and described the new validation behavior
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (2)

packages/devtools-solana/src/common/addresses.ts:30

  • [nitpick] Consider adding unit tests for assertValidSolanaAdmin to cover malformed addresses, multisig account rejection, on-curve addresses, and vault PDAs.
export async function assertValidSolanaAdmin(connection: Connection, address: string): Promise<void> {

packages/devtools-solana/src/common/addresses.ts:3

  • The @sqds/multisig package is consumed here but not declared in package.json dependencies; please add it so the module resolves correctly.
import { PROGRAM_ID as SQUADS_PROGRAM_ID } from '@sqds/multisig'

Comment thread packages/io-devtools/src/stdio/debugLogger.ts Outdated
Comment thread packages/devtools-solana/src/common/addresses.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@nazreen
nazreen merged commit 0aff8fb into main Jul 16, 2025
11 checks passed
@nazreen
nazreen deleted the codex/add-solana-contract-owner/delegate-check branch July 16, 2025 20:39
shankars99 pushed a commit that referenced this pull request Jul 20, 2025
…n wiring (#1538)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
mattsse pushed a commit to mattsse/devtools that referenced this pull request Aug 12, 2025
…n wiring (LayerZero-Labs#1538)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants