Skip to content

Commit

Permalink
fix: mint and transfer funds back to escrow account on timeout or ack…
Browse files Browse the repository at this point in the history
… error (#173)

* chore: fix deps

* chore: fix func sig
  • Loading branch information
jtieri authored Mar 19, 2024
1 parent 16e0000 commit 5099c03
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.52
version: v1.55.2
working-directory: ${{ matrix.workdir }}
args: --timeout=5m
43 changes: 26 additions & 17 deletions middleware/packet-forward-middleware/packetforward/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,48 +141,57 @@ func (k *Keeper) WriteAcknowledgementForForwardedPacket(
}
}

amount, ok := sdk.NewIntFromString(data.Amount)
if !ok {
return fmt.Errorf("failed to parse amount from packet data for forward refund: %s", data.Amount)
}

denomTrace := transfertypes.ParseDenomTrace(fullDenomPath)
token := sdk.NewCoin(denomTrace.IBCDenom(), amount)

escrowAddress := transfertypes.GetEscrowAddress(packet.SourcePort, packet.SourceChannel)
refundEscrowAddress := transfertypes.GetEscrowAddress(inFlightPacket.RefundPortId, inFlightPacket.RefundChannelId)

newToken := sdk.NewCoins(token)

if transfertypes.SenderChainIsSource(packet.SourcePort, packet.SourceChannel, fullDenomPath) {
// funds were moved to escrow account for transfer, so they need to either:
// - move to the other escrow account, in the case of native denom
// - burn

amount, ok := sdk.NewIntFromString(data.Amount)
if !ok {
return fmt.Errorf("failed to parse amount from packet data for forward refund: %s", data.Amount)
}
denomTrace := transfertypes.ParseDenomTrace(fullDenomPath)
token := sdk.NewCoin(denomTrace.IBCDenom(), amount)

escrowAddress := transfertypes.GetEscrowAddress(packet.SourcePort, packet.SourceChannel)

if transfertypes.SenderChainIsSource(inFlightPacket.RefundPortId, inFlightPacket.RefundChannelId, fullDenomPath) {
// transfer funds from escrow account for forwarded packet to escrow account going back for refund.

refundEscrowAddress := transfertypes.GetEscrowAddress(inFlightPacket.RefundPortId, inFlightPacket.RefundChannelId)

if err := k.bankKeeper.SendCoins(
ctx, escrowAddress, refundEscrowAddress, sdk.NewCoins(token),
ctx, escrowAddress, refundEscrowAddress, newToken,
); err != nil {
return fmt.Errorf("failed to send coins from escrow account to refund escrow account: %w", err)
}
} else {
// transfer the coins from the escrow account to the module account and burn them.

if err := k.bankKeeper.SendCoinsFromAccountToModule(
ctx, escrowAddress, transfertypes.ModuleName, sdk.NewCoins(token),
ctx, escrowAddress, transfertypes.ModuleName, newToken,
); err != nil {
return fmt.Errorf("failed to send coins from escrow to module account for burn: %w", err)
}

if err := k.bankKeeper.BurnCoins(
ctx, transfertypes.ModuleName, sdk.NewCoins(token),
ctx, transfertypes.ModuleName, newToken,
); err != nil {
// NOTE: should not happen as the module account was
// retrieved on the step above and it has enough balace
// to burn.
panic(fmt.Sprintf("cannot burn coins after a successful send from escrow account to module account: %v", err))
}
}
} else {
// Funds in the escrow account were burned,
// so on a timeout or acknowledgement error we need to mint the funds back to the escrow account.
if err := k.bankKeeper.MintCoins(ctx, transfertypes.ModuleName, newToken); err != nil {
return fmt.Errorf("cannot mint coins to the %s module account: %v", transfertypes.ModuleName, err)
}

if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, transfertypes.ModuleName, refundEscrowAddress, newToken); err != nil {
return fmt.Errorf("cannot send coins from the %s module to the escrow account %s: %v", transfertypes.ModuleName, refundEscrowAddress, err)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type DistributionKeeper interface {
// BankKeeper defines the expected bank keeper
type BankKeeper interface {
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error
BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error
}
28 changes: 28 additions & 0 deletions middleware/packet-forward-middleware/test/mock/bank_keeper.go

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

0 comments on commit 5099c03

Please sign in to comment.