From e0c79c5812c80fbb5b89714b7ea02ebcca83e431 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Sun, 11 Sep 2022 19:53:32 +0800 Subject: [PATCH] Burn account amount when getting events from bridge contract --- contracts/abis/json.go | 70 ++++++++++++++++++++++++++++++++++++++ contracts/bridge/events.go | 45 ++++++++++++++++++++++++ state/executor.go | 10 ++++++ 3 files changed, 125 insertions(+) diff --git a/contracts/abis/json.go b/contracts/abis/json.go index 46d574d598..2ac7ed10fd 100644 --- a/contracts/abis/json.go +++ b/contracts/abis/json.go @@ -470,6 +470,26 @@ const BridgeJSONABI = `[ "stateMutability": "nonpayable", "type": "constructor" }, + { + "anonymous": false, + "inputs": + [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Burned", + "type": "event" + }, { "anonymous": false, "inputs": @@ -646,6 +666,21 @@ const BridgeJSONABI = `[ "name": "Withdrawn", "type": "event" }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "addBalance", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ @@ -661,6 +696,26 @@ const BridgeJSONABI = `[ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": + [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ @@ -862,6 +917,21 @@ const BridgeJSONABI = `[ "stateMutability": "view", "type": "function" }, + { + "inputs": + [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "subBalance", + "outputs": + [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], diff --git a/contracts/bridge/events.go b/contracts/bridge/events.go index e4c585c53f..c58e845108 100644 --- a/contracts/bridge/events.go +++ b/contracts/bridge/events.go @@ -13,10 +13,12 @@ import ( const ( EventDeposited = "Deposited" EventWithdrawn = "Withdrawn" + EventBurned = "Burned" fieldReceiver = "receiver" fieldAmount = "amount" fieldFee = "fee" + fieldSender = "sender" ) // Frequently used methods. Must exist. @@ -25,6 +27,8 @@ var ( BridgeDepositedEventID = types.Hash(BridgeDepositedEvent.ID()) BridgeWithdrawnEvent = abis.BridgeABI.Events[EventWithdrawn] BridgeWithdrawnEventID = types.Hash(BridgeWithdrawnEvent.ID()) + BridgeEventBurnedEvent = abis.BridgeABI.Events[EventBurned] + BridgeBurnedEventID = types.Hash(BridgeEventBurnedEvent.ID()) ) type DepositedLog struct { @@ -125,3 +129,44 @@ func getBigIntFromWithdrawnLog(log map[string]interface{}, key string) (*big.Int return bigVal, nil } + +type BurnedLog struct { + Sender types.Address + Amount *big.Int +} + +func ParseBridgeBurnedLog(log *types.Log) (*BurnedLog, error) { + topics := make([]web3.Hash, 0, len(log.Topics)) + for _, topic := range log.Topics { + topics = append(topics, web3.Hash(topic)) + } + + w3Log, err := BridgeEventBurnedEvent.ParseLog(&web3.Log{ + Address: web3.Address(log.Address), + Topics: topics, + Data: log.Data, + }) + if err != nil { + return nil, err + } + + sender, ok := w3Log[fieldSender] + if !ok { + return nil, errors.New("address not exists in Deposited event") + } + + account, ok := sender.(web3.Address) + if !ok { + return nil, errors.New("address downcast failed") + } + + amount, err := getBigIntFromWithdrawnLog(w3Log, fieldAmount) + if err != nil { + return nil, err + } + + return &BurnedLog{ + Sender: types.Address(account), + Amount: amount, + }, nil +} diff --git a/state/executor.go b/state/executor.go index 4d27c4a54e..9ff70c9bbb 100644 --- a/state/executor.go +++ b/state/executor.go @@ -339,6 +339,16 @@ func (t *Transition) handleBridgeLogs(msg *types.Transaction, logs []*types.Log) // the fee goes to system Vault contract t.state.AddBalance(systemcontracts.AddrVaultContract, parsedLog.Fee) + case bridge.BridgeBurnedEventID: + parsedLog, err := bridge.ParseBridgeBurnedLog(log) + if err != nil { + return err + } + + // burn + if err := t.state.SubBalance(parsedLog.Sender, parsedLog.Amount); err != nil { + return err + } } }