Skip to content

Commit

Permalink
Testing transfers to non-whitelisted smart contract (#676)
Browse files Browse the repository at this point in the history
# Description

Funds might be transferred to smart contract in 3 ways:
1. regular bank send
2. smart contract call
3. smart contract instantiation

In this PR, tests are added to verify that in all 3 cases transfer fails if smart contract is not whitelisted.

# Reviewers checklist:
- [ ] Try to write more meaningful comments with clear actions to be taken.
- [ ] Nit-picking should be unblocking. Focus on core issues.

# Authors checklist
- [x] Provide a concise and meaningful description
- [x] Review the code yourself first, before making the PR.
- [x] Annotate your PR in places that require explanation.
- [x] Think and try to split the PR to smaller PR if it is big.
  • Loading branch information
wojtek-coreum authored Oct 25, 2023
1 parent 84503b3 commit f3af2f2
Showing 1 changed file with 204 additions and 0 deletions.
204 changes: 204 additions & 0 deletions integration-tests/modules/assetft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2382,6 +2382,210 @@ func TestAssetFTWhitelistIssuerAccount(t *testing.T) {
requireT.ErrorIs(err, cosmoserrors.ErrUnauthorized)
}

// TestAssetFTSendingToNonWhitelistedSmartContractIsDenied verifies that this is not possible to send token to smart contract
// if it is not whitelisted.
func TestAssetFTSendingToNonWhitelistedSmartContractIsDenied(t *testing.T) {
t.Parallel()

ctx, chain := integrationtests.NewCoreumTestingContext(t)

issuer := chain.GenAccount()

requireT := require.New(t)
chain.Faucet.FundAccounts(ctx, t,
integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))),
)

clientCtx := chain.ClientContext

// Issue a fungible token which cannot be sent to the smart contract
issueMsg := &assetfttypes.MsgIssue{
Issuer: issuer.String(),
Symbol: "ABC",
Subunit: "abc",
Precision: 6,
InitialAmount: sdkmath.NewInt(1000),
Description: "ABC Description",
Features: []assetfttypes.Feature{
assetfttypes.Feature_whitelisting,
},
BurnRate: sdk.ZeroDec(),
SendCommissionRate: sdk.ZeroDec(),
}

_, err := client.BroadcastTx(
ctx,
chain.ClientContext.WithFromAddress(issuer),
chain.TxFactory().WithGas(chain.GasLimitByMsgs(issueMsg)),
issueMsg,
)

requireT.NoError(err)
denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer)

initialPayload, err := json.Marshal(moduleswasm.SimpleState{
Count: 1337,
})
requireT.NoError(err)

contractAddr, _, err := chain.Wasm.DeployAndInstantiateWASMContract(
ctx,
chain.TxFactory().WithSimulateAndExecute(true),
issuer,
moduleswasm.SimpleStateWASM,
integration.InstantiateConfig{
AccessType: wasmtypes.AccessTypeUnspecified,
Payload: initialPayload,
Label: "simple_state",
},
)
requireT.NoError(err)

// sending coins to the smart contract should fail
sendMsg := &banktypes.MsgSend{
FromAddress: issuer.String(),
ToAddress: contractAddr,
Amount: sdk.NewCoins(sdk.NewInt64Coin(denom, 100)),
}
_, err = client.BroadcastTx(
ctx,
clientCtx.WithFromAddress(issuer),
chain.TxFactory().WithGas(chain.GasLimitByMsgs(sendMsg)),
sendMsg,
)
requireT.ErrorIs(err, assetfttypes.ErrWhitelistedLimitExceeded)
}

// TestAssetFTAttachingToNonWhitelistedSmartContractCallIsDenied verifies that this is not possible to attach token to smart contract call
// if contract is not whitelisted.
func TestAssetFTAttachingToNonWhitelistedSmartContractCallIsDenied(t *testing.T) {
t.Parallel()

ctx, chain := integrationtests.NewCoreumTestingContext(t)

issuer := chain.GenAccount()

requireT := require.New(t)
chain.Faucet.FundAccounts(ctx, t,
integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))),
)

txf := chain.TxFactory().
WithSimulateAndExecute(true)

// Issue a fungible token which cannot be sent to the smart contract
issueMsg := &assetfttypes.MsgIssue{
Issuer: issuer.String(),
Symbol: "ABC",
Subunit: "abc",
Precision: 6,
InitialAmount: sdkmath.NewInt(1000),
Description: "ABC Description",
Features: []assetfttypes.Feature{
assetfttypes.Feature_whitelisting,
},
BurnRate: sdk.ZeroDec(),
SendCommissionRate: sdk.ZeroDec(),
}

_, err := client.BroadcastTx(
ctx,
chain.ClientContext.WithFromAddress(issuer),
chain.TxFactory().WithGas(chain.GasLimitByMsgs(issueMsg)),
issueMsg,
)

requireT.NoError(err)
denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer)

initialPayload, err := json.Marshal(moduleswasm.SimpleState{
Count: 1337,
})
requireT.NoError(err)

contractAddr, _, err := chain.Wasm.DeployAndInstantiateWASMContract(
ctx,
txf,
issuer,
moduleswasm.SimpleStateWASM,
integration.InstantiateConfig{
AccessType: wasmtypes.AccessTypeUnspecified,
Payload: initialPayload,
Label: "simple_state",
},
)
requireT.NoError(err)

// Executing smart contract - this operation should fail because coins are attached to it
incrementPayload, err := moduleswasm.MethodToEmptyBodyPayload(moduleswasm.SimpleIncrement)
requireT.NoError(err)
_, err = chain.Wasm.ExecuteWASMContract(ctx, txf, issuer, contractAddr, incrementPayload, sdk.NewInt64Coin(denom, 100))
requireT.ErrorContains(err, "whitelisted limit exceeded")
}

// TestAssetFTAttachingToNonWhitelistedSmartContractInstantiationIsDenied verifies that this is not possible to attach token to smart contract instantiation
// if contract is not whitelisted.
func TestAssetFTAttachingToNonWhitelistedSmartContractInstantiationIsDenied(t *testing.T) {
t.Parallel()

ctx, chain := integrationtests.NewCoreumTestingContext(t)

issuer := chain.GenAccount()

requireT := require.New(t)
chain.Faucet.FundAccounts(ctx, t,
integration.NewFundedAccount(issuer, chain.NewCoin(sdkmath.NewInt(5000000000))),
)

txf := chain.TxFactory().
WithSimulateAndExecute(true)

// Issue a fungible token which cannot be sent to the smart contract
issueMsg := &assetfttypes.MsgIssue{
Issuer: issuer.String(),
Symbol: "ABC",
Subunit: "abc",
Precision: 6,
InitialAmount: sdkmath.NewInt(1000),
Description: "ABC Description",
Features: []assetfttypes.Feature{
assetfttypes.Feature_whitelisting,
},
BurnRate: sdk.ZeroDec(),
SendCommissionRate: sdk.ZeroDec(),
}

_, err := client.BroadcastTx(
ctx,
chain.ClientContext.WithFromAddress(issuer),
chain.TxFactory().WithGas(chain.GasLimitByMsgs(issueMsg)),
issueMsg,
)

requireT.NoError(err)
denom := assetfttypes.BuildDenom(issueMsg.Subunit, issuer)

initialPayload, err := json.Marshal(moduleswasm.SimpleState{
Count: 1337,
})
requireT.NoError(err)

// This operation should fail due to coins being attached to it
_, _, err = chain.Wasm.DeployAndInstantiateWASMContract(
ctx,
txf,
issuer,
moduleswasm.SimpleStateWASM,
integration.InstantiateConfig{
AccessType: wasmtypes.AccessTypeUnspecified,
Payload: initialPayload,
Amount: sdk.NewInt64Coin(denom, 100),
Label: "simple_state",
},
)
requireT.ErrorContains(err, "whitelisted limit exceeded")
}

// TestBareToken checks none of the features will work if the flags are not set.
func TestBareToken(t *testing.T) {
t.Parallel()
Expand Down

0 comments on commit f3af2f2

Please sign in to comment.