Skip to content

Commit

Permalink
fix: avoid paying fee with staking related transfers
Browse files Browse the repository at this point in the history
Signed-off-by: Jeremy Letang <[email protected]>
  • Loading branch information
jeremyletang committed Oct 22, 2024
1 parent 8e4733b commit cc1cdaf
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 11 deletions.
8 changes: 6 additions & 2 deletions core/banking/fee_estimate.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ func EstimateFee(
fromAccountType types.AccountType,
fromDerivedKey *string,
to string,
toAccountType types.AccountType,
) (fee *num.Uint, discount *num.Uint) {
tFee := calculateFeeForTransfer(assetQuantum, maxQuantumAmount, transferFeeFactor, amount, from,
fromAccountType, fromDerivedKey, to)
fromAccountType, fromDerivedKey, to, toAccountType)
return calculateDiscount(accumulatedDiscount, tFee)
}

Expand All @@ -46,12 +47,15 @@ func calculateFeeForTransfer(
fromAccountType types.AccountType,
fromDerivedKey *string,
to string,
toAccountType types.AccountType,
) *num.Uint {
feeAmount := num.UintZero()

// no fee for Vested account
// either from owner's vested to their general account or from derived key vested to owner's general account
if fromAccountType == types.AccountTypeVestedRewards && (from == to || fromDerivedKey != nil) {
if (fromAccountType == types.AccountTypeVestedRewards && (from == to || fromDerivedKey != nil)) ||
(fromAccountType == types.AccountTypeLockedForStaking && from == to) ||
(fromAccountType == types.AccountTypeGeneral && toAccountType == types.AccountTypeLockedForStaking && from == to) {
return feeAmount
}

Expand Down
4 changes: 2 additions & 2 deletions core/banking/oneoff_transfers.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (e *Engine) updateStakingAccounts(
BlockHeight: height,
BlockTime: now,
LogIndex: 1,
EthereumAddress: transfer.From,
EthereumAddress: "",
}
}

Expand All @@ -112,7 +112,7 @@ func (e *Engine) updateStakingAccounts(
BlockHeight: height,
BlockTime: now,
LogIndex: 1,
EthereumAddress: transfer.From,
EthereumAddress: "",
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/banking/recurring_transfers.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ func (e *Engine) distributeRecurringTransfers(ctx context.Context, newEpoch uint
)
} else {
// check if the amount + fees can be covered by the party issuing the transfer
if err = e.ensureFeeForTransferFunds(a, amount, v.From, v.FromAccountType, v.FromDerivedKey, v.To); err == nil {
if err = e.ensureFeeForTransferFunds(a, amount, v.From, v.FromAccountType, v.FromDerivedKey, v.To, v.ToAccountType); err == nil {
// NB: if the metric is market value we're going to transfer the bonus if any directly
// to the market account of the asset/reward type - this is similar to previous behaviour and
// different to how all other metric based rewards behave. The reason is that we need the context of the funder
Expand Down
12 changes: 8 additions & 4 deletions core/banking/transfers_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (e *Engine) CheckTransfer(t *types.TransferBase) error {
return err
}

if err = e.ensureFeeForTransferFunds(a, t.Amount, t.From, t.FromAccountType, t.FromDerivedKey, t.To); err != nil {
if err = e.ensureFeeForTransferFunds(a, t.Amount, t.From, t.FromAccountType, t.FromDerivedKey, t.To, t.ToAccountType); err != nil {
return fmt.Errorf("could not transfer funds, %w", err)
}
return nil
Expand Down Expand Up @@ -166,7 +166,7 @@ func (e *Engine) processTransfer(

// ensure the party have enough funds for both the
// amount and the fee for the transfer
feeTransfer, discount, err := e.makeFeeTransferForFundsTransfer(ctx, assetType, amount, from, fromAcc, fromDerivedKey, to)
feeTransfer, discount, err := e.makeFeeTransferForFundsTransfer(ctx, assetType, amount, from, fromAcc, fromDerivedKey, to, toAcc)
if err != nil {
return nil, fmt.Errorf("could not pay the fee for transfer: %w", err)
}
Expand Down Expand Up @@ -249,6 +249,7 @@ func (e *Engine) calculateFeeTransferForTransfer(
fromAccountType types.AccountType,
fromDerivedKey *string,
to string,
toAccountType types.AccountType,
) *num.Uint {
return calculateFeeForTransfer(
asset.Details.Quantum,
Expand All @@ -259,6 +260,7 @@ func (e *Engine) calculateFeeTransferForTransfer(
fromAccountType,
fromDerivedKey,
to,
toAccountType,
)
}

Expand All @@ -270,8 +272,9 @@ func (e *Engine) makeFeeTransferForFundsTransfer(
fromAccountType types.AccountType,
fromDerivedKey *string,
to string,
toAccountType types.AccountType,
) (*types.Transfer, *num.Uint, error) {
theoreticalFee := e.calculateFeeTransferForTransfer(asset, amount, from, fromAccountType, fromDerivedKey, to)
theoreticalFee := e.calculateFeeTransferForTransfer(asset, amount, from, fromAccountType, fromDerivedKey, to, toAccountType)
feeAmount, discountAmount := e.ApplyFeeDiscount(ctx, asset.ID, from, theoreticalFee)

if err := e.ensureEnoughFundsForTransfer(asset, amount, from, fromAccountType, fromDerivedKey, feeAmount); err != nil {
Expand Down Expand Up @@ -306,9 +309,10 @@ func (e *Engine) ensureFeeForTransferFunds(
fromAccountType types.AccountType,
fromDerivedKey *string,
to string,
toAccountType types.AccountType,
) error {
assetType := asset.ToAssetType()
theoreticalFee := e.calculateFeeTransferForTransfer(assetType, amount, from, fromAccountType, fromDerivedKey, to)
theoreticalFee := e.calculateFeeTransferForTransfer(assetType, amount, from, fromAccountType, fromDerivedKey, to, toAccountType)
feeAmount, _ := e.EstimateFeeDiscount(assetType.ID, from, theoreticalFee)
return e.ensureEnoughFundsForTransfer(assetType, amount, from, fromAccountType, fromDerivedKey, feeAmount)
}
Expand Down
6 changes: 5 additions & 1 deletion core/types/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ func (s *StakeLinking) IntoProto() *eventspb.StakeLinking {

func StakeLinkingFromProto(sl *eventspb.StakeLinking) *StakeLinking {
amt, _ := num.UintFromString(sl.Amount, 10)
var ethereumAddress string
if len(sl.EthereumAddress) > 0 {
ethereumAddress = crypto.EthereumChecksumAddress(sl.EthereumAddress)
}
return &StakeLinking{
ID: sl.Id,
Type: sl.Type,
Expand All @@ -153,7 +157,7 @@ func StakeLinkingFromProto(sl *eventspb.StakeLinking) *StakeLinking {
BlockHeight: sl.BlockHeight,
BlockTime: sl.BlockTime,
LogIndex: sl.LogIndex,
EthereumAddress: crypto.EthereumChecksumAddress(sl.EthereumAddress),
EthereumAddress: ethereumAddress,
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/vesting/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func (e *Engine) updateStakingAccount(
BlockHeight: height,
BlockTime: now,
LogIndex: logIndex,
EthereumAddress: party,
EthereumAddress: "",
}

e.stakeAccounting.AddEvent(context.Background(), stakeLinking)
Expand Down
2 changes: 2 additions & 0 deletions datanode/api/trading_data_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -5728,6 +5728,8 @@ func (t *TradingDataServiceV2) EstimateTransferFee(ctx context.Context, req *v2.
req.FromAccountType,
req.FromAmmKey,
req.ToAccount,
// irrelvant here
vega.AccountType_ACCOUNT_TYPE_UNSPECIFIED,
)

return &v2.EstimateTransferFeeResponse{
Expand Down

0 comments on commit cc1cdaf

Please sign in to comment.