From a6eca9e972507e8e797a0d4b844e4bafd5cdc9ee Mon Sep 17 00:00:00 2001 From: Marton Date: Tue, 26 Oct 2021 10:06:06 -0500 Subject: [PATCH] eth/dex/client: Add initiateBatch function This PR adds a batch initiation function to the ETH swap contract. This function saves a bit of gas when initiating multiple swaps simultaneously, and also allows ETH to conform to the current wallet interface which requires swaps to be submitted together. This saves ~20k gas for each additional swap that is batched. --- client/asset/eth/rpcclient.go | 9 + client/asset/eth/rpcclient_harness_test.go | 284 ++++++++++++++++++++- dex/networks/eth/BinRuntimeV0.go | 2 +- dex/networks/eth/contract.go | 62 +++-- dex/networks/eth/contracts/ETHSwapV0.sol | 61 ++++- dex/testing/eth/harness.sh | 2 +- server/asset/eth/common.go | 2 +- 7 files changed, 389 insertions(+), 33 deletions(-) diff --git a/client/asset/eth/rpcclient.go b/client/asset/eth/rpcclient.go index d527f55901..1ff86a5722 100644 --- a/client/asset/eth/rpcclient.go +++ b/client/asset/eth/rpcclient.go @@ -257,6 +257,15 @@ func (c *rpcclient) initiate(txOpts *bind.TransactOpts, netID int64, refundTimes return c.es.Initiate(txOpts, big.NewInt(refundTimestamp), secretHash, *participant) } +// initiateBatch initiates multiple swaps in the same transaction. +func (c *rpcclient) initiateBatch(txOpts *bind.TransactOpts, netID int64, initiations []swap.ETHSwapInitiation) (*types.Transaction, error) { + err := c.addSignerToOpts(txOpts, netID) + if err != nil { + return nil, err + } + return c.es.InitiateBatch(txOpts, initiations) +} + // estimateGas checks the amount of gas that is used for a function call. func (c *rpcclient) estimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) { return c.ec.EstimateGas(ctx, msg) diff --git a/client/asset/eth/rpcclient_harness_test.go b/client/asset/eth/rpcclient_harness_test.go index b082019b05..b438519cb9 100644 --- a/client/asset/eth/rpcclient_harness_test.go +++ b/client/asset/eth/rpcclient_harness_test.go @@ -421,6 +421,284 @@ func TestInitiateGas(t *testing.T) { fmt.Printf("Gas used for initiate: %v \n", gas) } +func TestInitiateBatchGas(t *testing.T) { + parsedAbi, err := abi.JSON(strings.NewReader(dexeth.ETHSwapABI)) + if err != nil { + t.Fatalf("unexpected error parsing abi: %v", err) + } + + var previousGas uint64 + for i := 1; i < 10; i++ { + initiations := make([]dexeth.ETHSwapInitiation, 0, i) + for j := 0; j < i; j++ { + var secretHash [32]byte + copy(secretHash[:], encode.RandomBytes(32)) + initiations = append(initiations, dexeth.ETHSwapInitiation{ + RefundTimestamp: big.NewInt(1), + SecretHash: secretHash, + Participant: participantAddr, + Value: big.NewInt(1), + }) + } + data, err := parsedAbi.Pack("initiateBatch", initiations) + if err != nil { + t.Fatalf("unexpected error packing abi: %v", err) + } + msg := ethereum.CallMsg{ + From: participantAddr, + To: &contractAddr, + Value: big.NewInt(int64(i)), + Gas: 0, + Data: data, + } + gas, err := participantEthClient.estimateGas(ctx, msg) + if err != nil { + t.Fatalf("unexpected error from estimateGas: %v", err) + } + fmt.Printf("Gas used for batch initiating %v swaps: %v. %v more than previous \n", i, gas, gas-previousGas) + previousGas = gas + } +} + +func TestInitiateBatch(t *testing.T) { + err := ethClient.unlock(ctx, pw, simnetAcct) + if err != nil { + t.Fatal(err) + } + + // Create a slice of random secret hashes that can be used in the tests and + // make sure none of them have been used yet. + numSecretHashes := 10 + secretHashes := make([][32]byte, numSecretHashes) + for i := 0; i < numSecretHashes; i++ { + copy(secretHashes[i][:], encode.RandomBytes(32)) + swap, err := ethClient.swap(ctx, simnetAcct, secretHashes[i]) + if err != nil { + t.Fatal("unable to get swap state") + } + state := srveth.SwapState(swap.State) + if state != srveth.SSNone { + t.Fatalf("unexpected swap state: want %s got %s", srveth.SSNone, state) + } + } + + now := time.Now().Unix() + + intOverFlow := big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(1)) + maxInt := big.NewInt(0).Sub(intOverFlow, big.NewInt(1)) + + tests := []struct { + name string + swaps []dexeth.ETHSwapInitiation + success bool + txValue *big.Int + }{ + { + name: "1 swap ok", + success: true, + txValue: big.NewInt(1), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[0], + Participant: participantAddr, + Value: big.NewInt(1), + }, + }, + }, + { + name: "1 swap with existing hash", + success: false, + txValue: big.NewInt(1), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[0], + Participant: participantAddr, + Value: big.NewInt(1), + }, + }, + }, + { + name: "2 swaps ok", + success: true, + txValue: big.NewInt(2), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[1], + Participant: participantAddr, + Value: big.NewInt(1), + }, + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[2], + Participant: participantAddr, + Value: big.NewInt(1), + }, + }, + }, + { + name: "2 swaps repeated hash", + success: false, + txValue: big.NewInt(2), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[3], + Participant: participantAddr, + Value: big.NewInt(1), + }, + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[3], + Participant: participantAddr, + Value: big.NewInt(1), + }, + }, + }, + { + name: "1 swap nil refundtimestamp", + success: false, + txValue: big.NewInt(2), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(0), + SecretHash: secretHashes[4], + Participant: participantAddr, + Value: big.NewInt(1), + }, + }, + }, + { + // Preventing this used to need explicit checks before solidity 0.8, but now the + // compiler checks for integer overflows by default. + name: "integer overflow attack", + success: false, + txValue: big.NewInt(999), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[5], + Participant: participantAddr, + Value: maxInt, + }, + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[6], + Participant: participantAddr, + Value: big.NewInt(1000), + }, + }, + }, + { + name: "swap with 0 value", + success: false, + txValue: big.NewInt(1000), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[5], + Participant: participantAddr, + Value: big.NewInt(0), + }, + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[6], + Participant: participantAddr, + Value: big.NewInt(1000), + }, + }, + }, + { + name: "sum of swaps != msg.value", + success: false, + txValue: big.NewInt(99), + swaps: []dexeth.ETHSwapInitiation{ + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[5], + Participant: participantAddr, + Value: big.NewInt(50), + }, + { + RefundTimestamp: big.NewInt(now), + SecretHash: secretHashes[6], + Participant: participantAddr, + Value: big.NewInt(50), + }, + }, + }, + } + + for _, test := range tests { + originalBal, err := ethClient.balance(ctx, &simnetAddr) + if err != nil { + t.Fatalf("unexpected error for test %v: %v", test.name, err) + } + + originalStates := make(map[string]srveth.SwapState) + for _, testSwap := range test.swaps { + swap, err := ethClient.swap(ctx, simnetAcct, testSwap.SecretHash) + if err != nil { + t.Fatalf("unexpected error for test %v: %v", test.name, err) + } + originalStates[hex.EncodeToString(testSwap.SecretHash[:])] = srveth.SwapState(swap.State) + } + + txOpts := newTxOpts(ctx, &simnetAddr, test.txValue) + tx, err := ethClient.initiateBatch(txOpts, simnetID, test.swaps) + if err != nil { + t.Fatalf("unexpected error for test %v: %v", test.name, err) + } + spew.Dump(tx) + + if err := waitForMined(t, time.Second*10, false); err != nil { + t.Fatalf("unexpected error for test %v: %v", test.name, err) + } + + // It appears the receipt is only accessible after the tx is mined. + receipt, err := ethClient.transactionReceipt(ctx, tx.Hash()) + if err != nil { + t.Fatalf("unexpected error for test %v: %v", test.name, err) + } + spew.Dump(receipt) + + // Balance should be reduced by a certain amount depending on + // whether initiate completed successfully on-chain. If + // unsuccessful the fee is subtracted. If successful, amt is + // also subtracted. + bal, err := ethClient.balance(ctx, &simnetAddr) + if err != nil { + t.Fatalf("unexpected error for test %v: %v", test.name, err) + } + txFee := big.NewInt(0).Mul(big.NewInt(int64(receipt.GasUsed)), gasPrice) + wantBal := big.NewInt(0).Sub(originalBal, txFee) + if test.success { + wantBal.Sub(wantBal, test.txValue) + } + if bal.Cmp(wantBal) != 0 { + t.Fatalf("unexpected balance change for test %v: want %v got %v", test.name, wantBal, bal) + } + + for _, testSwap := range test.swaps { + swap, err := ethClient.swap(ctx, simnetAcct, testSwap.SecretHash) + if err != nil { + t.Fatalf("unexpected error for test %v: %v", test.name, err) + } + state := srveth.SwapState(swap.State) + if test.success && state != srveth.SSInitiated { + t.Fatalf("unexpected swap state for test %v: want %s got %s", test.name, srveth.SSInitiated, state) + } + + originalState := originalStates[hex.EncodeToString(testSwap.SecretHash[:])] + if !test.success && state != originalState { + t.Fatalf("unexpected swap state for test %v: want %s got %s", test.name, originalState, state) + } + } + } +} + func TestInitiate(t *testing.T) { now := time.Now().Unix() var secretHash [32]byte @@ -472,7 +750,7 @@ func TestInitiate(t *testing.T) { t.Fatalf("unexpected error for test %v: %v", test.name, err) } - // It appears the receipt is only accessable after the tx is mined. + // It appears the receipt is only accessible after the tx is mined. receipt, err := ethClient.transactionReceipt(ctx, tx.Hash()) if err != nil { t.Fatalf("unexpected error for test %v: %v", test.name, err) @@ -641,7 +919,7 @@ func TestRedeem(t *testing.T) { t.Fatalf("unexpected error for test %v: %v", test.name, err) } - // It appears the receipt is only accessable after the tx is mined. + // It appears the receipt is only accessible after the tx is mined. receipt, err := test.redeemerClient.transactionReceipt(ctx, tx.Hash()) if err != nil { t.Fatalf("unexpected error for test %v: %v", test.name, err) @@ -775,7 +1053,7 @@ func TestRefund(t *testing.T) { t.Fatalf("unexpected error for test %v: %v", test.name, err) } - // It appears the receipt is only accessable after the tx is mined. + // It appears the receipt is only accessible after the tx is mined. receipt, err := test.refunderClient.transactionReceipt(ctx, tx.Hash()) if err != nil { t.Fatalf("unexpected error for test %v: %v", test.name, err) diff --git a/dex/networks/eth/BinRuntimeV0.go b/dex/networks/eth/BinRuntimeV0.go index 923a45cfb3..b030270d6e 100644 --- a/dex/networks/eth/BinRuntimeV0.go +++ b/dex/networks/eth/BinRuntimeV0.go @@ -3,4 +3,4 @@ package eth -const ETHSwapRuntimeBin = "60806040526004361061004a5760003560e01c80637249fbb61461004f57806376467cbd14610071578063ae052147146100a7578063b31597ad146100ba578063eb84e7f2146100da575b600080fd5b34801561005b57600080fd5b5061006f61006a36600461057d565b61015c565b005b34801561007d57600080fd5b5061009161008c36600461057d565b61025e565b60405161009e9190610673565b60405180910390f35b61006f6100b53660046105d1565b610349565b3480156100c657600080fd5b5061006f6100d53660046105af565b61040e565b3480156100e657600080fd5b506101486100f536600461057d565b6000602081905290815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492936001600160a01b0392831693919092169160ff1688565b60405161009e9897969594939291906106e3565b32331461016857600080fd5b80600160008281526020819052604090206007015460ff16600381111561019157610191610738565b1461019b57600080fd5b6000818152602081905260409020600401546001600160a01b031633146101c157600080fd5b600081815260208190526040902060010154428111156101e057600080fd5b60008381526020819052604080822060078101805460ff191660031790556006015490513391908381818185875af1925050503d806000811461023f576040519150601f19603f3d011682016040523d82523d6000602084013e610244565b606091505b509091505060018115151461025857600080fd5b50505050565b6102a36040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290529060e082015290565b6000828152602081815260409182902082516101008101845281548152600182015492810192909252600281015492820192909252600380830154606083015260048301546001600160a01b03908116608084015260058401541660a0830152600683015460c0830152600783015491929160e084019160ff9091169081111561032f5761032f610738565b600381111561034057610340610738565b90525092915050565b826000341161035757600080fd5b6000811161036457600080fd5b32331461037057600080fd5b826000808281526020819052604090206007015460ff16600381111561039857610398610738565b146103a257600080fd5b6000848152602081905260409020438155600180820187905560028201869055600482018054336001600160a01b0319918216179091556005830180549091166001600160a01b0387161790553460068301556007909101805460ff1916828002179055505050505050565b32331461041a57600080fd5b8082600160008381526020819052604090206007015460ff16600381111561044457610444610738565b1461044e57600080fd5b6000828152602081905260409020600501546001600160a01b0316331461047457600080fd5b8160028260405160200161048a91815260200190565b60408051601f19818403018152908290526104a491610638565b602060405180830381855afa1580156104c1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906104e49190610596565b146104ee57600080fd5b60008381526020819052604080822060078101805460ff191660021790556006015490513391908381818185875af1925050503d806000811461054d576040519150601f19603f3d011682016040523d82523d6000602084013e610552565b606091505b509091505060018115151461056657600080fd5b505050600090815260208190526040902060030155565b60006020828403121561058f57600080fd5b5035919050565b6000602082840312156105a857600080fd5b5051919050565b600080604083850312156105c257600080fd5b50508035926020909101359150565b6000806000606084860312156105e657600080fd5b833592506020840135915060408401356001600160a01b038116811461060b57600080fd5b809150509250925092565b6004811061063457634e487b7160e01b600052602160045260246000fd5b9052565b6000825160005b81811015610659576020818601810151858301520161063f565b81811115610668576000828501525b509190910192915050565b60006101008201905082518252602083015160208301526040830151604083015260608301516060830152608083015160018060a01b0380821660808501528060a08601511660a0850152505060c083015160c083015260e08301516106dc60e0840182610616565b5092915050565b8881526020810188905260408101879052606081018690526001600160a01b038581166080830152841660a082015260c08101839052610100810161072b60e0830184610616565b9998505050505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220f5008532d651b31b24a7d133ff5dd0c4461e5f6339f32c9d551cb9cf81107e6b64736f6c63430008060033" +const ETHSwapRuntimeBin = "6080604052600436106100555760003560e01c806358ac45f51461005a5780637249fbb61461006f57806376467cbd1461008f578063ae052147146100c5578063b31597ad146100d8578063eb84e7f2146100f8575b600080fd5b61006d6100683660046106e3565b610172565b005b34801561007b57600080fd5b5061006d61008a366004610758565b61029e565b34801561009b57600080fd5b506100af6100aa366004610758565b6103a0565b6040516100bc919061083e565b60405180910390f35b61006d6100d33660046107ac565b610478565b3480156100e457600080fd5b5061006d6100f336600461078a565b610536565b34801561010457600080fd5b5061015f610113366004610758565b60006020819052908152604090208054600182015460028301546003840154600485015460058601546006909601549495939492936001600160a01b0392831693929091169160ff1687565b6040516100bc97969594939291906108a3565b32331461017e57600080fd5b6000805b8281101561028c573684848381811061019d5761019d61094e565b9050608002019050600080600083602001358152602001908152602001600020905060008260600135116101d057600080fd5b81356101db57600080fd5b6000600682015460ff1660038111156101f6576101f6610938565b1461020057600080fd5b438155813560018201556003810180546001600160a01b0319163317905561022e60608301604084016106c1565b6004820180546001600160a01b0319166001600160a01b039290921691909117905560608201356005820181905560068201805460ff1916600117905561027590856108ef565b93505050808061028490610907565b915050610182565b5034811461029957600080fd5b505050565b3233146102aa57600080fd5b80600160008281526020819052604090206006015460ff1660038111156102d3576102d3610938565b146102dd57600080fd5b6000818152602081905260409020600301546001600160a01b0316331461030357600080fd5b6000818152602081905260409020600101544281111561032257600080fd5b60008381526020819052604080822060068101805460ff191660031790556005015490513391908381818185875af1925050503d8060008114610381576040519150601f19603f3d011682016040523d82523d6000602084013e610386565b606091505b509091505060018115151461039a57600080fd5b50505050565b6103dd6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c082015290565b60008281526020818152604091829020825160e081018452815481526001820154928101929092526002810154928201929092526003808301546001600160a01b0390811660608401526004840154166080830152600583015460a0830152600683015491929160c084019160ff9091169081111561045e5761045e610938565b600381111561046f5761046f610938565b90525092915050565b826000341161048657600080fd5b6000811161049357600080fd5b32331461049f57600080fd5b826000808281526020819052604090206006015460ff1660038111156104c7576104c7610938565b146104d157600080fd5b60008481526020819052604090204381556001808201879055600382018054336001600160a01b0319918216179091556004830180549091166001600160a01b03871617905534600583015560068201805460ff191682800217905550505050505050565b32331461054257600080fd5b8082600160008381526020819052604090206006015460ff16600381111561056c5761056c610938565b1461057657600080fd5b6000828152602081905260409020600401546001600160a01b0316331461059c57600080fd5b816002826040516020016105b291815260200190565b60408051601f19818403018152908290526105cc91610803565b602060405180830381855afa1580156105e9573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061060c9190610771565b1461061657600080fd5b60008381526020819052604080822060068101805460ff191660021790556005015490513391908381818185875af1925050503d8060008114610675576040519150601f19603f3d011682016040523d82523d6000602084013e61067a565b606091505b509091505060018115151461068e57600080fd5b505050600090815260208190526040902060020155565b80356001600160a01b03811681146106bc57600080fd5b919050565b6000602082840312156106d357600080fd5b6106dc826106a5565b9392505050565b600080602083850312156106f657600080fd5b823567ffffffffffffffff8082111561070e57600080fd5b818501915085601f83011261072257600080fd5b81358181111561073157600080fd5b8660208260071b850101111561074657600080fd5b60209290920196919550909350505050565b60006020828403121561076a57600080fd5b5035919050565b60006020828403121561078357600080fd5b5051919050565b6000806040838503121561079d57600080fd5b50508035926020909101359150565b6000806000606084860312156107c157600080fd5b83359250602084013591506107d8604085016106a5565b90509250925092565b600481106107ff57634e487b7160e01b600052602160045260246000fd5b9052565b6000825160005b81811015610824576020818601810151858301520161080a565b81811115610833576000828501525b509190910192915050565b600060e082019050825182526020830151602083015260408301516040830152606083015160018060a01b038082166060850152806080860151166080850152505060a083015160a083015260c083015161089c60c08401826107e1565b5092915050565b87815260208101879052604081018690526001600160a01b0385811660608301528416608082015260a0810183905260e081016108e360c08301846107e1565b98975050505050505050565b6000821982111561090257610902610922565b500190565b600060001982141561091b5761091b610922565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220adfd4cb419e368c3af5d1d3c6ec2039d2c5eb3b75584a75ee0226c403fb5a68164736f6c63430008060033" diff --git a/dex/networks/eth/contract.go b/dex/networks/eth/contract.go index 45030cfc8e..e3c984527f 100644 --- a/dex/networks/eth/contract.go +++ b/dex/networks/eth/contract.go @@ -26,11 +26,18 @@ var ( _ = event.NewSubscription ) +// ETHSwapInitiation is an auto generated low-level Go binding around an user-defined struct. +type ETHSwapInitiation struct { + RefundTimestamp *big.Int + SecretHash [32]byte + Participant common.Address + Value *big.Int +} + // ETHSwapSwap is an auto generated low-level Go binding around an user-defined struct. type ETHSwapSwap struct { InitBlockNumber *big.Int RefundBlockTimestamp *big.Int - SecretHash [32]byte Secret [32]byte Initiator common.Address Participant common.Address @@ -39,11 +46,12 @@ type ETHSwapSwap struct { } // ETHSwapABI is the input ABI used to generate the binding from. -const ETHSwapABI = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"refundTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"participant\",\"type\":\"address\"}],\"name\":\"initiate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"}],\"name\":\"redeem\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"}],\"name\":\"refund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"}],\"name\":\"swap\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"initBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"refundBlockTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"participant\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"enumETHSwap.State\",\"name\":\"state\",\"type\":\"uint8\"}],\"internalType\":\"structETHSwap.Swap\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"swaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"refundBlockTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"participant\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"enumETHSwap.State\",\"name\":\"state\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" +const ETHSwapABI = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"refundTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"participant\",\"type\":\"address\"}],\"name\":\"initiate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"refundTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"participant\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"internalType\":\"structETHSwap.Initiation[]\",\"name\":\"initiations\",\"type\":\"tuple[]\"}],\"name\":\"initiateBatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"}],\"name\":\"redeem\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"}],\"name\":\"refund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"secretHash\",\"type\":\"bytes32\"}],\"name\":\"swap\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"initBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"refundBlockTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"participant\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"enumETHSwap.State\",\"name\":\"state\",\"type\":\"uint8\"}],\"internalType\":\"structETHSwap.Swap\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"swaps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"initBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"refundBlockTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"secret\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"participant\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"enumETHSwap.State\",\"name\":\"state\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" // ETHSwapFuncSigs maps the 4-byte function signature to its string representation. var ETHSwapFuncSigs = map[string]string{ "ae052147": "initiate(uint256,bytes32,address)", + "58ac45f5": "initiateBatch((uint256,bytes32,address,uint256)[])", "b31597ad": "redeem(bytes32,bytes32)", "7249fbb6": "refund(bytes32)", "76467cbd": "swap(bytes32)", @@ -51,7 +59,7 @@ var ETHSwapFuncSigs = map[string]string{ } // ETHSwapBin is the compiled bytecode used for deploying new contracts. -var ETHSwapBin = "0x608060405234801561001057600080fd5b50610784806100206000396000f3fe60806040526004361061004a5760003560e01c80637249fbb61461004f57806376467cbd14610071578063ae052147146100a7578063b31597ad146100ba578063eb84e7f2146100da575b600080fd5b34801561005b57600080fd5b5061006f61006a36600461057d565b61015c565b005b34801561007d57600080fd5b5061009161008c36600461057d565b61025e565b60405161009e9190610673565b60405180910390f35b61006f6100b53660046105d1565b610349565b3480156100c657600080fd5b5061006f6100d53660046105af565b61040e565b3480156100e657600080fd5b506101486100f536600461057d565b6000602081905290815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492936001600160a01b0392831693919092169160ff1688565b60405161009e9897969594939291906106e3565b32331461016857600080fd5b80600160008281526020819052604090206007015460ff16600381111561019157610191610738565b1461019b57600080fd5b6000818152602081905260409020600401546001600160a01b031633146101c157600080fd5b600081815260208190526040902060010154428111156101e057600080fd5b60008381526020819052604080822060078101805460ff191660031790556006015490513391908381818185875af1925050503d806000811461023f576040519150601f19603f3d011682016040523d82523d6000602084013e610244565b606091505b509091505060018115151461025857600080fd5b50505050565b6102a36040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290529060e082015290565b6000828152602081815260409182902082516101008101845281548152600182015492810192909252600281015492820192909252600380830154606083015260048301546001600160a01b03908116608084015260058401541660a0830152600683015460c0830152600783015491929160e084019160ff9091169081111561032f5761032f610738565b600381111561034057610340610738565b90525092915050565b826000341161035757600080fd5b6000811161036457600080fd5b32331461037057600080fd5b826000808281526020819052604090206007015460ff16600381111561039857610398610738565b146103a257600080fd5b6000848152602081905260409020438155600180820187905560028201869055600482018054336001600160a01b0319918216179091556005830180549091166001600160a01b0387161790553460068301556007909101805460ff1916828002179055505050505050565b32331461041a57600080fd5b8082600160008381526020819052604090206007015460ff16600381111561044457610444610738565b1461044e57600080fd5b6000828152602081905260409020600501546001600160a01b0316331461047457600080fd5b8160028260405160200161048a91815260200190565b60408051601f19818403018152908290526104a491610638565b602060405180830381855afa1580156104c1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906104e49190610596565b146104ee57600080fd5b60008381526020819052604080822060078101805460ff191660021790556006015490513391908381818185875af1925050503d806000811461054d576040519150601f19603f3d011682016040523d82523d6000602084013e610552565b606091505b509091505060018115151461056657600080fd5b505050600090815260208190526040902060030155565b60006020828403121561058f57600080fd5b5035919050565b6000602082840312156105a857600080fd5b5051919050565b600080604083850312156105c257600080fd5b50508035926020909101359150565b6000806000606084860312156105e657600080fd5b833592506020840135915060408401356001600160a01b038116811461060b57600080fd5b809150509250925092565b6004811061063457634e487b7160e01b600052602160045260246000fd5b9052565b6000825160005b81811015610659576020818601810151858301520161063f565b81811115610668576000828501525b509190910192915050565b60006101008201905082518252602083015160208301526040830151604083015260608301516060830152608083015160018060a01b0380821660808501528060a08601511660a0850152505060c083015160c083015260e08301516106dc60e0840182610616565b5092915050565b8881526020810188905260408101879052606081018690526001600160a01b038581166080830152841660a082015260c08101839052610100810161072b60e0830184610616565b9998505050505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220f5008532d651b31b24a7d133ff5dd0c4461e5f6339f32c9d551cb9cf81107e6b64736f6c63430008060033" +var ETHSwapBin = "0x608060405234801561001057600080fd5b5061099a806100206000396000f3fe6080604052600436106100555760003560e01c806358ac45f51461005a5780637249fbb61461006f57806376467cbd1461008f578063ae052147146100c5578063b31597ad146100d8578063eb84e7f2146100f8575b600080fd5b61006d6100683660046106e3565b610172565b005b34801561007b57600080fd5b5061006d61008a366004610758565b61029e565b34801561009b57600080fd5b506100af6100aa366004610758565b6103a0565b6040516100bc919061083e565b60405180910390f35b61006d6100d33660046107ac565b610478565b3480156100e457600080fd5b5061006d6100f336600461078a565b610536565b34801561010457600080fd5b5061015f610113366004610758565b60006020819052908152604090208054600182015460028301546003840154600485015460058601546006909601549495939492936001600160a01b0392831693929091169160ff1687565b6040516100bc97969594939291906108a3565b32331461017e57600080fd5b6000805b8281101561028c573684848381811061019d5761019d61094e565b9050608002019050600080600083602001358152602001908152602001600020905060008260600135116101d057600080fd5b81356101db57600080fd5b6000600682015460ff1660038111156101f6576101f6610938565b1461020057600080fd5b438155813560018201556003810180546001600160a01b0319163317905561022e60608301604084016106c1565b6004820180546001600160a01b0319166001600160a01b039290921691909117905560608201356005820181905560068201805460ff1916600117905561027590856108ef565b93505050808061028490610907565b915050610182565b5034811461029957600080fd5b505050565b3233146102aa57600080fd5b80600160008281526020819052604090206006015460ff1660038111156102d3576102d3610938565b146102dd57600080fd5b6000818152602081905260409020600301546001600160a01b0316331461030357600080fd5b6000818152602081905260409020600101544281111561032257600080fd5b60008381526020819052604080822060068101805460ff191660031790556005015490513391908381818185875af1925050503d8060008114610381576040519150601f19603f3d011682016040523d82523d6000602084013e610386565b606091505b509091505060018115151461039a57600080fd5b50505050565b6103dd6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c082015290565b60008281526020818152604091829020825160e081018452815481526001820154928101929092526002810154928201929092526003808301546001600160a01b0390811660608401526004840154166080830152600583015460a0830152600683015491929160c084019160ff9091169081111561045e5761045e610938565b600381111561046f5761046f610938565b90525092915050565b826000341161048657600080fd5b6000811161049357600080fd5b32331461049f57600080fd5b826000808281526020819052604090206006015460ff1660038111156104c7576104c7610938565b146104d157600080fd5b60008481526020819052604090204381556001808201879055600382018054336001600160a01b0319918216179091556004830180549091166001600160a01b03871617905534600583015560068201805460ff191682800217905550505050505050565b32331461054257600080fd5b8082600160008381526020819052604090206006015460ff16600381111561056c5761056c610938565b1461057657600080fd5b6000828152602081905260409020600401546001600160a01b0316331461059c57600080fd5b816002826040516020016105b291815260200190565b60408051601f19818403018152908290526105cc91610803565b602060405180830381855afa1580156105e9573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061060c9190610771565b1461061657600080fd5b60008381526020819052604080822060068101805460ff191660021790556005015490513391908381818185875af1925050503d8060008114610675576040519150601f19603f3d011682016040523d82523d6000602084013e61067a565b606091505b509091505060018115151461068e57600080fd5b505050600090815260208190526040902060020155565b80356001600160a01b03811681146106bc57600080fd5b919050565b6000602082840312156106d357600080fd5b6106dc826106a5565b9392505050565b600080602083850312156106f657600080fd5b823567ffffffffffffffff8082111561070e57600080fd5b818501915085601f83011261072257600080fd5b81358181111561073157600080fd5b8660208260071b850101111561074657600080fd5b60209290920196919550909350505050565b60006020828403121561076a57600080fd5b5035919050565b60006020828403121561078357600080fd5b5051919050565b6000806040838503121561079d57600080fd5b50508035926020909101359150565b6000806000606084860312156107c157600080fd5b83359250602084013591506107d8604085016106a5565b90509250925092565b600481106107ff57634e487b7160e01b600052602160045260246000fd5b9052565b6000825160005b81811015610824576020818601810151858301520161080a565b81811115610833576000828501525b509190910192915050565b600060e082019050825182526020830151602083015260408301516040830152606083015160018060a01b038082166060850152806080860151166080850152505060a083015160a083015260c083015161089c60c08401826107e1565b5092915050565b87815260208101879052604081018690526001600160a01b0385811660608301528416608082015260a0810183905260e081016108e360c08301846107e1565b98975050505050505050565b6000821982111561090257610902610922565b500190565b600060001982141561091b5761091b610922565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220adfd4cb419e368c3af5d1d3c6ec2039d2c5eb3b75584a75ee0226c403fb5a68164736f6c63430008060033" // DeployETHSwap deploys a new Ethereum contract, binding an instance of ETHSwap to it. func DeployETHSwap(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ETHSwap, error) { @@ -211,7 +219,7 @@ func (_ETHSwap *ETHSwapTransactorRaw) Transact(opts *bind.TransactOpts, method s // Swap is a free data retrieval call binding the contract method 0x76467cbd. // -// Solidity: function swap(bytes32 secretHash) view returns((uint256,uint256,bytes32,bytes32,address,address,uint256,uint8)) +// Solidity: function swap(bytes32 secretHash) view returns((uint256,uint256,bytes32,address,address,uint256,uint8)) func (_ETHSwap *ETHSwapCaller) Swap(opts *bind.CallOpts, secretHash [32]byte) (ETHSwapSwap, error) { var out []interface{} err := _ETHSwap.contract.Call(opts, &out, "swap", secretHash) @@ -228,25 +236,24 @@ func (_ETHSwap *ETHSwapCaller) Swap(opts *bind.CallOpts, secretHash [32]byte) (E // Swap is a free data retrieval call binding the contract method 0x76467cbd. // -// Solidity: function swap(bytes32 secretHash) view returns((uint256,uint256,bytes32,bytes32,address,address,uint256,uint8)) +// Solidity: function swap(bytes32 secretHash) view returns((uint256,uint256,bytes32,address,address,uint256,uint8)) func (_ETHSwap *ETHSwapSession) Swap(secretHash [32]byte) (ETHSwapSwap, error) { return _ETHSwap.Contract.Swap(&_ETHSwap.CallOpts, secretHash) } // Swap is a free data retrieval call binding the contract method 0x76467cbd. // -// Solidity: function swap(bytes32 secretHash) view returns((uint256,uint256,bytes32,bytes32,address,address,uint256,uint8)) +// Solidity: function swap(bytes32 secretHash) view returns((uint256,uint256,bytes32,address,address,uint256,uint8)) func (_ETHSwap *ETHSwapCallerSession) Swap(secretHash [32]byte) (ETHSwapSwap, error) { return _ETHSwap.Contract.Swap(&_ETHSwap.CallOpts, secretHash) } // Swaps is a free data retrieval call binding the contract method 0xeb84e7f2. // -// Solidity: function swaps(bytes32 ) view returns(uint256 initBlockNumber, uint256 refundBlockTimestamp, bytes32 secretHash, bytes32 secret, address initiator, address participant, uint256 value, uint8 state) +// Solidity: function swaps(bytes32 ) view returns(uint256 initBlockNumber, uint256 refundBlockTimestamp, bytes32 secret, address initiator, address participant, uint256 value, uint8 state) func (_ETHSwap *ETHSwapCaller) Swaps(opts *bind.CallOpts, arg0 [32]byte) (struct { InitBlockNumber *big.Int RefundBlockTimestamp *big.Int - SecretHash [32]byte Secret [32]byte Initiator common.Address Participant common.Address @@ -259,7 +266,6 @@ func (_ETHSwap *ETHSwapCaller) Swaps(opts *bind.CallOpts, arg0 [32]byte) (struct outstruct := new(struct { InitBlockNumber *big.Int RefundBlockTimestamp *big.Int - SecretHash [32]byte Secret [32]byte Initiator common.Address Participant common.Address @@ -272,12 +278,11 @@ func (_ETHSwap *ETHSwapCaller) Swaps(opts *bind.CallOpts, arg0 [32]byte) (struct outstruct.InitBlockNumber = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) outstruct.RefundBlockTimestamp = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.SecretHash = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) - outstruct.Secret = *abi.ConvertType(out[3], new([32]byte)).(*[32]byte) - outstruct.Initiator = *abi.ConvertType(out[4], new(common.Address)).(*common.Address) - outstruct.Participant = *abi.ConvertType(out[5], new(common.Address)).(*common.Address) - outstruct.Value = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) - outstruct.State = *abi.ConvertType(out[7], new(uint8)).(*uint8) + outstruct.Secret = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + outstruct.Initiator = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) + outstruct.Participant = *abi.ConvertType(out[4], new(common.Address)).(*common.Address) + outstruct.Value = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.State = *abi.ConvertType(out[6], new(uint8)).(*uint8) return *outstruct, err @@ -285,11 +290,10 @@ func (_ETHSwap *ETHSwapCaller) Swaps(opts *bind.CallOpts, arg0 [32]byte) (struct // Swaps is a free data retrieval call binding the contract method 0xeb84e7f2. // -// Solidity: function swaps(bytes32 ) view returns(uint256 initBlockNumber, uint256 refundBlockTimestamp, bytes32 secretHash, bytes32 secret, address initiator, address participant, uint256 value, uint8 state) +// Solidity: function swaps(bytes32 ) view returns(uint256 initBlockNumber, uint256 refundBlockTimestamp, bytes32 secret, address initiator, address participant, uint256 value, uint8 state) func (_ETHSwap *ETHSwapSession) Swaps(arg0 [32]byte) (struct { InitBlockNumber *big.Int RefundBlockTimestamp *big.Int - SecretHash [32]byte Secret [32]byte Initiator common.Address Participant common.Address @@ -301,11 +305,10 @@ func (_ETHSwap *ETHSwapSession) Swaps(arg0 [32]byte) (struct { // Swaps is a free data retrieval call binding the contract method 0xeb84e7f2. // -// Solidity: function swaps(bytes32 ) view returns(uint256 initBlockNumber, uint256 refundBlockTimestamp, bytes32 secretHash, bytes32 secret, address initiator, address participant, uint256 value, uint8 state) +// Solidity: function swaps(bytes32 ) view returns(uint256 initBlockNumber, uint256 refundBlockTimestamp, bytes32 secret, address initiator, address participant, uint256 value, uint8 state) func (_ETHSwap *ETHSwapCallerSession) Swaps(arg0 [32]byte) (struct { InitBlockNumber *big.Int RefundBlockTimestamp *big.Int - SecretHash [32]byte Secret [32]byte Initiator common.Address Participant common.Address @@ -336,6 +339,27 @@ func (_ETHSwap *ETHSwapTransactorSession) Initiate(refundTimestamp *big.Int, sec return _ETHSwap.Contract.Initiate(&_ETHSwap.TransactOpts, refundTimestamp, secretHash, participant) } +// InitiateBatch is a paid mutator transaction binding the contract method 0x58ac45f5. +// +// Solidity: function initiateBatch((uint256,bytes32,address,uint256)[] initiations) payable returns() +func (_ETHSwap *ETHSwapTransactor) InitiateBatch(opts *bind.TransactOpts, initiations []ETHSwapInitiation) (*types.Transaction, error) { + return _ETHSwap.contract.Transact(opts, "initiateBatch", initiations) +} + +// InitiateBatch is a paid mutator transaction binding the contract method 0x58ac45f5. +// +// Solidity: function initiateBatch((uint256,bytes32,address,uint256)[] initiations) payable returns() +func (_ETHSwap *ETHSwapSession) InitiateBatch(initiations []ETHSwapInitiation) (*types.Transaction, error) { + return _ETHSwap.Contract.InitiateBatch(&_ETHSwap.TransactOpts, initiations) +} + +// InitiateBatch is a paid mutator transaction binding the contract method 0x58ac45f5. +// +// Solidity: function initiateBatch((uint256,bytes32,address,uint256)[] initiations) payable returns() +func (_ETHSwap *ETHSwapTransactorSession) InitiateBatch(initiations []ETHSwapInitiation) (*types.Transaction, error) { + return _ETHSwap.Contract.InitiateBatch(&_ETHSwap.TransactOpts, initiations) +} + // Redeem is a paid mutator transaction binding the contract method 0xb31597ad. // // Solidity: function redeem(bytes32 secret, bytes32 secretHash) returns() diff --git a/dex/networks/eth/contracts/ETHSwapV0.sol b/dex/networks/eth/contracts/ETHSwapV0.sol index 81f8d7a654..7df681865d 100644 --- a/dex/networks/eth/contracts/ETHSwapV0.sol +++ b/dex/networks/eth/contracts/ETHSwapV0.sol @@ -34,7 +34,6 @@ contract ETHSwap { struct Swap { uint initBlockNumber; uint refundBlockTimestamp; - bytes32 secretHash; bytes32 secret; address initiator; address participant; @@ -118,13 +117,59 @@ contract ETHSwap { senderIsOrigin() isNotInitiated(secretHash) { - swaps[secretHash].initBlockNumber = block.number; - swaps[secretHash].refundBlockTimestamp = refundTimestamp; - swaps[secretHash].secretHash = secretHash; - swaps[secretHash].initiator = msg.sender; - swaps[secretHash].participant = participant; - swaps[secretHash].value = msg.value; - swaps[secretHash].state = State.Filled; + Swap storage swapToUpdate = swaps[secretHash]; + + swapToUpdate.initBlockNumber = block.number; + swapToUpdate.refundBlockTimestamp = refundTimestamp; + swapToUpdate.initiator = msg.sender; + swapToUpdate.participant = participant; + swapToUpdate.value = msg.value; + swapToUpdate.state = State.Filled; + } + + struct Initiation { + uint refundTimestamp; + bytes32 secretHash; + address participant; + uint value; + } + + // initiateBatch initiates an array of swaps. It checks that all of the + // swaps have a non zero redemptionTimestamp and value, and that none of + // the secret hashes have ever been used previously. The function also makes + // sure that msg.value is equal to the sum of the values of all the swaps. + // Once initiated, each swap's state is set to Filled. The msg.value is now + // in the custody of the contract and can only be retrieved through redeem + // or refund. + // + // This is a writing function and requires gas. Failure or success should + // be guaged by querying the swap and checking state after being mined. Gas + // is expended either way. + function initiateBatch(Initiation[] calldata initiations) + public + payable + senderIsOrigin() + { + uint initVal = 0; + for (uint i = 0; i < initiations.length; i++) { + Initiation calldata initiation = initiations[i]; + Swap storage swapToUpdate = swaps[initiation.secretHash]; + + require(initiation.value > 0); + require(initiation.refundTimestamp > 0); + require(swapToUpdate.state == State.Empty); + + swapToUpdate.initBlockNumber = block.number; + swapToUpdate.refundBlockTimestamp = initiation.refundTimestamp; + swapToUpdate.initiator = msg.sender; + swapToUpdate.participant = initiation.participant; + swapToUpdate.value = initiation.value; + swapToUpdate.state = State.Filled; + + initVal += initiation.value; + } + + require(initVal == msg.value); } // redeem redeems a contract. It checks that the sender is not a contract, diff --git a/dex/testing/eth/harness.sh b/dex/testing/eth/harness.sh index dcd72291cb..5e97b50aff 100755 --- a/dex/testing/eth/harness.sh +++ b/dex/testing/eth/harness.sh @@ -44,7 +44,7 @@ DELTA_NODE_PORT="30307" # TESTING_ADDRESS is used by the client's internal node. TESTING_ADDRESS="b6de8bb5ed28e6be6d671975cad20c03931be981" -ETH_SWAP_V0="608060405234801561001057600080fd5b50610784806100206000396000f3fe60806040526004361061004a5760003560e01c80637249fbb61461004f57806376467cbd14610071578063ae052147146100a7578063b31597ad146100ba578063eb84e7f2146100da575b600080fd5b34801561005b57600080fd5b5061006f61006a36600461057d565b61015c565b005b34801561007d57600080fd5b5061009161008c36600461057d565b61025e565b60405161009e9190610673565b60405180910390f35b61006f6100b53660046105d1565b610349565b3480156100c657600080fd5b5061006f6100d53660046105af565b61040e565b3480156100e657600080fd5b506101486100f536600461057d565b6000602081905290815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492936001600160a01b0392831693919092169160ff1688565b60405161009e9897969594939291906106e3565b32331461016857600080fd5b80600160008281526020819052604090206007015460ff16600381111561019157610191610738565b1461019b57600080fd5b6000818152602081905260409020600401546001600160a01b031633146101c157600080fd5b600081815260208190526040902060010154428111156101e057600080fd5b60008381526020819052604080822060078101805460ff191660031790556006015490513391908381818185875af1925050503d806000811461023f576040519150601f19603f3d011682016040523d82523d6000602084013e610244565b606091505b509091505060018115151461025857600080fd5b50505050565b6102a36040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290529060e082015290565b6000828152602081815260409182902082516101008101845281548152600182015492810192909252600281015492820192909252600380830154606083015260048301546001600160a01b03908116608084015260058401541660a0830152600683015460c0830152600783015491929160e084019160ff9091169081111561032f5761032f610738565b600381111561034057610340610738565b90525092915050565b826000341161035757600080fd5b6000811161036457600080fd5b32331461037057600080fd5b826000808281526020819052604090206007015460ff16600381111561039857610398610738565b146103a257600080fd5b6000848152602081905260409020438155600180820187905560028201869055600482018054336001600160a01b0319918216179091556005830180549091166001600160a01b0387161790553460068301556007909101805460ff1916828002179055505050505050565b32331461041a57600080fd5b8082600160008381526020819052604090206007015460ff16600381111561044457610444610738565b1461044e57600080fd5b6000828152602081905260409020600501546001600160a01b0316331461047457600080fd5b8160028260405160200161048a91815260200190565b60408051601f19818403018152908290526104a491610638565b602060405180830381855afa1580156104c1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906104e49190610596565b146104ee57600080fd5b60008381526020819052604080822060078101805460ff191660021790556006015490513391908381818185875af1925050503d806000811461054d576040519150601f19603f3d011682016040523d82523d6000602084013e610552565b606091505b509091505060018115151461056657600080fd5b505050600090815260208190526040902060030155565b60006020828403121561058f57600080fd5b5035919050565b6000602082840312156105a857600080fd5b5051919050565b600080604083850312156105c257600080fd5b50508035926020909101359150565b6000806000606084860312156105e657600080fd5b833592506020840135915060408401356001600160a01b038116811461060b57600080fd5b809150509250925092565b6004811061063457634e487b7160e01b600052602160045260246000fd5b9052565b6000825160005b81811015610659576020818601810151858301520161063f565b81811115610668576000828501525b509190910192915050565b60006101008201905082518252602083015160208301526040830151604083015260608301516060830152608083015160018060a01b0380821660808501528060a08601511660a0850152505060c083015160c083015260e08301516106dc60e0840182610616565b5092915050565b8881526020810188905260408101879052606081018690526001600160a01b038581166080830152841660a082015260c08101839052610100810161072b60e0830184610616565b9998505050505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220f5008532d651b31b24a7d133ff5dd0c4461e5f6339f32c9d551cb9cf81107e6b64736f6c63430008060033" +ETH_SWAP_V0="608060405234801561001057600080fd5b5061099a806100206000396000f3fe6080604052600436106100555760003560e01c806358ac45f51461005a5780637249fbb61461006f57806376467cbd1461008f578063ae052147146100c5578063b31597ad146100d8578063eb84e7f2146100f8575b600080fd5b61006d6100683660046106e3565b610172565b005b34801561007b57600080fd5b5061006d61008a366004610758565b61029e565b34801561009b57600080fd5b506100af6100aa366004610758565b6103a0565b6040516100bc919061083e565b60405180910390f35b61006d6100d33660046107ac565b610478565b3480156100e457600080fd5b5061006d6100f336600461078a565b610536565b34801561010457600080fd5b5061015f610113366004610758565b60006020819052908152604090208054600182015460028301546003840154600485015460058601546006909601549495939492936001600160a01b0392831693929091169160ff1687565b6040516100bc97969594939291906108a3565b32331461017e57600080fd5b6000805b8281101561028c573684848381811061019d5761019d61094e565b9050608002019050600080600083602001358152602001908152602001600020905060008260600135116101d057600080fd5b81356101db57600080fd5b6000600682015460ff1660038111156101f6576101f6610938565b1461020057600080fd5b438155813560018201556003810180546001600160a01b0319163317905561022e60608301604084016106c1565b6004820180546001600160a01b0319166001600160a01b039290921691909117905560608201356005820181905560068201805460ff1916600117905561027590856108ef565b93505050808061028490610907565b915050610182565b5034811461029957600080fd5b505050565b3233146102aa57600080fd5b80600160008281526020819052604090206006015460ff1660038111156102d3576102d3610938565b146102dd57600080fd5b6000818152602081905260409020600301546001600160a01b0316331461030357600080fd5b6000818152602081905260409020600101544281111561032257600080fd5b60008381526020819052604080822060068101805460ff191660031790556005015490513391908381818185875af1925050503d8060008114610381576040519150601f19603f3d011682016040523d82523d6000602084013e610386565b606091505b509091505060018115151461039a57600080fd5b50505050565b6103dd6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c082015290565b60008281526020818152604091829020825160e081018452815481526001820154928101929092526002810154928201929092526003808301546001600160a01b0390811660608401526004840154166080830152600583015460a0830152600683015491929160c084019160ff9091169081111561045e5761045e610938565b600381111561046f5761046f610938565b90525092915050565b826000341161048657600080fd5b6000811161049357600080fd5b32331461049f57600080fd5b826000808281526020819052604090206006015460ff1660038111156104c7576104c7610938565b146104d157600080fd5b60008481526020819052604090204381556001808201879055600382018054336001600160a01b0319918216179091556004830180549091166001600160a01b03871617905534600583015560068201805460ff191682800217905550505050505050565b32331461054257600080fd5b8082600160008381526020819052604090206006015460ff16600381111561056c5761056c610938565b1461057657600080fd5b6000828152602081905260409020600401546001600160a01b0316331461059c57600080fd5b816002826040516020016105b291815260200190565b60408051601f19818403018152908290526105cc91610803565b602060405180830381855afa1580156105e9573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061060c9190610771565b1461061657600080fd5b60008381526020819052604080822060068101805460ff191660021790556005015490513391908381818185875af1925050503d8060008114610675576040519150601f19603f3d011682016040523d82523d6000602084013e61067a565b606091505b509091505060018115151461068e57600080fd5b505050600090815260208190526040902060020155565b80356001600160a01b03811681146106bc57600080fd5b919050565b6000602082840312156106d357600080fd5b6106dc826106a5565b9392505050565b600080602083850312156106f657600080fd5b823567ffffffffffffffff8082111561070e57600080fd5b818501915085601f83011261072257600080fd5b81358181111561073157600080fd5b8660208260071b850101111561074657600080fd5b60209290920196919550909350505050565b60006020828403121561076a57600080fd5b5035919050565b60006020828403121561078357600080fd5b5051919050565b6000806040838503121561079d57600080fd5b50508035926020909101359150565b6000806000606084860312156107c157600080fd5b83359250602084013591506107d8604085016106a5565b90509250925092565b600481106107ff57634e487b7160e01b600052602160045260246000fd5b9052565b6000825160005b81811015610824576020818601810151858301520161080a565b81811115610833576000828501525b509190910192915050565b600060e082019050825182526020830151602083015260408301516040830152606083015160018060a01b038082166060850152806080860151166080850152505060a083015160a083015260c083015161089c60c08401826107e1565b5092915050565b87815260208101879052604081018690526001600160a01b0385811660608301528416608082015260a0810183905260e081016108e360c08301846107e1565b98975050505050505050565b6000821982111561090257610902610922565b500190565b600060001982141561091b5761091b610922565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220adfd4cb419e368c3af5d1d3c6ec2039d2c5eb3b75584a75ee0226c403fb5a68164736f6c63430008060033" # PASSWORD is the password used to unlock all accounts/wallets/addresses. PASSWORD="abc" diff --git a/server/asset/eth/common.go b/server/asset/eth/common.go index 36d1f8c58f..9f9039bdf4 100644 --- a/server/asset/eth/common.go +++ b/server/asset/eth/common.go @@ -252,7 +252,7 @@ const ( // // TODO: When the contract is solidified, break down evm functions // called and the gas used for each. (◍•﹏•) - InitGas = 180000 // gas + InitGas = 158000 // gas RedeemGas = 63000 // gas )