Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TRA-80] Update subaccount-to-subaccount transfers for collateral pools. #1178

Merged
merged 4 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 55 additions & 6 deletions protocol/mocks/SubaccountsKeeper.go

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

2 changes: 1 addition & 1 deletion protocol/testing/e2e/funding/funding_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ func TestFunding(t *testing.T) {
tApp.App,
testapp.MustMakeCheckTxOptions{
AccAddressForSigning: transfer.Transfer.Sender.Owner,
Gas: 100_000,
Gas: 110_000,
FeeAmt: constants.TestFeeCoins_5Cents,
},
&transfer,
Expand Down
1 change: 1 addition & 0 deletions protocol/testutil/constants/perpetuals.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ var TestMarketPerpetuals = []perptypes.Perpetual{
FundingIndex: dtypes.ZeroInt(),
},
IsoUsd_IsolatedMarket,
Iso2Usd_IsolatedMarket,
}

// AddPremiumVotes messages.
Expand Down
16 changes: 16 additions & 0 deletions protocol/testutil/constants/positions.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ var (
Quantums: dtypes.NewInt(100_000_000),
FundingIndex: dtypes.NewInt(0),
}
PerpetualPosition_OneISO2Long = satypes.PerpetualPosition{
PerpetualId: 4,
Quantums: dtypes.NewInt(10_000_000),
FundingIndex: dtypes.NewInt(0),
}
// Short position for arbitrary isolated market
PerpetualPosition_OneISOShort = satypes.PerpetualPosition{
PerpetualId: 3,
Quantums: dtypes.NewInt(-100_000_000),
FundingIndex: dtypes.NewInt(0),
}
PerpetualPosition_OneISO2Short = satypes.PerpetualPosition{
PerpetualId: 4,
Quantums: dtypes.NewInt(-10_000_000),
FundingIndex: dtypes.NewInt(0),
}

// Asset Positions
Usdc_Asset_0 = satypes.AssetPosition{
Expand Down
18 changes: 7 additions & 11 deletions protocol/x/sending/keeper/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,17 @@ func (k Keeper) ProcessTransfer(
) (err error) {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), metrics.ProcessTransfer, metrics.Latency)

updates := []satypes.Update{
pendingTransfer.GetSenderSubaccountUpdate(),
pendingTransfer.GetRecipientSubaccountUpdate(),
}

success, successPerUpdate, err := k.subaccountsKeeper.UpdateSubaccounts(ctx, updates, satypes.Transfer)
err = k.subaccountsKeeper.TransferFundsFromSubaccountToSubaccount(
ctx,
pendingTransfer.Sender,
pendingTransfer.Recipient,
pendingTransfer.AssetId,
pendingTransfer.GetBigQuantums(),
)
if err != nil {
return err
}

// If not successful, return error indicating why.
if err := satypes.GetErrorFromUpdateResults(success, successPerUpdate, updates); err != nil {
return err
}

recipientAddr := pendingTransfer.Recipient.MustGetAccAddress()

// Create an account for the recipient address if one does not exist.
Expand Down
7 changes: 7 additions & 0 deletions protocol/x/sending/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ type SubaccountsKeeper interface {
assetId uint32,
amount *big.Int,
) (err error)
TransferFundsFromSubaccountToSubaccount(
ctx sdk.Context,
senderSubaccountId satypes.SubaccountId,
recipientSubaccountId satypes.SubaccountId,
assetId uint32,
quantums *big.Int,
) (err error)
SetSubaccount(ctx sdk.Context, subaccount satypes.Subaccount)
GetSubaccount(
ctx sdk.Context,
Expand Down
87 changes: 87 additions & 0 deletions protocol/x/subaccounts/keeper/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,90 @@ func (k Keeper) TransferInsuranceFundPayments(
[]sdk.Coin{coinToTransfer},
)
}

// TransferFundsFromSubaccountToSubaccount returns an error if the call to `k.CanUpdateSubaccounts()`
// fails. Otherwise, updates the asset quantums in the subaccounts, translates the
// `assetId` and `quantums` into a `sdk.Coin`, and call `bankKeeper.SendCoins()` if the collateral
// pools for the two subaccounts are different.
// TODO(CORE-168): Change function interface to accept `denom` and `amount` instead of `assetId` and
// `quantums`.
func (k Keeper) TransferFundsFromSubaccountToSubaccount(
ctx sdk.Context,
senderSubaccountId types.SubaccountId,
recipientSubaccountId types.SubaccountId,
assetId uint32,
quantums *big.Int,
) error {
// TODO(DEC-715): Support non-USDC assets.
if assetId != assettypes.AssetUsdc.Id {
return types.ErrAssetTransferThroughBankNotImplemented
}

updates := []types.Update{
{
SubaccountId: senderSubaccountId,
AssetUpdates: []types.AssetUpdate{
{
AssetId: assettypes.AssetUsdc.Id,
BigQuantumsDelta: new(big.Int).Neg(quantums),
},
},
},
{
SubaccountId: recipientSubaccountId,
AssetUpdates: []types.AssetUpdate{
{
AssetId: assettypes.AssetUsdc.Id,
BigQuantumsDelta: new(big.Int).Set(quantums),
},
},
},
}
success, successPerUpdate, err := k.CanUpdateSubaccounts(ctx, updates, types.Transfer)
if err != nil {
return err
}
if err := types.GetErrorFromUpdateResults(success, successPerUpdate, updates); err != nil {
return err
}

_, coinToTransfer, err := k.assetsKeeper.ConvertAssetToCoin(
ctx,
assetId,
quantums,
)
if err != nil {
return err
}

senderCollateralPoolAddr, err := k.GetCollateralPoolForSubaccount(ctx, senderSubaccountId)
if err != nil {
return err
}

recipientCollateralPoolAddr, err := k.GetCollateralPoolForSubaccount(ctx, recipientSubaccountId)
if err != nil {
return err
}

// Different collateral pool address, need to do a bank send.
if !senderCollateralPoolAddr.Equals(recipientCollateralPoolAddr) {
// Use SendCoins API instead of SendCoinsFromModuleToModule since we don't need the
// module account feature
if err := k.bankKeeper.SendCoins(
ctx,
senderCollateralPoolAddr,
recipientCollateralPoolAddr,
[]sdk.Coin{coinToTransfer},
); err != nil {
return err
}
}

// Apply subaccount updates.
return k.applyValidSubaccountUpdateForTransfer(
ctx,
updates,
types.Transfer,
)
}
vincentwschau marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading