Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions deployment/changesets/cs_add_new_fee_token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package changesets

import (
"fmt"
"math/big"

cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
"github.com/smartcontractkit/chainlink-deployments-framework/operations"

"github.com/smartcontractkit/chainlink-sui/bindings/bind"
"github.com/smartcontractkit/chainlink-sui/deployment"
sui_ops "github.com/smartcontractkit/chainlink-sui/deployment/ops"
ccipops "github.com/smartcontractkit/chainlink-sui/deployment/ops/ccip"
)

type NewFeeTokenConfig struct {
SuiChainSelector uint64
FeeTokensToRemove []string
FeeTokensToAdd []string // should be the objectID

// update price
SourceUsdPerToken []*big.Int

// premium multiplier wei per eth
PremiumMultiplierWeiPerEth []uint64
}

// ConnectSuiToEVM connects sui chain with EVM
type NewFeeToken struct{}

var _ cldf.ChangeSetV2[NewFeeTokenConfig] = NewFeeToken{}

// Apply implements deployment.ChangeSetV2.
func (d NewFeeToken) Apply(e cldf.Environment, config NewFeeTokenConfig) (cldf.ChangesetOutput, error) {
ab := cldf.NewMemoryAddressBook()
state, err := deployment.LoadOnchainStatesui(e)
if err != nil {
return cldf.ChangesetOutput{}, err
}

seqReports := make([]operations.Report[any, any], 0)

suiChains := e.BlockChains.SuiChains()
suiChain := suiChains[config.SuiChainSelector]

deps := sui_ops.OpTxDeps{
Client: suiChain.Client,
Signer: suiChain.Signer,
GetCallOpts: func() *bind.CallOpts {
b := uint64(400_000_000)
return &bind.CallOpts{
WaitForExecution: true,
GasBudget: &b,
}
},
SuiRPC: suiChain.URL,
}

// Run ApplyFeeTokenUpdate Operation
applyFeeTokenUpdateOP, err := operations.ExecuteOperation(e.OperationsBundle, ccipops.FeeQuoterApplyFeeTokenUpdatesOp, deps, ccipops.FeeQuoterApplyFeeTokenUpdatesInput{
CCIPPackageId: state[suiChain.Selector].CCIPAddress,
StateObjectId: state[suiChain.Selector].CCIPObjectRef,
OwnerCapObjectId: state[suiChain.Selector].CCIPOwnerCapObjectId,
FeeTokensToRemove: config.FeeTokensToRemove,
FeeTokensToAdd: config.FeeTokensToAdd,
})
if err != nil {
return cldf.ChangesetOutput{}, fmt.Errorf("failed to register receiver for Sui chain %d: %w", config.SuiChainSelector, err)
}

seqReports = append(seqReports, []operations.Report[any, any]{applyFeeTokenUpdateOP.ToGenericReport()}...)

// Run ApplyPremiumMultiplier
applyPremiumMultiplierOP, err := operations.ExecuteOperation(e.OperationsBundle, ccipops.FeeQuoterApplyPremiumMultiplierWeiPerEthUpdatesOp, deps, ccipops.FeeQuoterApplyPremiumMultiplierWeiPerEthUpdatesInput{
CCIPPackageId: state[suiChain.Selector].CCIPAddress,
StateObjectId: state[suiChain.Selector].CCIPObjectRef,
OwnerCapObjectId: state[suiChain.Selector].CCIPOwnerCapObjectId,
Tokens: config.FeeTokensToAdd,
PremiumMultiplierWeiPerEth: config.PremiumMultiplierWeiPerEth,
})
if err != nil {
return cldf.ChangesetOutput{}, fmt.Errorf("failed to register receiver for Sui chain %d: %w", config.SuiChainSelector, err)
}

seqReports = append(seqReports, []operations.Report[any, any]{applyPremiumMultiplierOP.ToGenericReport()}...)

return cldf.ChangesetOutput{
AddressBook: ab,
Reports: seqReports,
}, nil
}

// VerifyPreconditions implements deployment.ChangeSetV2.
func (d NewFeeToken) VerifyPreconditions(e cldf.Environment, config NewFeeTokenConfig) error {
return nil
}
42 changes: 41 additions & 1 deletion deployment/ops/ccip/op_fee_quoter.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,13 @@ var FeeQuoterApplyPremiumMultiplierWeiPerEthUpdatesOp = cld_ops.NewOperation(
type FeeQuoterUpdateTokenPricesInput struct {
CCIPPackageId string
CCIPObjectRef string
FeeQuoterCapId string
SourceTokens []string
SourceUsdPerToken []*big.Int
GasDestChainSelectors []uint64
GasUsdPerUnitGas []*big.Int

FeeQuoterCapId string // optional: only provide if you're running direct UpdateTokenPrice
OwnerCapId string // optional: only provide if you're running UpdateTokenPricesWithOwnerCap
}

var updateTokenPrices = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input FeeQuoterUpdateTokenPricesInput) (output sui_ops.OpTxResult[NoObjects], err error) {
Expand Down Expand Up @@ -446,6 +448,44 @@ var FeeQuoterUpdateTokenPricesOp = cld_ops.NewOperation(
updateTokenPrices,
)

var updateTokenPricesWithOwnerCap = func(b cld_ops.Bundle, deps sui_ops.OpTxDeps, input FeeQuoterUpdateTokenPricesInput) (output sui_ops.OpTxResult[NoObjects], err error) {
contract, err := module_fee_quoter.NewFeeQuoter(input.CCIPPackageId, deps.Client)
if err != nil {
return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to create fee quoter contract: %w", err)
}

opts := deps.GetCallOpts()
opts.Signer = deps.Signer
fmt.Println("INPUTSS: ", input)
tx, err := contract.UpdatePricesWithOwnerCap(
b.GetContext(),
opts,
bind.Object{Id: input.CCIPObjectRef},
bind.Object{Id: input.OwnerCapId},
bind.Object{Id: "0x6"}, // Clock object
input.SourceTokens,
input.SourceUsdPerToken,
input.GasDestChainSelectors,
input.GasUsdPerUnitGas,
)

if err != nil {
return sui_ops.OpTxResult[NoObjects]{}, fmt.Errorf("failed to execute updateTokenPrices on SUI: %w", err)
}

return sui_ops.OpTxResult[NoObjects]{
Digest: tx.Digest,
PackageId: input.CCIPPackageId,
}, err
}

var FeeQuoterUpdateTokenPricesWithOwnerCapOp = cld_ops.NewOperation(
sui_ops.NewSuiOperationName("ccip", "fee_quoter", "update_prices_with_owner_cap"),
semver.MustParse("0.1.0"),
"Apply update prices with ownerCap in CCIP Fee Quoter contract",
updateTokenPricesWithOwnerCap,
)

// FEE QUOTER -- new_fee_quoter_cap
type NewFeeQuoterCapObjects struct {
FeeQuoterCapObjectId string
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/aptos-labs/aptos-go-sdk v1.7.1-0.20250602153733-bb1facae1d43
github.com/aptos-labs/tree-sitter-move-on-aptos v0.0.0-20250321090037-c820eb4716e1
github.com/block-vision/sui-go-sdk v1.1.2
github.com/ethereum/go-ethereum v1.15.7
github.com/ethereum/go-ethereum v1.16.2
github.com/google/uuid v1.6.0
github.com/hashicorp/go-plugin v1.6.3
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum/go-ethereum v1.15.7 h1:vm1XXruZVnqtODBgqFaTclzP0xAvCvQIDKyFNUA1JpY=
github.com/ethereum/go-ethereum v1.15.7/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0=
github.com/ethereum/go-ethereum v1.16.2 h1:VDHqj86DaQiMpnMgc7l0rwZTg0FRmlz74yupSG5SnzI=
github.com/ethereum/go-ethereum v1.16.2/go.mod h1:X5CIOyo8SuK1Q5GnaEizQVLHT/DfsiGWuNeVdQcEMNA=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
Expand Down
Loading