From d18a39fefe2f5b9368f8ffe4829dc6a6fabfe99b Mon Sep 17 00:00:00 2001 From: rockca <86341157+rockca@users.noreply.github.com> Date: Tue, 21 Dec 2021 17:11:50 +0800 Subject: [PATCH] feat: btfs deposit (#14) --- chain/abi/abi.go | 40 +++++++++++++++- chain/config/config.go | 2 +- settlement/swap/erc20/erc20.go | 76 +++++++++++++++++++++++++++++++ settlement/swap/vault/contract.go | 17 +++++++ settlement/swap/vault/init.go | 18 ++++++++ settlement/swap/vault/vault.go | 2 +- 6 files changed, 152 insertions(+), 3 deletions(-) diff --git a/chain/abi/abi.go b/chain/abi/abi.go index 8782e6006..dc026a971 100644 --- a/chain/abi/abi.go +++ b/chain/abi/abi.go @@ -53,6 +53,31 @@ const VaultABI = `[ { "anonymous": false, "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, { "indexed": false, "internalType": "uint256", @@ -125,6 +150,19 @@ const VaultABI = `[ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -728,4 +766,4 @@ const OracleAbi = `[ } ]` -const FactoryDeployedBin = "608060405234801561001057600080fd5b506004361061004c5760003560e01c806368027f2714610051578063c2cba30614610081578063c70242ad1461009f578063ee97f7f3146100cf575b600080fd5b61006b60048036038101906100669190610405565b6100ed565b60405161007891906104ae565b60405180910390f35b61008961026f565b60405161009691906104ae565b60405180910390f35b6100b960048036038101906100b491906103dc565b610295565b6040516100c6919061051b565b60405180910390f35b6100d76102b5565b6040516100e491906104ae565b60405180910390f35b600080610144600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856040516020016101299291906104f2565b604051602081830303815290604052805190602001206102db565b90508073ffffffffffffffffffffffffffffffffffffffff1663f09a401685600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016101a39291906104c9565b600060405180830381600087803b1580156101bd57600080fd5b505af11580156101d1573d6000803e3d6000fd5b5050505060016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f09d75e12e349f79020715b0ea7b2c707e8acf1889b6d6f1337fce7f4e1b9e5c7848260405161025d9291906104c9565b60405180910390a18091505092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006020528060005260406000206000915054906101000a900460ff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528360601b60148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f5915050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a390610536565b60405180910390fd5b92915050565b6000813590506103c1816105af565b92915050565b6000813590506103d6816105c6565b92915050565b6000602082840312156103ee57600080fd5b60006103fc848285016103b2565b91505092915050565b6000806040838503121561041857600080fd5b6000610426858286016103b2565b9250506020610437858286016103c7565b9150509250929050565b61044a81610567565b82525050565b61045981610579565b82525050565b61046881610585565b82525050565b600061047b601783610556565b91507f455243313136373a2063726561746532206661696c65640000000000000000006000830152602082019050919050565b60006020820190506104c36000830184610441565b92915050565b60006040820190506104de6000830185610441565b6104eb6020830184610441565b9392505050565b60006040820190506105076000830185610441565b610514602083018461045f565b9392505050565b60006020820190506105306000830184610450565b92915050565b6000602082019050818103600083015261054f8161046e565b9050919050565b600082825260208201905092915050565b60006105728261058f565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6105b881610567565b81146105c357600080fd5b50565b6105cf81610585565b81146105da57600080fd5b5056fea2646970667358221220525a425ed317dbd08bae789a99beeec2f85908609903f21f79212b1a5c2324a264736f6c63430008000033" +const FactoryDeployedBin = "608060405234801561001057600080fd5b506004361061004c5760003560e01c806368027f2714610051578063c2cba30614610081578063c70242ad1461009f578063ee97f7f3146100cf575b600080fd5b61006b60048036038101906100669190610405565b6100ed565b60405161007891906104ae565b60405180910390f35b61008961026f565b60405161009691906104ae565b60405180910390f35b6100b960048036038101906100b491906103dc565b610295565b6040516100c6919061051b565b60405180910390f35b6100d76102b5565b6040516100e491906104ae565b60405180910390f35b600080610144600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633856040516020016101299291906104f2565b604051602081830303815290604052805190602001206102db565b90508073ffffffffffffffffffffffffffffffffffffffff1663f09a401685600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016101a39291906104c9565b600060405180830381600087803b1580156101bd57600080fd5b505af11580156101d1573d6000803e3d6000fd5b5050505060016000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f09d75e12e349f79020715b0ea7b2c707e8acf1889b6d6f1337fce7f4e1b9e5c7848260405161025d9291906104c9565b60405180910390a18091505092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006020528060005260406000206000915054906101000a900460ff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528360601b60148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f5915050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156103ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a390610536565b60405180910390fd5b92915050565b6000813590506103c1816105af565b92915050565b6000813590506103d6816105c6565b92915050565b6000602082840312156103ee57600080fd5b60006103fc848285016103b2565b91505092915050565b6000806040838503121561041857600080fd5b6000610426858286016103b2565b9250506020610437858286016103c7565b9150509250929050565b61044a81610567565b82525050565b61045981610579565b82525050565b61046881610585565b82525050565b600061047b601783610556565b91507f455243313136373a2063726561746532206661696c65640000000000000000006000830152602082019050919050565b60006020820190506104c36000830184610441565b92915050565b60006040820190506104de6000830185610441565b6104eb6020830184610441565b9392505050565b60006040820190506105076000830185610441565b610514602083018461045f565b9392505050565b60006020820190506105306000830184610450565b92915050565b6000602082019050818103600083015261054f8161046e565b9050919050565b600082825260208201905092915050565b60006105728261058f565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6105b881610567565b81146105c357600080fd5b50565b6105cf81610585565b81146105da57600080fd5b5056fea2646970667358221220de9cc791669a5da4dbf93c17c12aa3293139ce57cce78af651439465f447ba0764736f6c63430008000033" diff --git a/chain/config/config.go b/chain/config/config.go index fada3c146..f37e86f36 100644 --- a/chain/config/config.go +++ b/chain/config/config.go @@ -25,7 +25,7 @@ var ( tronOracleAddress = common.HexToAddress("0x0c9de531dcb38b758fe8a2c163444a5e54ee0db2") tronBatchAddress = common.HexToAddress("0x0c9de531dcb38b758fe8a2c163444a5e54ee0db2") - bttcTestFactoryAddress = common.HexToAddress("0x953bb0d5bF1DF0050b43BAff7Ae756102F5550E4") + bttcTestFactoryAddress = common.HexToAddress("0x392E3CE1B56c34ae0102C70cE3D640FFB9048A79") bttcTestOracleAddress = common.HexToAddress("0xF6515C49F97ebF6355214A6D6132fAD4b40D2f84") bttcTestBatchAddress = common.HexToAddress("0x0c9de531dcb38b758fe8a2c163444a5e54ee0db2") diff --git a/settlement/swap/erc20/erc20.go b/settlement/swap/erc20/erc20.go index 2df4a940d..6ccb477c5 100644 --- a/settlement/swap/erc20/erc20.go +++ b/settlement/swap/erc20/erc20.go @@ -19,6 +19,9 @@ var ( type Service interface { BalanceOf(ctx context.Context, address common.Address) (*big.Int, error) Transfer(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error) + Allowance(ctx context.Context, issuer common.Address, vault common.Address) (*big.Int, error) + Approve(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error) + TransferFrom(ctx context.Context, issuer common.Address, vault common.Address, value *big.Int) (common.Hash, error) } type erc20Service struct { @@ -85,3 +88,76 @@ func (c *erc20Service) Transfer(ctx context.Context, address common.Address, val return txHash, nil } + +// first, approve to vault +func (c *erc20Service) TransferFrom(ctx context.Context, issuer common.Address, vault common.Address, value *big.Int) (common.Hash, error) { + callData, err := erc20ABI.Pack("transferFrom", issuer, vault, value) + if err != nil { + return common.Hash{}, err + } + + request := &transaction.TxRequest{ + To: &c.address, + Data: callData, + Value: big.NewInt(0), + Description: "token transfer", + } + + txHash, err := c.transactionService.Send(ctx, request) + if err != nil { + return common.Hash{}, err + } + + return txHash, nil +} + +func (c *erc20Service) Allowance(ctx context.Context, issuer common.Address, vault common.Address) (*big.Int, error) { + callData, err := erc20ABI.Pack("allowance", issuer, vault) + if err != nil { + return nil, err + } + + output, err := c.transactionService.Call(ctx, &transaction.TxRequest{ + To: &c.address, + Data: callData, + }) + if err != nil { + return nil, err + } + + results, err := erc20ABI.Unpack("allowance", output) + if err != nil { + return nil, err + } + + if len(results) != 1 { + return nil, errDecodeABI + } + + allowance, ok := abi.ConvertType(results[0], new(big.Int)).(*big.Int) + if !ok || allowance == nil { + return nil, errDecodeABI + } + return allowance, nil +} + +func (c *erc20Service) Approve(ctx context.Context, address common.Address, value *big.Int) (common.Hash, error) { + callData, err := erc20ABI.Pack("approve", address, value) + if err != nil { + return common.Hash{}, err + } + + request := &transaction.TxRequest{ + To: &c.address, + Data: callData, + Value: big.NewInt(0), + Description: "approve", + } + + txHash, err := c.transactionService.Send(ctx, request) + if err != nil { + return common.Hash{}, err + } + + return txHash, nil +} diff --git a/settlement/swap/vault/contract.go b/settlement/swap/vault/contract.go index 6f96476a7..8f96b39f3 100644 --- a/settlement/swap/vault/contract.go +++ b/settlement/swap/vault/contract.go @@ -149,3 +149,20 @@ func (c *vaultContract) SetReceiver(ctx context.Context, newReceiver common.Addr return hash, nil } + +func (c *vaultContract) Deposit(ctx context.Context, amount *big.Int) (common.Hash, error) { + callData, err := vaultABI.Pack("deposit", amount) + if err != nil { + return common.Hash{}, err + } + + hash, err := c.transactionService.Send(ctx, &transaction.TxRequest{ + To: &c.address, + Data: callData, + }) + if err != nil { + return hash, err + } + + return hash, nil +} diff --git a/settlement/swap/vault/init.go b/settlement/swap/vault/init.go index b8273d213..e8f67851f 100644 --- a/settlement/swap/vault/init.go +++ b/settlement/swap/vault/init.go @@ -22,6 +22,8 @@ const ( balanceCheckBackoffDuration = 20 * time.Second balanceCheckMaxRetries = 10 + maxApprove = 10000000000000000 + decimals = 100000000000000000 ) func checkBalance( @@ -163,5 +165,21 @@ func Init( return nil, err } + // approve to vaultAddress + allowance, err := erc20Service.Allowance(ctx, overlayEthAddress, vaultAddress) + if err != nil { + return nil, err + } + + if allowance.Cmp(big.NewInt(0)) == 0 { + var value big.Int + value.Mul(big.NewInt(maxApprove), big.NewInt(decimals)) + hash, err := erc20Service.Approve(ctx, vaultAddress, &value) + if err != nil { + return nil, err + } + + fmt.Printf("approve WBTT to vault [0x%x] at tx [0x%x] \n", vaultAddress, hash) + } return vaultService, nil } diff --git a/settlement/swap/vault/vault.go b/settlement/swap/vault/vault.go index 4455afdab..09562d9ee 100644 --- a/settlement/swap/vault/vault.go +++ b/settlement/swap/vault/vault.go @@ -121,7 +121,7 @@ func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Has return common.Hash{}, ErrInsufficientFunds } - return s.erc20Service.Transfer(ctx, s.address, amount) + return s.contract.Deposit(ctx, amount) } // Deposit starts depositing erc20 token into the vault. This returns once the transactions has been broadcast.