package testcontracts import ( "context" "fmt" "math/big" "github.com/brianvoe/gofakeit/v6" "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/testbridge" "github.com/synapsecns/sanguine/services/explorer/contracts/bridge/testbridgev1" "github.com/synapsecns/sanguine/services/explorer/contracts/bridgeconfig" "github.com/synapsecns/sanguine/services/explorer/contracts/cctp/testcctp" "github.com/synapsecns/sanguine/services/explorer/contracts/fastbridge/testfastbridge" "github.com/synapsecns/sanguine/services/explorer/contracts/messagebus/testmessagebus" "github.com/synapsecns/sanguine/services/explorer/contracts/metaswap/testmetaswap" "github.com/synapsecns/sanguine/services/explorer/contracts/swap/testswap" "github.com/synapsecns/sanguine/services/explorer/testutil" ) // TestSynapseBridgeDeployer is the type of the test bridge deployer. type TestSynapseBridgeDeployer struct { *deployer.BaseDeployer } // TestSynapseBridgeV1Deployer is the type of the test bridge deployer. type TestSynapseBridgeV1Deployer struct { *deployer.BaseDeployer } // TestSwapFlashLoanDeployer is the type of the test swap deployer. type TestSwapFlashLoanDeployer struct { *deployer.BaseDeployer } // BridgeConfigV3Deployer is the type of the bridge config v3 deployer. type BridgeConfigV3Deployer struct { *deployer.BaseDeployer } // TestMessageBusUpgradeableDeployer is the type of the test message bus upgradeable deployer. type TestMessageBusUpgradeableDeployer struct { *deployer.BaseDeployer } // TestMetaSwapDeployer is the type of the test meta swap deployer. type TestMetaSwapDeployer struct { *deployer.BaseDeployer } // TestCCTPDeployer is the type of the test cctp deployer. type TestCCTPDeployer struct { *deployer.BaseDeployer } // TestFastBridgeDeployer is the type of the test rfq (fastbridge) deployer. type TestFastBridgeDeployer struct { *deployer.BaseDeployer } // NewTestSynapseBridgeDeployer creates a new test bridge deployer. func NewTestSynapseBridgeDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return TestSynapseBridgeDeployer{deployer.NewSimpleDeployer(registry, backend, TestSynapseBridgeType)} } // NewTestSynapseBridgeV1Deployer creates a new test bridge v1 deployer. func NewTestSynapseBridgeV1Deployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return TestSynapseBridgeV1Deployer{deployer.NewSimpleDeployer(registry, backend, TestSynapseBridgeV1Type)} } // NewTestSwapFlashLoanDeployer creates a new test swap deployer. func NewTestSwapFlashLoanDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return TestSwapFlashLoanDeployer{deployer.NewSimpleDeployer(registry, backend, TestSwapFlashLoanType)} } // NewBridgeConfigV3Deployer creates a new bridge config v2 client. func NewBridgeConfigV3Deployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return BridgeConfigV3Deployer{deployer.NewSimpleDeployer(registry, backend, testutil.BridgeConfigTypeV3)} } // NewTestMessageBusDeployer creates a new test message bus deployer. func NewTestMessageBusDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return TestMessageBusUpgradeableDeployer{deployer.NewSimpleDeployer(registry, backend, TestMessageBusType)} } // NewTestMetaSwapDeployer creates a new test meta swap deployer. func NewTestMetaSwapDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return TestMetaSwapDeployer{deployer.NewSimpleDeployer(registry, backend, TestMetaSwapType)} } // NewTestCCTPDeployer creates a new test cctp client. func NewTestCCTPDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return TestCCTPDeployer{deployer.NewSimpleDeployer(registry, backend, TestCCTPType)} } // NewTestFastBridgeDeployer creates a new test rfq (fastbridge) client. func NewTestFastBridgeDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer { return TestFastBridgeDeployer{deployer.NewSimpleDeployer(registry, backend, TestFastBridgeType)} } // Deploy deploys a test bridge. func (t TestSynapseBridgeDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) { return t.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) { return testbridge.DeployTestSynapseBridge(transactOps, backend) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testbridge.NewTestBridgeRef(address, backend) }) } // Deploy deploys a test bridge v1. func (t TestSynapseBridgeV1Deployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) { return t.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) { return testbridgev1.DeployTestSynapseBridgeV1(transactOps, backend) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testbridgev1.NewTestBridgeV1Ref(address, backend) }) } // Deploy deploys a test swap. func (t TestSwapFlashLoanDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) { return t.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) { return testswap.DeployTestSwapFlashLoan(transactOps, backend) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testswap.NewTestSwapRef(address, backend) }) } // Deploy deploys bridge config v3 // //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 a test message bus contract. func (t TestMessageBusUpgradeableDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) { return t.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) { return testmessagebus.DeployTestMessageBusUpgradeable(transactOps, backend) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testmessagebus.NewTestMessageBusRef(address, backend) }) } // Deploy deploys a test meta swap contract. func (t TestMetaSwapDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) { return t.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) { return testmetaswap.DeployTestMetaSwap(transactOps, backend) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testmetaswap.NewTestMetaSwapRef(address, backend) }) } // Deploy deploys CCTP contract // //nolint:dupl func (n TestCCTPDeployer) 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 testcctp.DeployMessageTransmitter(transactOps, backend) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testcctp.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 testcctp.DeployTestSynapseCCTP(transactOps, backend, tokenMessengerContract.Address(), owner) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testcctp.NewTestCCTPRef(address, backend) }) } // Deploy deploys FastBridge contract // //nolint:dupl func (n TestFastBridgeDeployer) 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 testfastbridge.DeployTestFastBridge(transactOps, backend, owner) }, func(address common.Address, backend bind.ContractBackend) (interface{}, error) { return testfastbridge.NewTestFastBridgeRef(address, backend) }) } var _ deployer.ContractDeployer = &TestSynapseBridgeDeployer{} var _ deployer.ContractDeployer = &TestSynapseBridgeV1Deployer{} var _ deployer.ContractDeployer = &TestSwapFlashLoanDeployer{} var _ deployer.ContractDeployer = &BridgeConfigV3Deployer{} var _ deployer.ContractDeployer = &TestMessageBusUpgradeableDeployer{} var _ deployer.ContractDeployer = &TestMetaSwapDeployer{} var _ deployer.ContractDeployer = &TestCCTPDeployer{} var _ deployer.ContractDeployer = &TestFastBridgeDeployer{}