Skip to content

Commit

Permalink
Merge pull request #1975 from 0chain/1922_service_fee
Browse files Browse the repository at this point in the history
Added ZCN Service Fee
  • Loading branch information
peterlimg committed Jan 16, 2023
2 parents 79a6c5f + 77ffd4a commit 5188685
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 9 deletions.
Expand Up @@ -87,6 +87,7 @@ func MakeMockStateContext() *mockStateContext {
// Transfers

var transfers []*state.Transfer
var mints []*state.Mint

// EventsDB
events = make(map[string]*AuthorizerNode, 100)
Expand Down Expand Up @@ -188,7 +189,13 @@ func MakeMockStateContext() *mockStateContext {
return nil
})

ctx.On("AddMint", mock.AnythingOfType("*state.Mint")).Return(nil)
ctx.On("AddMint", mock.AnythingOfType("*state.Mint")).Return(func(m *state.Mint) error {
mints = append(mints, m)
return nil
})
ctx.On("GetMints").Return(func() []*state.Mint {
return mints
})

// EventsDB

Expand Down
48 changes: 40 additions & 8 deletions code/go/0chain.net/smartcontract/zcnsc/mint.go
Expand Up @@ -8,6 +8,7 @@ import (
"0chain.net/chaincore/state"
"0chain.net/chaincore/transaction"
"0chain.net/core/common"
"github.com/0chain/common/core/currency"
"github.com/0chain/common/core/logging"
"github.com/pkg/errors"
"go.uber.org/zap"
Expand All @@ -19,13 +20,11 @@ func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []by
code = "failed to mint"
)

var (
info = fmt.Sprintf(
"transaction hash %s, clientID: %s, payload: %s",
trans.Hash,
trans.ClientID,
string(inputData),
)
info := fmt.Sprintf(
"transaction hash %s, clientID: %s, payload: %s",
trans.Hash,
trans.ClientID,
string(inputData),
)

gn, err := GetGlobalNode(ctx)
Expand Down Expand Up @@ -114,14 +113,47 @@ func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []by
// record the global nonce from solidity smart contract
gn.WZCNNonceMinted[payload.Nonce] = true

var (
amount currency.Coin
n currency.Coin
share currency.Coin
)
share, _, err = currency.DistributeCoin(gn.ZCNSConfig.MaxFee, int64(len(payload.Signatures)))
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, DistributeCoin operation, %s", code, info))
return
}
n, err = currency.Int64ToCoin(int64(len(payload.Signatures)))
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, convert len signatures to coin, %s", code, info))
return
}
amount, err = currency.MinusCoin(payload.Amount, share*n)
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, payload.Amount - share * len(signatures), %s", code, info))
return
}
payload.Amount = amount
for _, sig := range payload.Signatures {
err = ctx.AddMint(&state.Mint{
Minter: gn.ID,
ToClientID: sig.ID,
Amount: share,
})
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, AddMint for authorizers, %s", code, info))
return
}
}

// mint the tokens
err = ctx.AddMint(&state.Mint{
Minter: gn.ID,
ToClientID: trans.ClientID,
Amount: payload.Amount,
})
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, add mint operation, %s", code, info))
err = errors.Wrap(err, fmt.Sprintf("%s, Add mint operation, %s", code, info))
return
}

Expand Down
38 changes: 38 additions & 0 deletions code/go/0chain.net/smartcontract/zcnsc/mint_test.go
Expand Up @@ -6,6 +6,7 @@ import (
"time"

. "0chain.net/smartcontract/zcnsc"
"github.com/0chain/common/core/currency"
"github.com/0chain/common/core/logging"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
Expand Down Expand Up @@ -66,6 +67,43 @@ func Test_FuzzyMintTest(t *testing.T) {
}
}

func Test_MaxFeeMint(t *testing.T) {
const maxFee = 10
ctx := MakeMockStateContext()
ctx.globalNode.ZCNSConfig.MaxFee = maxFee
contract := CreateZCNSmartContract()
payload, err := CreateMintPayload(ctx, defaultClient)
require.NoError(t, err)

transaction, err := CreateTransaction(defaultClient, "mint", payload.Encode(), ctx)
require.NoError(t, err)

response, err := contract.Mint(transaction, payload.Encode(), ctx)
require.NoError(t, err, "Testing authorizer: '%s'", defaultClient)
require.NotNil(t, response)
require.NotEmpty(t, response)

mm := ctx.GetMints()
require.Equal(t, len(mm), len(authorizersID)+1)
expectedShare, _, err := currency.DistributeCoin(maxFee, int64(len(authorizersID)))
require.NoError(t, err)
for i := 0; i < 3; i++ {
require.Equal(t, mm[i].ToClientID, authorizersID[i])
require.Equal(t, mm[i].Amount, expectedShare)
}

rp := &MintPayload{}
require.NoError(t, rp.Decode([]byte(response)))
require.Equal(t, payload.ReceivingClientID, rp.ReceivingClientID)
sz, err := currency.Int64ToCoin(int64(len(authorizersID)))
require.NoError(t, err)
totalShare, err := currency.MultCoin(expectedShare, sz)
require.NoError(t, err)
expectedAmount, err := currency.MinusCoin(payload.Amount, totalShare)
require.NoError(t, err)
require.Equal(t, rp.Amount, expectedAmount)
}

func Test_EmptySignaturesShouldFail(t *testing.T) {
ctx := MakeMockStateContext()
contract := CreateZCNSmartContract()
Expand Down

0 comments on commit 5188685

Please sign in to comment.