mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-08 21:58:07 -05:00
195 lines
5.4 KiB
Go
195 lines
5.4 KiB
Go
// Copyright 2023 Athanor Labs (ON)
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
package xmrmaker
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ecdsa"
|
|
"math/big"
|
|
"testing"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/athanorlabs/go-relayer/impls/gsnforwarder"
|
|
|
|
"github.com/athanorlabs/atomic-swap/common/types"
|
|
"github.com/athanorlabs/atomic-swap/dleq"
|
|
contracts "github.com/athanorlabs/atomic-swap/ethereum"
|
|
"github.com/athanorlabs/atomic-swap/ethereum/block"
|
|
"github.com/athanorlabs/atomic-swap/ethereum/extethclient"
|
|
"github.com/athanorlabs/atomic-swap/relayer"
|
|
"github.com/athanorlabs/atomic-swap/tests"
|
|
)
|
|
|
|
var (
|
|
defaultTestTimeoutDuration = big.NewInt(60 * 5)
|
|
)
|
|
|
|
func TestSwapState_ClaimRelayer_ERC20(t *testing.T) {
|
|
t.Skip("Claiming ERC20 tokens via relayer is not yet supported")
|
|
|
|
initialBalance := big.NewInt(90000000000000000)
|
|
|
|
sk := tests.GetMakerTestKey(t)
|
|
conn, chainID := tests.NewEthClient(t)
|
|
|
|
pub := sk.Public().(*ecdsa.PublicKey)
|
|
addr := crypto.PubkeyToAddress(*pub)
|
|
|
|
txOpts, err := bind.NewKeyedTransactorWithChainID(sk, chainID)
|
|
require.NoError(t, err)
|
|
|
|
_, tx, _, err := contracts.DeployERC20Mock(
|
|
txOpts,
|
|
conn,
|
|
"Mock",
|
|
"MOCK",
|
|
addr,
|
|
initialBalance,
|
|
)
|
|
require.NoError(t, err)
|
|
contractAddr, err := bind.WaitDeployed(context.Background(), conn, tx)
|
|
require.NoError(t, err)
|
|
|
|
testSwapStateClaimRelayer(t, sk, types.EthAsset(contractAddr))
|
|
}
|
|
|
|
func TestSwapState_ClaimRelayer_ETH(t *testing.T) {
|
|
sk := tests.GetMakerTestKey(t)
|
|
testSwapStateClaimRelayer(t, sk, types.EthAssetETH)
|
|
}
|
|
|
|
func testSwapStateClaimRelayer(t *testing.T, sk *ecdsa.PrivateKey, asset types.EthAsset) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
ec := extethclient.CreateTestClient(t, sk)
|
|
txOpts, err := ec.TxOpts(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// generate claim secret and public key
|
|
dleq := &dleq.DefaultDLEq{}
|
|
proof, err := dleq.Prove()
|
|
require.NoError(t, err)
|
|
res, err := dleq.Verify(proof)
|
|
require.NoError(t, err)
|
|
|
|
// hash public key of claim secret
|
|
cmt := res.Secp256k1PublicKey().Keccak256()
|
|
|
|
pub := sk.Public().(*ecdsa.PublicKey)
|
|
addr := crypto.PubkeyToAddress(*pub)
|
|
|
|
// deploy forwarder
|
|
forwarderAddr, tx, forwarderContract, err := gsnforwarder.DeployForwarder(txOpts, ec.Raw())
|
|
require.NoError(t, err)
|
|
receipt, err := block.WaitForReceipt(ctx, ec.Raw(), tx.Hash())
|
|
require.NoError(t, err)
|
|
t.Logf("gas cost to deploy Forwarder.sol: %d", receipt.GasUsed)
|
|
|
|
tx, err = forwarderContract.RegisterDomainSeparator(txOpts, gsnforwarder.DefaultName, gsnforwarder.DefaultVersion)
|
|
require.NoError(t, err)
|
|
receipt, err = block.WaitForReceipt(ctx, ec.Raw(), tx.Hash())
|
|
require.NoError(t, err)
|
|
t.Logf("gas cost to call RegisterDomainSeparator: %d", receipt.GasUsed)
|
|
|
|
// deploy swap contract with claim key hash
|
|
contractAddr, tx, contract, err := contracts.DeploySwapCreator(txOpts, ec.Raw(), forwarderAddr)
|
|
require.NoError(t, err)
|
|
receipt, err = block.WaitForReceipt(ctx, ec.Raw(), tx.Hash())
|
|
require.NoError(t, err)
|
|
t.Logf("gas cost to deploy SwapCreator.sol: %d", receipt.GasUsed)
|
|
|
|
if asset != types.EthAssetETH {
|
|
token, err := contracts.NewIERC20(asset.Address(), ec.Raw()) //nolint:govet
|
|
require.NoError(t, err)
|
|
|
|
balance, err := token.BalanceOf(&bind.CallOpts{}, addr)
|
|
require.NoError(t, err)
|
|
|
|
tx, err = token.Approve(txOpts, contractAddr, balance)
|
|
require.NoError(t, err)
|
|
|
|
_, err = block.WaitForReceipt(ctx, ec.Raw(), tx.Hash())
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
value := big.NewInt(90000000000000000)
|
|
nonce := big.NewInt(0)
|
|
txOpts.Value = value
|
|
|
|
tx, err = contract.NewSwap(txOpts, cmt, [32]byte{}, addr,
|
|
defaultTestTimeoutDuration, defaultTestTimeoutDuration, asset.Address(), value, nonce)
|
|
require.NoError(t, err)
|
|
receipt, err = block.WaitForReceipt(ctx, ec.Raw(), tx.Hash())
|
|
require.NoError(t, err)
|
|
t.Logf("gas cost to call new_swap: %d", receipt.GasUsed)
|
|
txOpts.Value = big.NewInt(0)
|
|
|
|
logIndex := 0
|
|
if asset != types.EthAssetETH {
|
|
logIndex = 2
|
|
}
|
|
|
|
require.Equal(t, logIndex+1, len(receipt.Logs))
|
|
id, err := contracts.GetIDFromLog(receipt.Logs[logIndex])
|
|
require.NoError(t, err)
|
|
|
|
t0, t1, err := contracts.GetTimeoutsFromLog(receipt.Logs[logIndex])
|
|
require.NoError(t, err)
|
|
|
|
swap := &contracts.SwapCreatorSwap{
|
|
Owner: addr,
|
|
Claimer: addr,
|
|
PubKeyClaim: cmt,
|
|
PubKeyRefund: [32]byte{},
|
|
Timeout0: t0,
|
|
Timeout1: t1,
|
|
Asset: asset.Address(),
|
|
Value: value,
|
|
Nonce: nonce,
|
|
}
|
|
|
|
// set contract to Ready
|
|
tx, err = contract.SetReady(txOpts, *swap)
|
|
require.NoError(t, err)
|
|
receipt, err = block.WaitForReceipt(ctx, ec.Raw(), tx.Hash())
|
|
t.Logf("gas cost to call SetReady: %d", receipt.GasUsed)
|
|
require.NoError(t, err)
|
|
|
|
secret := proof.Secret()
|
|
|
|
// now let's try to claim
|
|
req, err := relayer.CreateRelayClaimRequest(
|
|
ctx,
|
|
sk,
|
|
ec.Raw(),
|
|
contractAddr,
|
|
forwarderAddr,
|
|
swap,
|
|
&secret,
|
|
)
|
|
require.NoError(t, err)
|
|
|
|
resp, err := relayer.ValidateAndSendTransaction(ctx, req, ec, contractAddr)
|
|
require.NoError(t, err)
|
|
|
|
receipt, err = block.WaitForReceipt(ctx, ec.Raw(), resp.TxHash)
|
|
require.NoError(t, err)
|
|
t.Logf("gas cost to call Claim via relayer: %d", receipt.GasUsed)
|
|
|
|
if asset != types.EthAssetETH {
|
|
require.Equal(t, 3, len(receipt.Logs))
|
|
} else {
|
|
// expected 1 Claimed log
|
|
require.Equal(t, 1, len(receipt.Logs))
|
|
}
|
|
|
|
stage, err := contract.Swaps(nil, id)
|
|
require.NoError(t, err)
|
|
require.Equal(t, contracts.StageCompleted, stage)
|
|
}
|