Skip to content

Commit

Permalink
feat: add bridge call refund callback (#484)
Browse files Browse the repository at this point in the history
  • Loading branch information
zakir-code authored May 15, 2024
1 parent 5ce799b commit 36e997a
Show file tree
Hide file tree
Showing 17 changed files with 327 additions and 19 deletions.
202 changes: 202 additions & 0 deletions contract/IRefundCallback.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion contract/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ echo "===> Compiling contracts"
[[ ! -d "$project_dir/contract/artifacts" ]] && mkdir -p "$project_dir/contract/artifacts"

# add core contracts
contracts=(WFXUpgradable FIP20Upgradable ICrossChain IStaking IFxBridgeLogic)
contracts=(WFXUpgradable FIP20Upgradable ICrossChain IStaking IFxBridgeLogic IRefundCallback)
contracts_test=(CrossChainTest StakingTest)
# add 3rd party contracts
contracts+=(ERC1967Proxy)
Expand Down
6 changes: 6 additions & 0 deletions contract/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ var (
}

fxBridgeABI = MustABIJson(IFxBridgeLogicMetaData.ABI)

bridgeCallRefundCallback = MustABIJson(IRefundCallbackMetaData.ABI)
)

type Contract struct {
Expand Down Expand Up @@ -72,6 +74,10 @@ func GetFxBridgeABI() abi.ABI {
return fxBridgeABI
}

func GetBridgeCallRefundCallback() abi.ABI {
return bridgeCallRefundCallback
}

func MustDecodeHex(str string) []byte {
bz, err := hexutil.Decode(str)
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions solidity/.solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"endOfLine": "auto"
}
],
"reason-string": ["warn", { "maxLength": 64 }],
"one-contract-per-file": "off"
"reason-string": ["warn", { "maxLength": 64 }]
}
}
3 changes: 2 additions & 1 deletion solidity/contracts/bridge/FxBridgeLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";

import {IERC20ExtensionsUpgradeable} from "./IERC20ExtensionsUpgradeable.sol";
import {IBridgeCallback, IRefundCallback} from "./ICallback.sol";
import {IBridgeCallback} from "./IBridgeCallback.sol";
import {IRefundCallback} from "./IRefundCallback.sol";

/* solhint-disable custom-errors */

Expand Down
3 changes: 2 additions & 1 deletion solidity/contracts/bridge/FxBridgeLogicETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";

import {IERC20ExtensionsUpgradeable} from "./IERC20ExtensionsUpgradeable.sol";
import {IBridgeCallback, IRefundCallback} from "./ICallback.sol";
import {IBridgeCallback} from "./IBridgeCallback.sol";
import {IRefundCallback} from "./IRefundCallback.sol";

/* solhint-disable custom-errors */

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

/* solhint-disable one-contract-per-file */
interface IBridgeCallback {
function bridgeCallback(
address,
Expand All @@ -12,12 +11,3 @@ interface IBridgeCallback {
bytes memory
) external;
}

/* solhint-disable one-contract-per-file */
interface IRefundCallback {
function refundCallback(
uint256,
address[] memory,
uint256[] memory
) external;
}
10 changes: 10 additions & 0 deletions solidity/contracts/bridge/IRefundCallback.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IRefundCallback {
function refundCallback(
uint256,
address[] memory,
uint256[] memory
) external;
}
2 changes: 1 addition & 1 deletion x/crosschain/keeper/bridge_call_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (k Keeper) BridgeCallHandler(ctx sdk.Context, msg *types.MsgBridgeCallClaim
}
// refund event
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeBridgeCallRefund,
types.EventTypeBridgeCallRefundOut,
sdk.NewAttribute(types.AttributeKeyEventNonce, fmt.Sprintf("%d", eventNonce)),
sdk.NewAttribute(types.AttributeKeyBridgeCallNonce, fmt.Sprintf("%d", outCall.Nonce)),
))
Expand Down
2 changes: 1 addition & 1 deletion x/crosschain/keeper/bridge_call_in_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (s *KeeperTestSuite) TestBridgeCallHandler() {
if t.refund {
refundEvent := false
for _, event := range s.ctx.EventManager().Events().ToABCIEvents() {
if event.Type == types.EventTypeBridgeCallRefund {
if event.Type == types.EventTypeBridgeCallRefundOut {
refundEvent = true
}
}
Expand Down
58 changes: 58 additions & 0 deletions x/crosschain/keeper/bridge_call_refund.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package keeper

import (
"math/big"
"strconv"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"

"github.com/functionx/fx-core/v7/contract"
"github.com/functionx/fx-core/v7/x/crosschain/types"
)

Expand All @@ -13,13 +18,66 @@ func (k Keeper) HandleOutgoingBridgeCallRefund(ctx sdk.Context, data *types.Outg
panic(err)
}

evmErrCause, evmSuccess, isCallback := "", false, false
defer func() {
attrs := []sdk.Attribute{
sdk.NewAttribute(sdk.AttributeKeySender, sender.String()),
}
if isCallback {
attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyStateSuccess, strconv.FormatBool(evmSuccess)))
if len(evmErrCause) > 0 {
attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyErrCause, evmErrCause))
}
}
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeBridgeCallRefund,
attrs...,
))
}()

if k.HasBridgeCallFromMsg(ctx, data.Nonce) {
return
}
// precompile bridge call, refund to evm
if err = k.bridgeCallTransferToReceiver(ctx, sender, sender, coins); err != nil {
panic(err)
}
if data.EventNonce > 0 {
contractAddr := common.BytesToAddress(sender.Bytes())
account := k.evmKeeper.GetAccount(ctx, contractAddr)
if !account.IsContract() {
return
}

isCallback = true
maxGasLimit := k.GetParams(ctx).BridgeCallMaxGasLimit
tokens := types.ERC20Tokens(data.Tokens)
args, err := contract.GetBridgeCallRefundCallback().Pack(
"refundCallback",
data.EventNonce,
tokens.GetContracts(),
tokens.GetAmounts(),
)
if err != nil {
evmErrCause = err.Error()
return
}
txResp, err := k.evmKeeper.CallEVM(
ctx,
k.callbackFrom,
&contractAddr,
big.NewInt(0),
maxGasLimit,
args,
true,
)
if err != nil {
evmErrCause = err.Error()
} else {
evmSuccess = !txResp.Failed()
evmErrCause = txResp.VmError
}
}
}

func (k Keeper) DeleteOutgoingBridgeCallRecord(ctx sdk.Context, bridgeCallNonce uint64) {
Expand Down
Loading

0 comments on commit 36e997a

Please sign in to comment.