synapsecns/sanguine

View on GitHub
services/explorer/testutil/deployers.go

Summary

Maintainability
D
2 days
Test Coverage
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{}