Skip to content

Commit

Permalink
erc20: Add testnet usdc.
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeGruffins committed Nov 30, 2022
1 parent 75bb91d commit e491ed0
Show file tree
Hide file tree
Showing 22 changed files with 562 additions and 213 deletions.
11 changes: 6 additions & 5 deletions client/asset/eth/contractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func newV0Contractor(net dex.Network, acctAddr common.Address, cb bind.ContractB
}

// initiate sends the initiations to the swap contract's initiate function.
func (c *contractorV0) initiate(txOpts *bind.TransactOpts, contracts []*asset.Contract) (*types.Transaction, error) {
func (c *contractorV0) initiate(txOpts *bind.TransactOpts, contracts []*asset.Contract) (tx *types.Transaction, err error) {
inits := make([]swapv0.ETHSwapInitiation, 0, len(contracts))
secrets := make(map[[32]byte]bool, len(contracts))

Expand Down Expand Up @@ -146,9 +146,10 @@ func (c *contractorV0) initiate(txOpts *bind.TransactOpts, contracts []*asset.Co
}

// redeem sends the redemptions to the swap contracts redeem method.
func (c *contractorV0) redeem(txOpts *bind.TransactOpts, redemptions []*asset.Redemption) (*types.Transaction, error) {
func (c *contractorV0) redeem(txOpts *bind.TransactOpts, redemptions []*asset.Redemption) (tx *types.Transaction, err error) {
redemps := make([]swapv0.ETHSwapRedemption, 0, len(redemptions))
secretHashes := make(map[[32]byte]bool, len(redemptions))

for _, r := range redemptions {
secretB, secretHashB := r.Secret, r.Spends.SecretHash
if len(secretB) != 32 || len(secretHashB) != 32 {
Expand Down Expand Up @@ -194,7 +195,7 @@ func (c *contractorV0) swap(ctx context.Context, secretHash [32]byte) (*dexeth.S

// refund issues the refund command to the swap contract. Use isRefundable first
// to ensure the refund will be accepted.
func (c *contractorV0) refund(txOpts *bind.TransactOpts, secretHash [32]byte) (*types.Transaction, error) {
func (c *contractorV0) refund(txOpts *bind.TransactOpts, secretHash [32]byte) (tx *types.Transaction, err error) {
return c.contractV0.Refund(txOpts, secretHash)
}

Expand Down Expand Up @@ -395,13 +396,13 @@ func (c *tokenContractorV0) allowance(ctx context.Context) (*big.Int, error) {

// approve sends an approve transaction approving the linked contract to call
// transferFrom for the specified amount.
func (c *tokenContractorV0) approve(txOpts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) {
func (c *tokenContractorV0) approve(txOpts *bind.TransactOpts, amount *big.Int) (tx *types.Transaction, err error) {
return c.tokenContract.Approve(txOpts, c.contractAddr, amount)
}

// transfer calls the transfer method of the erc20 token contract. Used for
// sends or withdrawals.
func (c *tokenContractorV0) transfer(txOpts *bind.TransactOpts, addr common.Address, amount *big.Int) (*types.Transaction, error) {
func (c *tokenContractorV0) transfer(txOpts *bind.TransactOpts, addr common.Address, amount *big.Int) (tx *types.Transaction, err error) {
return c.tokenContract.Transfer(txOpts, addr, amount)
}

Expand Down
56 changes: 42 additions & 14 deletions client/asset/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"decred.org/dcrdex/dex/config"
"decred.org/dcrdex/dex/encode"
"decred.org/dcrdex/dex/keygen"
"decred.org/dcrdex/dex/networks/erc20"
dexeth "decred.org/dcrdex/dex/networks/eth"
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
"github.com/decred/dcrd/hdkeychain/v3"
Expand Down Expand Up @@ -60,7 +59,8 @@ func registerToken(tokenID uint32, desc string, nets ...dex.Network) {
func init() {
asset.Register(BipID, &Driver{})
// Test token
registerToken(testTokenID, "A token wallet for the DEX test token. Used for testing DEX software.", dex.Simnet)
registerToken(simnetTokenID, "A token wallet for the DEX test token. Used for testing DEX software.", dex.Simnet)
registerToken(usdcTokenID, "The USDC Ethereum ERC20 token.", dex.Testnet)
}

const (
Expand All @@ -83,7 +83,8 @@ const (
)

var (
testTokenID, _ = dex.BipSymbolID("dextt.eth")
simnetTokenID, _ = dex.BipSymbolID("dextt.eth")
usdcTokenID, _ = dex.BipSymbolID("usdc.eth")
// blockTicker is the delay between calls to check for new blocks.
blockTicker = time.Second
peerCountTicker = 5 * time.Second
Expand Down Expand Up @@ -1482,7 +1483,7 @@ func (w *assetWallet) approvalGas(newGas *big.Int, ver uint32) (uint64, error) {
if approveEst, err := w.estimateApproveGas(newGas); err != nil {
return 0, fmt.Errorf("error estimating approve gas: %v", err)
} else if approveEst > approveGas {
w.log.Warnf("Approve gas estimate %d is greater than the expected value %d. Using live estimate + 10%.")
w.log.Warnf("Approve gas estimate %d is greater than the expected value %d. Using live estimate + 10%%.", approveEst, approveGas)
return approveEst * 11 / 10, nil
}
return approveGas, nil
Expand Down Expand Up @@ -1756,6 +1757,14 @@ func (w *TokenWallet) Swap(swaps *asset.Swaps) ([]asset.Receipt, asset.Coin, uin
return fail("Swap: initiate error: %w", err)
}

if dexeth.Tokens[w.assetID] == nil ||
dexeth.Tokens[w.assetID].NetTokens[w.net] == nil ||
dexeth.Tokens[w.assetID].NetTokens[w.net].SwapContracts[swaps.Version] == nil {
return fail("unable to find contract address for asset %d", w.assetID)
}

contractAddr := dexeth.Tokens[w.assetID].NetTokens[w.net].SwapContracts[swaps.Version].Address.String()

txHash := tx.Hash()
for _, swap := range swaps.Contracts {
var secretHash [dexeth.SecretHashSize]byte
Expand All @@ -1766,7 +1775,7 @@ func (w *TokenWallet) Swap(swaps *asset.Swaps) ([]asset.Receipt, asset.Coin, uin
txHash: txHash,
secretHash: secretHash,
ver: swaps.Version,
contractAddr: erc20.ContractAddresses[swaps.Version][w.net].String(),
contractAddr: contractAddr,
})
}

Expand Down Expand Up @@ -3387,7 +3396,7 @@ func (w *assetWallet) confirmRedemption(coinID dex.Bytes, redemption *asset.Rede

monitoredTx, err := w.getLatestMonitoredTx(txHash)
if err != nil {
w.log.Error("getLatestMonitoredTx error: %v", err)
w.log.Errorf("getLatestMonitoredTx error: %v", err)
return w.confirmRedemptionWithoutMonitoredTx(txHash, redemption, feeWallet)
}
// This mutex is locked inside of getLatestMonitoredTx.
Expand Down Expand Up @@ -3692,7 +3701,16 @@ func (w *assetWallet) withContractor(contractVer uint32, f func(contractor) erro
if !found {
return fmt.Errorf("no version %d contractor for asset %d", contractVer, w.assetID)
}
return f(contractor)
err := f(contractor)
// If a transaction fails with a provider, trust the next nonce.
if err != nil {
if c, is := contractor.(*contractorV0); is {
if mRPC, is := c.cb.(*multiRPCClient); is {
mRPC.voidUnusedNonce()
}
}
}
return err
}

// withTokenContractor runs the provided function with the tokenContractor.
Expand All @@ -3702,7 +3720,16 @@ func (w *assetWallet) withTokenContractor(assetID, ver uint32, f func(tokenContr
if !is {
return fmt.Errorf("contractor for %d %T is not a tokenContractor", assetID, c)
}
return f(tc)
err := f(tc)
// If a transaction fails with a provider, trust the next nonce.
if err != nil {
if c, is := tc.(*tokenContractorV0); is {
if mRPC, is := c.cb.(*multiRPCClient); is {
mRPC.voidUnusedNonce()
}
}
}
return err
})
}

Expand Down Expand Up @@ -3799,7 +3826,8 @@ func checkTxStatus(receipt *types.Receipt, gasLimit uint64) error {
// factor of 2. The account should already have a trading balance of at least
// maxSwaps gwei (token or eth), and sufficient eth balance to cover the
// requisite tx fees.
func GetGasEstimates(ctx context.Context, cl ethFetcher, c contractor, maxSwaps int, g *dexeth.Gases, waitForMined func()) error {
func GetGasEstimates(ctx context.Context, cl ethFetcher, c contractor, maxSwaps int, g *dexeth.Gases,
toAddress common.Address, waitForMined func(), waitForReceipt func(ethFetcher, *types.Transaction) (*types.Receipt, error)) error {
tokenContractor, isToken := c.(tokenContractor)

stats := struct {
Expand Down Expand Up @@ -3872,7 +3900,7 @@ func GetGasEstimates(ctx context.Context, cl ethFetcher, c contractor, maxSwaps
if err != nil {
return fmt.Errorf("error constructing signed tx opts for transfer: %v", err)
}
transferTx, err = tokenContractor.transfer(txOpts, cl.address(), big.NewInt(1))
transferTx, err = tokenContractor.transfer(txOpts, toAddress, big.NewInt(1))
if err != nil {
return fmt.Errorf("error estimating transfer gas: %v", err)
}
Expand Down Expand Up @@ -3909,7 +3937,7 @@ func GetGasEstimates(ctx context.Context, cl ethFetcher, c contractor, maxSwaps
return fmt.Errorf("initiate error for %d swaps: %v", n, err)
}
waitForMined()
receipt, _, err := cl.transactionReceipt(ctx, tx.Hash())
receipt, err := waitForReceipt(cl, tx)
if err != nil {
return err
}
Expand All @@ -3919,15 +3947,15 @@ func GetGasEstimates(ctx context.Context, cl ethFetcher, c contractor, maxSwaps
stats.swaps = append(stats.swaps, receipt.GasUsed)

if isToken {
receipt, _, err = cl.transactionReceipt(ctx, approveTx.Hash())
receipt, err = waitForReceipt(cl, approveTx)
if err != nil {
return err
}
if err := checkTxStatus(receipt, txOpts.GasLimit); err != nil {
return err
}
stats.approves = append(stats.approves, receipt.GasUsed)
receipt, _, err = cl.transactionReceipt(ctx, transferTx.Hash())
receipt, err = waitForReceipt(cl, transferTx)
if err != nil {
return err
}
Expand Down Expand Up @@ -3962,7 +3990,7 @@ func GetGasEstimates(ctx context.Context, cl ethFetcher, c contractor, maxSwaps
return fmt.Errorf("redeem error for %d swaps: %v", n, err)
}
waitForMined()
receipt, _, err = cl.transactionReceipt(ctx, tx.Hash())
receipt, err = waitForReceipt(cl, tx)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit e491ed0

Please sign in to comment.