diff --git a/src/auction.test.ts b/src/auction.test.ts index d4bc200..2efdc61 100644 --- a/src/auction.test.ts +++ b/src/auction.test.ts @@ -1,6 +1,7 @@ -import { Registry, Account, createBid, INVALID_BID_ERROR, RELEASE_FUNDS_ERROR, OWNER_MISMATCH_ERROR } from './index'; -import { checkAccountBalance, createTestAccounts, getConfig } from './testing/helper'; +import { Registry, Account, createBid } from './index'; +import { createTestAccounts, getConfig } from './testing/helper'; import { DENOM } from './constants'; +import { INVALID_BID_ERROR, OWNER_MISMATCH_ERROR, RELEASE_FUNDS_ERROR } from './types/cerc/auction/message'; jest.setTimeout(30 * 60 * 1000); const { chainId, rpcEndpoint, gqlEndpoint, privateKey, fee } = getConfig(); @@ -105,13 +106,9 @@ const auctionTests = () => { // Check that the bid amounts are locked after reveal phase for (let i = 0; i < numBidders; i++) { - const { type, quantity } = await checkAccountBalance(registry, bidderAccounts[i].address); - const actualBalance = parseInt(quantity); - // The bid amount, commit fee, reveal fee and tx fees (for commit and reveal txs) will be deducted from the bidder's acoount const expectedBalance = bidderInitialBalance - parseInt(bidAmounts[i]) - (2 * txFees) - parseInt(commitFee) - parseInt(revealFee); - expect(actualBalance).toBe(expectedBalance); - expect(type).toBe(DENOM); + await checkAccountBalance(registry, bidderAccounts[i].address, expectedBalance); } }); @@ -137,12 +134,9 @@ const auctionTests = () => { const winningPriceAmount = parseInt(auction.winnerPrice.quantity); - const { type, quantity } = await checkAccountBalance(registry, highestBidder.address); - const actualBalance = parseInt(quantity); - // The winning price will get deducted after auction completion - expect(actualBalance).toBe(bidderInitialBalance - winningPriceAmount - (2 * txFees) - parseInt(commitFee)); - expect(type).toBe(DENOM); + const expectedBalance = bidderInitialBalance - winningPriceAmount - (2 * txFees) - parseInt(commitFee); + await checkAccountBalance(registry, highestBidder.address, expectedBalance); }); }; @@ -201,14 +195,9 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number auctionId = auction.auction?.id || ''; expect(auction.auction?.status).toEqual('commit'); - // Check that the total locked amount is deducted from the creator's account - const { type, quantity } = await checkAccountBalance(registry, auctionCreatorAccount.address); - const actualBalance = parseInt(quantity); - // The locked amount and tx fees are deducted from the auction creator's account const expectedBalance = creatorInitialBalance - (maxPrice * numProviders) - txFees; - expect(actualBalance).toBe(expectedBalance); - expect(type).toBe(DENOM); + await checkAccountBalance(registry, auctionCreatorAccount.address, expectedBalance); }); test('Commit bids.', async () => { @@ -301,14 +290,10 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number const expectedWinningPrice = winningBidders[numWinners - 1].bid.reveal.bidAmount; expect(`${auction.winnerPrice.quantity}${auction.winnerPrice.type}`).toEqual(expectedWinningPrice); - const { type, quantity } = await checkAccountBalance(registry, auctionCreatorAccount.address); - const actualBalance = parseInt(quantity); - // The total winning amount will get deducted and the leftover locked amount is returned const totalWinningAmount = parseInt(auction.winnerPrice.quantity) * winningBidders.length; const expectedCreatorBalance = creatorInitialBalance - totalWinningAmount - txFees; - expect(actualBalance).toBe(expectedCreatorBalance); - expect(type).toBe(DENOM); + await checkAccountBalance(registry, auctionCreatorAccount.address, expectedCreatorBalance); // Funds should not be given to winners on auction completion for (let i = 0; i < winningBidders.length; i++) { @@ -317,12 +302,8 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number expect(auction.winnerAddresses[i]).toEqual(bidWinner.address); expect(`${auction.winnerBids[i].quantity}${auction.winnerBids[i].type}`).toEqual(bidWinner.bid.reveal.bidAmount); - const { type, quantity } = await checkAccountBalance(registry, bidWinner.address); - const actualBalance = parseInt(quantity); - const expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee); - expect(actualBalance).toBe(expectedBidderBalance); - expect(type).toBe(DENOM); + await checkAccountBalance(registry, bidWinner.address, expectedBidderBalance); } }); @@ -347,25 +328,18 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number expect(auctionObj.auction?.fundsReleased).toBe(true); // Auction winners get the winning amount after funds are released + const expectedBidderBalance = bidderInitialBalance + winningBidAmount - (2 * txFees) - parseInt(commitFee); for (let i = 0; i < winningBidders.length; i++) { const bidWinner = winningBidders[i]; expect(auction.winnerAddresses[i]).toEqual(bidWinner.address); expect(`${auction.winnerBids[i].quantity}${auction.winnerBids[i].type}`).toEqual(bidWinner.bid.reveal.bidAmount); - const { type, quantity } = await checkAccountBalance(registry, bidWinner.address); - const actualBalance = parseInt(quantity); - - const expectedBidderBalance = bidderInitialBalance + winningBidAmount - (2 * txFees) - parseInt(commitFee); - expect(actualBalance).toBe(expectedBidderBalance); - expect(type).toBe(DENOM); + await checkAccountBalance(registry, bidWinner.address, expectedBidderBalance); } // Check balances of non-winners for (const bidder of losingBidders) { - const { type, quantity } = await checkAccountBalance(registry, bidder.address); - const actualBalance = parseInt(quantity); - let expectedBidderBalance: number; if (invalidBidderAddress !== bidder.address) { expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee); @@ -374,8 +348,7 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee) - parseInt(revealFee); } - expect(actualBalance).toBe(expectedBidderBalance); - expect(type).toBe(DENOM); + await checkAccountBalance(registry, bidder.address, expectedBidderBalance); } // Funds cannot be released twice @@ -387,14 +360,23 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number }); }; +const checkAccountBalance = async (registry: Registry, address: string, expectedBalance: number): Promise => { + const [winnerAccountObj] = await registry.getAccounts([address]); + const [{ type, quantity }] = winnerAccountObj.balance; + const actualBalance = parseInt(quantity); + + expect(actualBalance).toBe(expectedBalance); + expect(type).toBe(DENOM); +}; + const providerAuctionTests = () => { // With a bid amount greater than the max price - const bids1 = [10002000, 10009000, 10006000 * 10, 10004000]; + const bids = [10002000, 10009000, 10006000 * 10, 10004000]; // Number of providers is less than number of bidders - describe('Auction with numProviders < numBidders', () => providerAuctionTestsWithBids(bids1, 3)); + describe('Auction with numProviders < numBidders', () => providerAuctionTestsWithBids(bids, 3)); // Number of providers is greater than number of bidders - describe('Auction numProviders > numBidders', () => providerAuctionTestsWithBids(bids1, 5)); + describe('Auction numProviders > numBidders', () => providerAuctionTestsWithBids(bids, 5)); }; describe('Vickrey Auction', () => auctionTests()); diff --git a/src/laconic-client.ts b/src/laconic-client.ts index 5fcc940..2aaaf31 100644 --- a/src/laconic-client.ts +++ b/src/laconic-client.ts @@ -13,8 +13,8 @@ import { Comet38Client } from '@cosmjs/tendermint-rpc'; import { MsgCancelBondEncodeObject, MsgCreateBondEncodeObject, MsgRefillBondEncodeObject, MsgWithdrawBondEncodeObject, bondTypes, typeUrlMsgCancelBond, typeUrlMsgCreateBond, typeUrlMsgRefillBond, typeUrlMsgWithdrawBond } from './types/cerc/bond/message'; import { Coin } from './proto/cosmos/base/v1beta1/coin'; import { MsgAssociateBondEncodeObject, MsgDeleteNameEncodeObject, MsgDissociateBondEncodeObject, MsgDissociateRecordsEncodeObject, MsgReassociateRecordsEncodeObject, MsgReserveAuthorityEncodeObject, MsgSetAuthorityBondEncodeObject, MsgSetNameEncodeObject, MsgSetRecordEncodeObject, registryTypes, typeUrlMsgAssociateBond, typeUrlMsgDeleteName, typeUrlMsgDissociateBond, typeUrlMsgDissociateRecords, typeUrlMsgReassociateRecords, typeUrlMsgReserveAuthority, typeUrlMsgSetAuthorityBond, typeUrlMsgSetName, typeUrlMsgSetRecord, NAMESERVICE_ERRORS } from './types/cerc/registry/message'; -import { MsgCommitBidEncodeObject, MsgCreateAuctionEncodeObject, MsgReleaseFundsEncodeObject, MsgRevealBidEncodeObject, auctionTypes, typeUrlMsgCommitBid, typeUrlMsgCreateAuction, typeUrlMsgReleaseFunds, typeUrlMsgRevealBid } from './types/cerc/auction/message'; -import { INVALID_BID_ERROR, MsgOnboardParticipantEncodeObject, ONBOARDING_DISABLED_ERROR, onboardingTypes, OWNER_MISMATCH_ERROR, RELEASE_FUNDS_ERROR, typeUrlMsgOnboardParticipant } from './types/cerc/onboarding/message'; +import { AUCTION_ERRORS, MsgCommitBidEncodeObject, MsgCreateAuctionEncodeObject, MsgReleaseFundsEncodeObject, MsgRevealBidEncodeObject, auctionTypes, typeUrlMsgCommitBid, typeUrlMsgCreateAuction, typeUrlMsgReleaseFunds, typeUrlMsgRevealBid } from './types/cerc/auction/message'; +import { MsgOnboardParticipantEncodeObject, ONBOARDING_DISABLED_ERROR, onboardingTypes, typeUrlMsgOnboardParticipant } from './types/cerc/onboarding/message'; import { MsgAssociateBondResponse, MsgDeleteNameResponse, MsgDissociateBondResponse, MsgDissociateRecordsResponse, MsgReassociateRecordsResponse, MsgReserveAuthorityResponse, MsgSetAuthorityBondResponse, MsgSetNameResponse, MsgSetRecordResponse, Payload } from './proto/cerc/registry/v1/tx'; import { Record, Signature } from './proto/cerc/registry/v1/registry'; import { Account } from './account'; @@ -383,7 +383,7 @@ export class LaconicClient extends SigningStargateClient { } processWriteError (error: string) { - const errorMessage = [...NAMESERVICE_ERRORS, ONBOARDING_DISABLED_ERROR, INVALID_BID_ERROR, RELEASE_FUNDS_ERROR, OWNER_MISMATCH_ERROR].find(message => error.includes(message)); + const errorMessage = [...NAMESERVICE_ERRORS, ...AUCTION_ERRORS, ONBOARDING_DISABLED_ERROR].find(message => error.includes(message)); if (!errorMessage) { console.error(error); diff --git a/src/testing/helper.ts b/src/testing/helper.ts index 1f9be53..f3d5c81 100644 --- a/src/testing/helper.ts +++ b/src/testing/helper.ts @@ -48,10 +48,3 @@ export const createTestAccounts = async (numAccounts: number): Promise => { - const [winnerAccountObj] = await registry.getAccounts([address]); - const [{ type, quantity }] = winnerAccountObj.balance; - - return { type, quantity }; -}; diff --git a/src/types/cerc/auction/message.ts b/src/types/cerc/auction/message.ts index c93537e..4329e9e 100644 --- a/src/types/cerc/auction/message.ts +++ b/src/types/cerc/auction/message.ts @@ -42,6 +42,11 @@ export interface MsgReleaseFundsEncodeObject extends EncodeObject { readonly value: Partial; } +export const INVALID_BID_ERROR = 'Bid is higher than max price'; +export const RELEASE_FUNDS_ERROR = 'Auction funds already released'; +export const OWNER_MISMATCH_ERROR = 'Only auction owner can release funds'; +export const AUCTION_ERRORS = [INVALID_BID_ERROR, RELEASE_FUNDS_ERROR, OWNER_MISMATCH_ERROR]; + export interface MessageMsgCommitBid { auctionId: string, commitHash: string, diff --git a/src/types/cerc/onboarding/message.ts b/src/types/cerc/onboarding/message.ts index 26f32b8..1056704 100644 --- a/src/types/cerc/onboarding/message.ts +++ b/src/types/cerc/onboarding/message.ts @@ -16,9 +16,6 @@ export interface MsgOnboardParticipantEncodeObject extends EncodeObject { } export const ONBOARDING_DISABLED_ERROR = 'Onboarding is disabled'; -export const INVALID_BID_ERROR = 'Bid is higher than max price'; -export const RELEASE_FUNDS_ERROR = 'Auction funds already released'; -export const OWNER_MISMATCH_ERROR = 'Only auction owner can release funds'; interface ethPayload { address: string