Skip to content

Commit

Permalink
feat: remove fee and minimal amount on transfer from vested account
Browse files Browse the repository at this point in the history
Signed-off-by: Jeremy Letang <[email protected]>
  • Loading branch information
jeremyletang committed Nov 4, 2023
1 parent d58ba71 commit eb394d0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
### 🛠 Improvements

- [9930](https://github.com/vegaprotocol/vega/issues/9930) - `LiquidityFeeSettings` can now be used in market proposals to choose how liquidity fees are calculated.
- [9982](https://github.com/vegaprotocol/vega/issues/9982) - Remove fees and minimal transfer amount from vested account

### 🐛 Fixes

Expand Down
2 changes: 1 addition & 1 deletion core/banking/oneoff_transfers.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (e *Engine) oneOffTransfer(
return err
}

if err := e.ensureMinimalTransferAmount(a, transfer.Amount); err != nil {
if err := e.ensureMinimalTransferAmount(a, transfer.Amount, transfer.FromAccountType, transfer.From); err != nil {
transfer.Status = types.TransferStatusRejected
return err
}
Expand Down
6 changes: 3 additions & 3 deletions core/banking/recurring_transfers.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (e *Engine) recurringTransfer(
return err
}

if err := e.ensureMinimalTransferAmount(a, transfer.Amount); err != nil {
if err := e.ensureMinimalTransferAmount(a, transfer.Amount, transfer.FromAccountType, transfer.From); err != nil {
transfer.Status = types.TransferStatusRejected
return err
}
Expand Down Expand Up @@ -238,7 +238,7 @@ func (e *Engine) distributeRecurringTransfers(ctx context.Context, newEpoch uint
e.log.Panic("this should never happen", logging.Error(err))
}

if err = e.ensureMinimalTransferAmount(a, amount); err != nil {
if err = e.ensureMinimalTransferAmount(a, amount, v.FromAccountType, v.From); err != nil {
v.Status = types.TransferStatusStopped
transfersDone = append(transfersDone,
events.NewRecurringTransferFundsEventWithReason(ctx, v, err.Error()))
Expand All @@ -256,7 +256,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(amount, v.From, v.Asset, v.FromAccountType); err == nil {
if _, err = e.ensureFeeForTransferFunds(amount, v.From, v.Asset, v.FromAccountType, v.To); 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
44 changes: 38 additions & 6 deletions core/banking/transfers_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,33 @@ func (e *Engine) CheckTransfer(t *types.TransferBase) error {
return fmt.Errorf("could not transfer funds, %w", err)
}

if err := e.ensureMinimalTransferAmount(a, t.Amount); err != nil {
if err := e.ensureMinimalTransferAmount(a, t.Amount, t.FromAccountType, t.From); err != nil {
return err
}

_, err = e.ensureFeeForTransferFunds(t.Amount, t.From, t.Asset, t.FromAccountType)
_, err = e.ensureFeeForTransferFunds(t.Amount, t.From, t.Asset, t.FromAccountType, t.To)
if err != nil {
return fmt.Errorf("could not transfer funds, %w", err)
}
return nil
}

func (e *Engine) ensureMinimalTransferAmount(a *assets.Asset, amount *num.Uint) error {
func (e *Engine) ensureMinimalTransferAmount(
a *assets.Asset,
amount *num.Uint,
fromAccType types.AccountType,
from string,
) error {
quantum := a.Type().Details.Quantum
// no reason this would produce an error
minAmount, _ := num.UintFromDecimal(quantum.Mul(e.minTransferQuantumMultiple))

// no verify amount
if amount.LT(minAmount) {
if fromAccType == types.AccountTypeVestedRewards {
return e.ensureMinimalTransferAmountFromVested(amount, from, a.Type().ID)
}

e.log.Debug("cannot transfer funds, less than minimal amount requested to transfer",
logging.BigUint("min-amount", minAmount),
logging.BigUint("requested-amount", amount),
Expand All @@ -94,6 +103,22 @@ func (e *Engine) ensureMinimalTransferAmount(a *assets.Asset, amount *num.Uint)
return nil
}

func (e *Engine) ensureMinimalTransferAmountFromVested(
transferAmount *num.Uint,
from, asset string,
) error {
account, err := e.col.GetPartyVestedRewardAccount(from, asset)
if err != nil {
return err
}

if transferAmount.EQ(account.Balance) {
return nil
}

return fmt.Errorf("transfer from vested account under minimal transfer amount must be the full balance")
}

func (e *Engine) processTransfer(
ctx context.Context,
from, to, asset, toMarket string,
Expand All @@ -108,7 +133,7 @@ func (e *Engine) processTransfer(
) ([]*types.LedgerMovement, error) {
// ensure the party have enough funds for both the
// amount and the fee for the transfer
feeTransfer, err := e.ensureFeeForTransferFunds(amount, from, asset, fromAcc)
feeTransfer, err := e.ensureFeeForTransferFunds(amount, from, asset, fromAcc, to)
if err != nil {
return nil, fmt.Errorf("could not pay the fee for transfer: %w", err)
}
Expand Down Expand Up @@ -179,9 +204,15 @@ func (e *Engine) makeFeeTransferForTransferFunds(
amount *num.Uint,
from, asset string,
fromAccountType types.AccountType,
to string,
) *types.Transfer {
// no fee for Vested account
feeAmount := num.UintZero()

// first we calculate the fee
feeAmount, _ := num.UintFromDecimal(amount.ToDecimal().Mul(e.transferFeeFactor))
if !(fromAccountType == types.AccountTypeVestedRewards && from == to) {
feeAmount, _ = num.UintFromDecimal(amount.ToDecimal().Mul(e.transferFeeFactor))
}

switch fromAccountType {
case types.AccountTypeGeneral, types.AccountTypeVestedRewards:
Expand All @@ -208,9 +239,10 @@ func (e *Engine) ensureFeeForTransferFunds(
amount *num.Uint,
from, asset string,
fromAccountType types.AccountType,
to string,
) (*types.Transfer, error) {
transfer := e.makeFeeTransferForTransferFunds(
amount, from, asset, fromAccountType,
amount, from, asset, fromAccountType, to,
)

var (
Expand Down

0 comments on commit eb394d0

Please sign in to comment.