-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Finish Polygon Generalize the ethereum wallet. Add tokens. Implement rpc tests and getgas. Server backend. Deploy usdc, Some frontend. --------- Co-authored-by: Jonathan Chappelow <[email protected]>
- Loading branch information
Showing
68 changed files
with
3,275 additions
and
1,410 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// This code is available on the terms of the project LICENSE.md file, | ||
// also available online at https://blueoakcouncil.org/license/1.0.0. | ||
|
||
package eth | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"os/user" | ||
"path/filepath" | ||
"strings" | ||
|
||
"decred.org/dcrdex/dex" | ||
dexeth "decred.org/dcrdex/dex/networks/eth" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core" | ||
ethcore "github.com/ethereum/go-ethereum/core" | ||
"github.com/ethereum/go-ethereum/eth/ethconfig" | ||
"github.com/ethereum/go-ethereum/params" | ||
) | ||
|
||
// CompatibilityData is some addresses and hashes used for validating an RPC | ||
// APIs compatibility with trading. | ||
type CompatibilityData struct { | ||
Addr common.Address | ||
TokenAddr common.Address | ||
TxHash common.Hash | ||
BlockHash common.Hash | ||
} | ||
|
||
var ( | ||
mainnetCompatibilityData = CompatibilityData{ | ||
// Vitalik's address from https://twitter.com/VitalikButerin/status/1050126908589887488 | ||
Addr: common.HexToAddress("0xab5801a7d398351b8be11c439e05c5b3259aec9b"), | ||
TokenAddr: common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), | ||
TxHash: common.HexToHash("0xea1a717af9fad5702f189d6f760bb9a5d6861b4ee915976fe7732c0c95cd8a0e"), | ||
BlockHash: common.HexToHash("0x44ebd6f66b4fd546bccdd700869f6a433ef9a47e296a594fa474228f86eeb353"), | ||
} | ||
|
||
testnetCompatibilityData = CompatibilityData{ | ||
Addr: common.HexToAddress("0x8879F72728C5eaf5fB3C55e6C3245e97601FBa32"), | ||
TokenAddr: common.HexToAddress("0x07865c6E87B9F70255377e024ace6630C1Eaa37F"), | ||
TxHash: common.HexToHash("0x4e1d455f7eac7e3a5f7c1e0989b637002755eaee3a262f90b0f3aef1f1c4dcf0"), | ||
BlockHash: common.HexToHash("0x8896021c2666303a85b7e4a6a6f2b075bc705d4e793bf374cd44b83bca23ef9a"), | ||
} | ||
) | ||
|
||
// NetworkCompatibilityData returns the CompatibilityData for the specified | ||
// network. If using simnet, make sure the simnet harness is running. | ||
func NetworkCompatibilityData(net dex.Network) (c CompatibilityData, err error) { | ||
switch net { | ||
case dex.Mainnet: | ||
return mainnetCompatibilityData, nil | ||
case dex.Testnet: | ||
return testnetCompatibilityData, nil | ||
case dex.Simnet: | ||
default: | ||
return c, fmt.Errorf("No compatibility data for network # %d", net) | ||
} | ||
// simnet | ||
tDir, err := simnetDataDir() | ||
if err != nil { | ||
return | ||
} | ||
|
||
addr := common.HexToAddress("18d65fb8d60c1199bb1ad381be47aa692b482605") | ||
var ( | ||
tTxHashFile = filepath.Join(tDir, "test_tx_hash.txt") | ||
tBlockHashFile = filepath.Join(tDir, "test_block10_hash.txt") | ||
tContractFile = filepath.Join(tDir, "test_token_contract_address.txt") | ||
) | ||
readIt := func(path string) string { | ||
b, err := os.ReadFile(path) | ||
if err != nil { | ||
panic(fmt.Sprintf("Problem reading simnet testing file %q: %v", path, err)) | ||
} | ||
return strings.TrimSpace(string(b)) // mainly the trailing "\r\n" | ||
} | ||
return CompatibilityData{ | ||
Addr: addr, | ||
TokenAddr: common.HexToAddress(readIt(tContractFile)), | ||
TxHash: common.HexToHash(readIt(tTxHashFile)), | ||
BlockHash: common.HexToHash(readIt(tBlockHashFile)), | ||
}, nil | ||
} | ||
|
||
// simnetDataDir returns the data directory for Ethereum simnet. | ||
func simnetDataDir() (string, error) { | ||
u, err := user.Current() | ||
if err != nil { | ||
return "", fmt.Errorf("error getting current user: %w", err) | ||
} | ||
|
||
return filepath.Join(u.HomeDir, "dextest", "eth"), nil | ||
} | ||
|
||
// ETHConfig returns the ETH protocol configuration for the specified network. | ||
func ETHConfig(net dex.Network) (c ethconfig.Config, err error) { | ||
c = ethconfig.Defaults | ||
switch net { | ||
// Ethereum | ||
case dex.Testnet: | ||
c.Genesis = core.DefaultGoerliGenesisBlock() | ||
case dex.Mainnet: | ||
c.Genesis = core.DefaultGenesisBlock() | ||
case dex.Simnet: | ||
c.Genesis, err = readSimnetGenesisFile() | ||
if err != nil { | ||
return c, fmt.Errorf("readSimnetGenesisFile error: %w", err) | ||
} | ||
default: | ||
return c, fmt.Errorf("unknown network %d", net) | ||
|
||
} | ||
c.NetworkId = c.Genesis.Config.ChainID.Uint64() | ||
return | ||
} | ||
|
||
// ChainConfig returns the core configuration for the blockchain. | ||
func ChainConfig(net dex.Network) (c *params.ChainConfig, err error) { | ||
cfg, err := ETHConfig(net) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return cfg.Genesis.Config, nil | ||
} | ||
|
||
// readSimnetGenesisFile reads the simnet genesis file. | ||
func readSimnetGenesisFile() (*ethcore.Genesis, error) { | ||
dataDir, err := simnetDataDir() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
genesisFile := filepath.Join(dataDir, "genesis.json") | ||
genesisCfg, err := dexeth.LoadGenesisFile(genesisFile) | ||
if err != nil { | ||
return nil, fmt.Errorf("error reading genesis file: %v", err) | ||
} | ||
|
||
return genesisCfg, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
// This code is available on the terms of the project LICENSE.md file, | ||
// also available online at https://blueoakcouncil.org/license/1.0.0. | ||
|
||
package main | ||
|
||
/* | ||
deploy is a utility for deploying swap contracts. Examples of use: | ||
1) Estimate the funding required to deploy a base asset swap contract to | ||
Ethereum | ||
./deploy --mainnet --chain eth --fundingrequired | ||
This will use the current prevailing fee rate to estimate the fee | ||
requirements for the deployment transaction. The estimate is only | ||
accurate if there are already enough funds in the wallet (so estimateGas | ||
can be used), otherwise, a generously-padded constant is used to estimate | ||
the gas requirements. | ||
2) Deploy a base asset swap contract to Ethereum. | ||
./deploy --mainnet --chain eth | ||
3) Deploy a token swap contract to Polygon. | ||
./deploy --mainnet --chain polygon --tokenaddr 0x2791bca1f2de4661ed88a30c99a7a9449aa84174 | ||
4) Return remaining Goerli testnet ETH balance to specified address. | ||
./deploy --testnet --chain eth --returnaddr 0x18d65fb8d60c1199bb1ad381be47aa692b482605 | ||
IMPORTANT: deploy uses the same wallet configuration as getgas. See getgas | ||
README for instructions. | ||
5) Test reading of the Polygon credentials file. | ||
./deploy --chain polygon --mainnet --readcreds | ||
*/ | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"fmt" | ||
"os" | ||
"os/user" | ||
"path/filepath" | ||
"strings" | ||
|
||
"decred.org/dcrdex/client/asset" | ||
"decred.org/dcrdex/client/asset/eth" | ||
"decred.org/dcrdex/client/asset/polygon" | ||
"decred.org/dcrdex/dex" | ||
dexeth "decred.org/dcrdex/dex/networks/eth" | ||
dexpolygon "decred.org/dcrdex/dex/networks/polygon" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/params" | ||
) | ||
|
||
func main() { | ||
if err := mainErr(); err != nil { | ||
fmt.Fprint(os.Stderr, err, "\n") | ||
os.Exit(1) | ||
} | ||
os.Exit(0) | ||
} | ||
|
||
func mainErr() error { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
|
||
u, err := user.Current() | ||
if err != nil { | ||
return fmt.Errorf("could not get the current user: %w", err) | ||
} | ||
defaultCredentialsPath := filepath.Join(u.HomeDir, "dextest", "credentials.json") | ||
|
||
var contractVerI int | ||
var chain, credentialsPath, tokenAddress, returnAddr string | ||
var useTestnet, useMainnet, useSimnet, trace, debug, readCreds, fundingReq bool | ||
flag.BoolVar(&readCreds, "readcreds", false, "does not run gas estimates. read the credentials file and print the address") | ||
flag.BoolVar(&fundingReq, "fundingrequired", false, "does not run gas estimates. calculate the funding required by the wallet to get estimates") | ||
flag.StringVar(&returnAddr, "return", "", "does not run gas estimates. return ethereum funds to supplied address") | ||
flag.BoolVar(&useMainnet, "mainnet", false, "use mainnet") | ||
flag.BoolVar(&useTestnet, "testnet", false, "use testnet") | ||
flag.BoolVar(&useSimnet, "simnet", false, "use simnet") | ||
flag.BoolVar(&trace, "trace", false, "use simnet") | ||
flag.BoolVar(&debug, "debug", false, "use simnet") | ||
flag.StringVar(&chain, "chain", "eth", "symbol of the base chain") | ||
flag.StringVar(&tokenAddress, "tokenaddr", "", "launches an erc20-linked contract with this token. default launches a base chain contract") | ||
flag.IntVar(&contractVerI, "ver", 0, "contract version") | ||
flag.StringVar(&credentialsPath, "creds", defaultCredentialsPath, "path for JSON credentials file.") | ||
flag.Parse() | ||
|
||
if !useMainnet && !useTestnet && !useSimnet { | ||
return fmt.Errorf("no network specified. add flag --mainnet, --testnet, or --simnet") | ||
} | ||
if (useMainnet && useTestnet) || (useMainnet && useSimnet) || (useTestnet && useSimnet) { | ||
return fmt.Errorf("more than one network specified") | ||
} | ||
|
||
net := dex.Mainnet | ||
if useSimnet { | ||
net = dex.Simnet | ||
dexeth.MaybeReadSimnetAddrs() | ||
dexpolygon.MaybeReadSimnetAddrs() | ||
} | ||
if useTestnet { | ||
net = dex.Testnet | ||
} | ||
|
||
if readCreds { | ||
addr, providers, err := eth.GetGas.ReadCredentials(chain, credentialsPath, net) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println("Credentials successfully parsed") | ||
fmt.Println("Address:", addr) | ||
fmt.Println("Providers:", strings.Join(providers, ", ")) | ||
return nil | ||
} | ||
|
||
assetID, found := dex.BipSymbolID(chain) | ||
if !found { | ||
return fmt.Errorf("asset %s not known", chain) | ||
} | ||
|
||
if tkn := asset.TokenInfo(assetID); tkn != nil { | ||
return fmt.Errorf("specified chain is not a base chain. appears to be token %s", tkn.Name) | ||
} | ||
|
||
contractVer := uint32(contractVerI) | ||
|
||
logLvl := dex.LevelInfo | ||
if debug { | ||
logLvl = dex.LevelDebug | ||
} | ||
if trace { | ||
logLvl = dex.LevelTrace | ||
} | ||
|
||
var tokenAddr common.Address | ||
if tokenAddress != "" { | ||
if !common.IsHexAddress(tokenAddress) { | ||
return fmt.Errorf("token address %q does not appear to be valid", tokenAddress) | ||
} | ||
tokenAddr = common.HexToAddress(tokenAddress) | ||
} | ||
|
||
log := dex.StdOutLogger("DEPLOY", logLvl) | ||
|
||
var bui *dex.UnitInfo | ||
var chainCfg *params.ChainConfig | ||
switch chain { | ||
case "eth": | ||
bui = &dexeth.UnitInfo | ||
chainCfg, err = eth.ChainConfig(net) | ||
if err != nil { | ||
return fmt.Errorf("error finding chain config: %v", err) | ||
} | ||
case "polygon": | ||
bui = &dexpolygon.UnitInfo | ||
chainCfg, err = polygon.ChainConfig(net) | ||
if err != nil { | ||
return fmt.Errorf("error finding chain config: %v", err) | ||
} | ||
} | ||
|
||
switch { | ||
case fundingReq: | ||
return eth.ContractDeployer.EstimateDeployFunding( | ||
ctx, | ||
chain, | ||
contractVer, | ||
tokenAddr, | ||
credentialsPath, | ||
chainCfg, | ||
bui, | ||
log, | ||
net, | ||
) | ||
case returnAddr != "": | ||
if !common.IsHexAddress(returnAddr) { | ||
return fmt.Errorf("return address %q is not valid", returnAddr) | ||
} | ||
addr := common.HexToAddress(returnAddr) | ||
return eth.ContractDeployer.ReturnETH(ctx, chain, addr, credentialsPath, chainCfg, bui, log, net) | ||
default: | ||
return eth.ContractDeployer.DeployContract( | ||
ctx, | ||
chain, | ||
contractVer, | ||
tokenAddr, | ||
credentialsPath, | ||
chainCfg, | ||
bui, | ||
log, | ||
net, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.