services/rfq/testutil/deployers.go
package testutil
import (
"context"
"fmt"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/assert"
"github.com/synapsecns/sanguine/ethergo/backends"
"github.com/synapsecns/sanguine/ethergo/contracts"
"github.com/synapsecns/sanguine/ethergo/deployer"
"github.com/synapsecns/sanguine/ethergo/manager"
"github.com/synapsecns/sanguine/services/rfq/contracts/fastbridge"
"github.com/synapsecns/sanguine/services/rfq/contracts/testcontracts/fastbridgemock"
)
// DeployManager wraps DeployManager and allows typed contract handles to be returned.
type DeployManager struct {
*manager.DeployerManager
}
// NewDeployManager creates a new DeployManager.
func NewDeployManager(t *testing.T) *DeployManager {
t.Helper()
parentManager := manager.NewDeployerManager(t, NewFastBridgeDeployer, NewMockERC20Deployer, NewMockFastBridgeDeployer, NewWETH9Deployer, NewUSDTDeployer, NewUSDCDeployer, NewDAIDeployer)
return &DeployManager{parentManager}
}
// MintToAddress mints an equal amount of tokens to an address. Amount is multiplied by decimals to ensure events.
func (d *DeployManager) MintToAddress(ctx context.Context, backend backends.SimulatedTestBackend, token contracts.ContractType, mintToAddress common.Address, amount *big.Int) (adjustedAmount *big.Int) {
d.T().Helper()
//nolint: exhaustive
switch token {
case DAIType:
contract, handle := d.GetDAI(ctx, backend)
auth := backend.GetTxContext(ctx, contract.OwnerPtr())
adjustedAmount = MustAdjustAmount(ctx, d.T(), amount, handle)
tx, err := handle.Mint(auth.TransactOpts, mintToAddress, adjustedAmount)
assert.NoError(d.T(), err)
backend.WaitForConfirmation(ctx, tx)
case USDTType:
contract, handle := d.GetUSDT(ctx, backend)
adjustedAmount = MustAdjustAmount(ctx, d.T(), amount, handle)
auth := backend.GetTxContext(ctx, contract.OwnerPtr())
tx, err := handle.Redeem(auth.TransactOpts, adjustedAmount)
assert.NoError(d.T(), err)
backend.WaitForConfirmation(ctx, tx)
auth = backend.GetTxContext(ctx, contract.OwnerPtr())
tx, err = handle.Transfer(auth.TransactOpts, mintToAddress, adjustedAmount)
assert.NoError(d.T(), err)
backend.WaitForConfirmation(ctx, tx)
case USDCType:
contract, handle := d.GetUSDC(ctx, backend)
adjustedAmount = MustAdjustAmount(ctx, d.T(), amount, handle)
auth := backend.GetTxContext(ctx, contract.OwnerPtr())
// TODO: it's fairly likely we should just configure this w/ max mint rights to minter
tx, err := handle.ConfigureMinter(auth.TransactOpts, contract.Owner(), adjustedAmount)
assert.NoError(d.T(), err)
backend.WaitForConfirmation(ctx, tx)
fmt.Printf("minter configured: %s \n ", tx.Hash())
auth = backend.GetTxContext(ctx, contract.OwnerPtr())
tx, err = handle.Mint(auth.TransactOpts, mintToAddress, adjustedAmount)
assert.NoError(d.T(), err)
backend.WaitForConfirmation(ctx, tx)
case MockERC20Type:
contract, handle := d.GetMockERC20(ctx, backend)
adjustedAmount = MustAdjustAmount(ctx, d.T(), amount, handle)
auth := backend.GetTxContext(ctx, contract.OwnerPtr())
tx, err := handle.Mint(auth.TransactOpts, mintToAddress, adjustedAmount)
assert.NoError(d.T(), err)
backend.WaitForConfirmation(ctx, tx)
default:
d.T().Errorf("contract type %s not (yet) supported", token.Name())
}
return adjustedAmount
}
// FastBridgeDeployer deplyos a fast bridge contract for testing.
type FastBridgeDeployer struct {
*deployer.BaseDeployer
}
// NewFastBridgeDeployer deploys a fast bridge contract.
func NewFastBridgeDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return FastBridgeDeployer{
deployer.NewSimpleDeployer(registry, backend, FastBridgeType),
}
}
// Deploy deploys the fast bridge contract.
func (f FastBridgeDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return f.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return fastbridge.DeployFastBridge(transactOps, backend, transactOps.From)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return fastbridge.NewFastBridgeRef(address, backend)
})
}
// MockFastBridgeDeployer deploys a mock fast bridge contract for testing.
type MockFastBridgeDeployer struct {
*deployer.BaseDeployer
}
// NewMockFastBridgeDeployer deploys a mock fast bridge contract.
func NewMockFastBridgeDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return MockFastBridgeDeployer{
deployer.NewSimpleDeployer(registry, backend, FastBridgeMockType),
}
}
// Deploy deploys the mock fast bridge contract.
func (m MockFastBridgeDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return m.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return fastbridgemock.DeployFastBridgeMock(transactOps, backend, transactOps.From)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return fastbridgemock.NewFastBridgeMockRef(address, backend)
})
}