This repository has been archived by the owner on Aug 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 112
/
factory.go
125 lines (108 loc) · 4.02 KB
/
factory.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package swap
import (
"bytes"
"context"
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
chequebookFactory "github.com/ethersphere/go-sw3/contracts-v0-1-1/simpleswapfactory"
)
var (
// ErrNotDeployedByFactory is given when a contract was not deployed by the factory
ErrNotDeployedByFactory = errors.New("not deployed by factory")
// Deployments maps from network ids to deployed contract factories
Deployments = map[uint64]common.Address{
// Ropsten
3: common.HexToAddress("0x2e9C43E186eaF4fee10799d67e75f8CFc5BA3a0c"),
}
)
type simpleSwapFactory struct {
instance *chequebookFactory.SimpleSwapFactory
address common.Address
backend Backend
}
// SimpleSwapFactory interface defines the methods available for a factory contract for SimpleSwap
type SimpleSwapFactory interface {
// DeploySimpleSwap deploys a new SimpleSwap contract from the factory and returns the ready to use Contract abstraction
DeploySimpleSwap(auth *bind.TransactOpts, issuer common.Address, defaultHardDepositTimeoutDuration *big.Int) (Contract, error)
// VerifyContract verifies that the supplied address was deployed by this factory
VerifyContract(address common.Address) error
// VerifySelf verifies that this is a valid factory on the network
VerifySelf() error
}
// FactoryAt creates a SimpleSwapFactory instance for the given address and backend
func FactoryAt(address common.Address, backend Backend) (SimpleSwapFactory, error) {
simple, err := chequebookFactory.NewSimpleSwapFactory(address, backend)
if err != nil {
return nil, err
}
c := simpleSwapFactory{instance: simple, address: address, backend: backend}
return c, err
}
// FactoryAddressForNetwork gets the default factory address for a given network id
func FactoryAddressForNetwork(networkID uint64) (common.Address, error) {
address, ok := Deployments[networkID]
if !ok {
return common.Address{}, fmt.Errorf("no known factory contract for ethereum network %d", networkID)
}
return address, nil
}
// VerifySelf verifies that this is a valid factory on the network
func (sf simpleSwapFactory) VerifySelf() error {
code, err := sf.backend.CodeAt(context.Background(), sf.address, nil)
if err != nil {
return err
}
referenceCode := common.FromHex(chequebookFactory.SimpleSwapFactoryDeployedCode)
if !bytes.Equal(code, referenceCode) {
return errors.New("not a valid factory contract")
}
return nil
}
// DeploySimpleSwap deploys a new SimpleSwap contract from the factory and returns the ready to use Contract abstraction
func (sf simpleSwapFactory) DeploySimpleSwap(auth *bind.TransactOpts, issuer common.Address, defaultHardDepositTimeoutDuration *big.Int) (Contract, error) {
// for some reason the automatic gas estimation is too low
// this value was determind by deploying through truffle and rounding up to the next 100000
// the deployment cost should always be constant
auth.GasLimit = 1700000
tx, err := sf.instance.DeploySimpleSwap(auth, issuer, defaultHardDepositTimeoutDuration)
if err != nil {
return nil, err
}
receipt, err := WaitFunc(auth, sf.backend, tx)
if err != nil {
return nil, err
}
// we iterate through the logs until we find the SimpleSwapDeployed event which contains the address of the new SimpleSwap contract
address := common.Address{}
for _, log := range receipt.Logs {
if log.Address != sf.address {
continue
}
if event, err := sf.instance.ParseSimpleSwapDeployed(*log); err == nil {
address = event.ContractAddress
break
}
}
if (address == common.Address{}) {
return nil, errors.New("contract deployment failed")
}
simpleSwap, err := InstanceAt(address, sf.backend)
if err != nil {
return nil, err
}
return simpleSwap, nil
}
// VerifyContract verifies that the supplied address was deployed by this factory
func (sf simpleSwapFactory) VerifyContract(address common.Address) error {
isDeployed, err := sf.instance.DeployedContracts(&bind.CallOpts{}, address)
if err != nil {
return err
}
if !isDeployed {
return ErrNotDeployedByFactory
}
return nil
}