services/explorer/testutil/deployers.go
package testutil
import (
"context"
"fmt"
"math/big"
"github.com/brianvoe/gofakeit/v6"
"github.com/synapsecns/sanguine/services/explorer/contracts/fastbridge"
"github.com/synapsecns/sanguine/services/explorer/contracts/metaswap"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/synapsecns/sanguine/ethergo/backends"
"github.com/synapsecns/sanguine/ethergo/contracts"
"github.com/synapsecns/sanguine/ethergo/deployer"
"github.com/synapsecns/sanguine/services/explorer/contracts/bridge"
"github.com/synapsecns/sanguine/services/explorer/contracts/bridge/bridgev1"
"github.com/synapsecns/sanguine/services/explorer/contracts/bridgeconfig"
"github.com/synapsecns/sanguine/services/explorer/contracts/cctp"
"github.com/synapsecns/sanguine/services/explorer/contracts/messagebus"
"github.com/synapsecns/sanguine/services/explorer/contracts/swap"
)
// BridgeConfigV3Deployer is the type of the bridge config v3 deployer.
type BridgeConfigV3Deployer struct {
*deployer.BaseDeployer
}
// SynapseBridgeDeployer is the type of the bridge deployer.
type SynapseBridgeDeployer struct {
*deployer.BaseDeployer
}
// SwapFlashLoanDeployer is the type of the swap flash loan deployer.
type SwapFlashLoanDeployer struct {
*deployer.BaseDeployer
}
// SynapseBridgeV1Deployer is the type of the swap flash loan deployer.
type SynapseBridgeV1Deployer struct {
*deployer.BaseDeployer
}
// MessageBusDeployer is the type of the message bus deployer.
type MessageBusDeployer struct {
*deployer.BaseDeployer
}
// MetaSwapDeployer is the type of the meta swap deployer.
type MetaSwapDeployer struct {
*deployer.BaseDeployer
}
// CCTPDeployer is the type of the cctp deployer.
type CCTPDeployer struct {
*deployer.BaseDeployer
}
// FastBridgeDeployer is the type of the rfq (fastbridge) deployer.
type FastBridgeDeployer struct {
*deployer.BaseDeployer
}
// NewBridgeConfigV3Deployer creates a new bridge config v2 client.
func NewBridgeConfigV3Deployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return BridgeConfigV3Deployer{deployer.NewSimpleDeployer(registry, backend, BridgeConfigTypeV3)}
}
// NewSynapseBridgeDeployer creates a new bridge client.
func NewSynapseBridgeDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return SynapseBridgeDeployer{deployer.NewSimpleDeployer(registry, backend, SynapseBridgeType)}
}
// NewSwapFlashLoanDeployer creates a new flash loan client.
func NewSwapFlashLoanDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return SwapFlashLoanDeployer{deployer.NewSimpleDeployer(registry, backend, SwapFlashLoanType)}
}
// NewSynapseBridgeV1Deployer creates a new bridge v1 client.
func NewSynapseBridgeV1Deployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return SynapseBridgeV1Deployer{deployer.NewSimpleDeployer(registry, backend, SynapseBridgeV1Type)}
}
// NewMessageBusDeployer creates a new message bus client.
func NewMessageBusDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return MessageBusDeployer{deployer.NewSimpleDeployer(registry, backend, MessageBusType)}
}
// NewMetaSwapDeployer creates a new meta swap client.
func NewMetaSwapDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return MetaSwapDeployer{deployer.NewSimpleDeployer(registry, backend, MetaSwapType)}
}
// NewCCTPDeployer creates a new cctp client.
func NewCCTPDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return CCTPDeployer{deployer.NewSimpleDeployer(registry, backend, CCTPType)}
}
// NewFastBridgeDeployer creates a new fastbridge client.
func NewFastBridgeDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return FastBridgeDeployer{deployer.NewSimpleDeployer(registry, backend, FastBridgeType)}
}
// Deploy deploys bridge config v3 contract
//
//nolint:dupl
func (n BridgeConfigV3Deployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
deployAddress, tx, handler, err := bridgeconfig.DeployBridgeConfigV3(transactOps, backend)
if err != nil {
return common.Address{}, nil, nil, fmt.Errorf("could not deploy bridge config: %w", err)
}
// wait for confirm, we need this to grant role
n.Backend().WaitForConfirmation(ctx, tx)
// https://github.com/synapsecns/synapse-contracts/pull/13 introduces a breaking change where the BRIDGEMANAGER_ROLE is not automatically granted to the
// deployer. We fix that here by granting the role to the owner
bridgeManagerRole, err := handler.BRIDGEMANAGERROLE(&bind.CallOpts{Context: ctx})
if err != nil {
return common.Address{}, nil, nil, fmt.Errorf("could not get bridge manager role: %w", err)
}
auth := n.Backend().GetTxContext(ctx, &transactOps.From)
// grant the role
grantTx, err := handler.GrantRole(auth.TransactOpts, bridgeManagerRole, auth.From)
if err != nil {
return common.Address{}, nil, nil, fmt.Errorf("could not grant bridge manager role: %w", err)
}
n.Backend().WaitForConfirmation(ctx, grantTx)
return deployAddress, tx, handler, nil
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return bridgeconfig.NewBridgeConfigRef(address, backend)
})
}
// Deploy deploys Synapse Bridge contract
//
//nolint:dupl
func (n SynapseBridgeDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return bridge.DeploySynapseBridge(transactOps, backend)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return bridge.NewBridgeRef(address, backend)
})
}
// Deploy deploys Synapse Bridge V1 contract
//
//nolint:dupl
func (n SynapseBridgeV1Deployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return bridgev1.DeploySynapseBridge(transactOps, backend)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return bridgev1.NewBridgeRef(address, backend)
})
}
// Deploy deploys Swap Flash Loan contract
//
//nolint:dupl
func (n SwapFlashLoanDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return swap.DeploySwapFlashLoan(transactOps, backend)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return swap.NewSwapRef(address, backend)
})
}
// Deploy deploys Message Bus contract
//
//nolint:dupl
func (n MessageBusDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return messagebus.DeployMessageBusUpgradeable(transactOps, backend)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return messagebus.NewMessageBusRef(address, backend)
})
}
// Deploy deploys Meta Swap contract
//
//nolint:dupl
func (n MetaSwapDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return metaswap.DeployMetaSwap(transactOps, backend)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return metaswap.NewMetaSwapRef(address, backend)
})
}
// Deploy deploys CCTP contract
//
//nolint:dupl
func (n CCTPDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
tokenMessengerContract, err := n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return cctp.DeployMessageTransmitter(transactOps, backend)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return cctp.NewMessageTransmitter(address, backend)
})
if err != nil {
return nil, fmt.Errorf("failed to deploy tokenMessengerContract %w", err)
}
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
// Create mock owner
owner := common.BigToAddress(big.NewInt(gofakeit.Int64()))
return cctp.DeploySynapseCCTP(transactOps, backend, tokenMessengerContract.Address(), owner)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return cctp.NewCCTPRef(address, backend)
})
}
// Deploy deploys RFQ contract
//
//nolint:dupl
func (n FastBridgeDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return n.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
// Create mock owner
owner := common.BigToAddress(big.NewInt(gofakeit.Int64()))
return fastbridge.DeployFastBridge(transactOps, backend, owner)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return fastbridge.NewFastBridgeRef(address, backend)
})
}
var _ deployer.ContractDeployer = &BridgeConfigV3Deployer{}
var _ deployer.ContractDeployer = &SynapseBridgeDeployer{}
var _ deployer.ContractDeployer = &SwapFlashLoanDeployer{}
var _ deployer.ContractDeployer = &SynapseBridgeV1Deployer{}
var _ deployer.ContractDeployer = &MetaSwapDeployer{}
var _ deployer.ContractDeployer = &CCTPDeployer{}
var _ deployer.ContractDeployer = &FastBridgeDeployer{}