services/rfq/testutil/tokens.go
package testutil
import (
"context"
"fmt"
"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/rfq/contracts/testcontracts/dai"
mockerc202 "github.com/synapsecns/sanguine/services/rfq/contracts/testcontracts/mockerc20"
"github.com/synapsecns/sanguine/services/rfq/contracts/testcontracts/usdc"
"github.com/synapsecns/sanguine/services/rfq/contracts/testcontracts/usdt"
"github.com/synapsecns/sanguine/services/rfq/contracts/testcontracts/weth9"
"math/big"
)
// MockERC20Deployer deploys a mock erc20 contract.
type MockERC20Deployer struct {
*deployer.BaseDeployer
}
// NewMockERC20Deployer creates a new mock erc20 deployer.
func NewMockERC20Deployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return MockERC20Deployer{
deployer.NewSimpleDeployer(registry, backend, MockERC20Type),
}
}
// MockERC20Decimals is the default number of mock erc20 decimals.
const MockERC20Decimals uint8 = 10
// MockERC20Name is the name of hte mock erc20.
const MockERC20Name = "token"
// Deploy deploys a mock erc20 contract.
func (m MockERC20Deployer) 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 mockerc202.DeployMockERC20(transactOps, backend, MockERC20Name, MockERC20Decimals)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return mockerc202.NewMockerc20Ref(address, backend)
})
}
// WETH9Deployer deploys a mock erc20 contract.
type WETH9Deployer struct {
*deployer.BaseDeployer
}
// NewWETH9Deployer creates a new deployer for weth9.
func NewWETH9Deployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return WETH9Deployer{
deployer.NewSimpleDeployer(registry, backend, WETH9Type),
}
}
// Deploy deploys the weth9 contract.
func (m WETH9Deployer) 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 weth9.DeployWETH9(transactOps, backend)
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return weth9.NewWeth9Ref(address, backend)
})
}
// USDTDeployer deploys the usdt token (https://tether.to/) for testing.
type USDTDeployer struct {
*deployer.BaseDeployer
}
var defaultTetherInitialSupply = big.NewInt(1e6 * 50000000000)
// NewUSDTDeployer creates a new deployer for tether.
func NewUSDTDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return USDTDeployer{deployer.NewSimpleDeployer(registry, backend, USDTType)}
}
// Deploy deploys the usdt token.
func (d USDTDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return d.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
return usdt.DeployTetherToken(transactOps, backend, defaultTetherInitialSupply, "Tether USD", "USDT", big.NewInt(6))
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return usdt.NewUSDTRef(address, backend)
})
}
// USDCDeployer deploys the usdc token (https://www.centre.io/usdc) for testing.
type USDCDeployer struct {
*deployer.BaseDeployer
}
// NewUSDCDeployer creates a new deployer for tether.
func NewUSDCDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return USDCDeployer{deployer.NewSimpleDeployer(registry, backend, USDCType)}
}
// Deploy deploys the usdt token.
func (d USDCDeployer) Deploy(ctx context.Context) (contracts.DeployedContract, error) {
return d.DeploySimpleContract(ctx, func(transactOps *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, interface{}, error) {
tmpAddress, tx, handle, err := usdc.DeployFiatTokenV21(transactOps, backend)
if err != nil {
return common.Address{}, nil, nil, fmt.Errorf("could not deploy usdc contract")
}
d.Backend().WaitForConfirmation(ctx, tx)
auth := d.Backend().GetTxContext(ctx, &transactOps.From)
// see https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#writeProxyContract
initializedTx, err := handle.Initialize(auth.TransactOpts, "USDC Coin", "USDC", "USD", uint8(6), auth.From, auth.From, auth.From, auth.From)
if err != nil {
return common.Address{}, nil, nil, fmt.Errorf("could not initialize usdc contract")
}
d.Backend().WaitForConfirmation(ctx, initializedTx)
return tmpAddress, tx, handle, nil
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return usdc.NewUSDCRef(address, backend)
})
}
// DAIDeployer deploys a mock erc20 contract.
type DAIDeployer struct {
*deployer.BaseDeployer
}
// NewDAIDeployer creates a new deployer for dai.
func NewDAIDeployer(registry deployer.GetOnlyContractRegistry, backend backends.SimulatedTestBackend) deployer.ContractDeployer {
return DAIDeployer{
deployer.NewSimpleDeployer(registry, backend, DAIType),
}
}
// Deploy deploys the dai contract.
func (m DAIDeployer) 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 dai.DeployDai(transactOps, backend, m.Backend().GetBigChainID())
}, func(address common.Address, backend bind.ContractBackend) (interface{}, error) {
return dai.NewDaiRef(address, backend)
})
}